mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-23 08:32:39 +00:00
Merged compiler optimizatins from Travis Fisher.
This commit is contained in:
commit
5157854692
@ -174,11 +174,29 @@ public class AsmFormat {
|
||||
}
|
||||
}
|
||||
|
||||
private static String shortNumberStrings[] = {
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "$a", "$b", "$c", "$d", "$e", "$f",
|
||||
"$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19", "$1a", "$1b", "$1c", "$1d", "$1e", "$1f",
|
||||
"$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29", "$2a", "$2b", "$2c", "$2d", "$2e", "$2f",
|
||||
"$30", "$31", "$32", "$33", "$34", "$35", "$36", "$37", "$38", "$39", "$3a", "$3b", "$3c", "$3d", "$3e", "$3f",
|
||||
"$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47", "$48", "$49", "$4a", "$4b", "$4c", "$4d", "$4e", "$4f",
|
||||
"$50", "$51", "$52", "$53", "$54", "$55", "$56", "$57", "$58", "$59", "$5a", "$5b", "$5c", "$5d", "$5e", "$5f",
|
||||
"$60", "$61", "$62", "$63", "$64", "$65", "$66", "$67", "$68", "$69", "$6a", "$6b", "$6c", "$6d", "$6e", "$6f",
|
||||
"$70", "$71", "$72", "$73", "$74", "$75", "$76", "$77", "$78", "$79", "$7a", "$7b", "$7c", "$7d", "$7e", "$7f",
|
||||
"$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", "$88", "$89", "$8a", "$8b", "$8c", "$8d", "$8e", "$8f",
|
||||
"$90", "$91", "$92", "$93", "$94", "$95", "$96", "$97", "$98", "$99", "$9a", "$9b", "$9c", "$9d", "$9e", "$9f",
|
||||
"$a0", "$a1", "$a2", "$a3", "$a4", "$a5", "$a6", "$a7", "$a8", "$a9", "$aa", "$ab", "$ac", "$ad", "$ae", "$af",
|
||||
"$b0", "$b1", "$b2", "$b3", "$b4", "$b5", "$b6", "$b7", "$b8", "$b9", "$ba", "$bb", "$bc", "$bd", "$be", "$bf",
|
||||
"$c0", "$c1", "$c2", "$c3", "$c4", "$c5", "$c6", "$c7", "$c8", "$c9", "$ca", "$cb", "$cc", "$cd", "$ce", "$cf",
|
||||
"$d0", "$d1", "$d2", "$d3", "$d4", "$d5", "$d6", "$d7", "$d8", "$d9", "$da", "$db", "$dc", "$dd", "$de", "$df",
|
||||
"$e0", "$e1", "$e2", "$e3", "$e4", "$e5", "$e6", "$e7", "$e8", "$e9", "$ea", "$eb", "$ec", "$ed", "$ee", "$ef",
|
||||
"$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", "$fa", "$fb", "$fc", "$fd", "$fe", "$ff"
|
||||
};
|
||||
|
||||
public static String getAsmNumber(Number number) {
|
||||
if(number instanceof Long || number instanceof Integer) {
|
||||
if(number.longValue() >= 0L && number.longValue() <= 9L) {
|
||||
return String.format("%d", number.longValue());
|
||||
if(number.longValue() >= 0L && number.longValue() <= 255L) {
|
||||
return shortNumberStrings[number.intValue()];
|
||||
} else {
|
||||
return String.format("$%x", number.longValue());
|
||||
}
|
||||
|
@ -22,24 +22,6 @@ public class LiveRange {
|
||||
this.intervals = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a statement to the live range
|
||||
*
|
||||
* @param statement The statement to add
|
||||
* @return true if the live range was modified by the addition. false otherwise
|
||||
*/
|
||||
public boolean add(Statement statement) {
|
||||
return add(getIndex(statement));
|
||||
}
|
||||
|
||||
private Integer getIndex(Statement statement) {
|
||||
Integer index = statement.getIndex();
|
||||
if(index == null) {
|
||||
throw new RuntimeException("Statement index not defined! Live Ranges only work after defining statement indexes (Pass3LiveRangesAnalysis.generateStatementIndices).");
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of statements in the live range.
|
||||
*
|
||||
@ -125,23 +107,13 @@ public class LiveRange {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the live range contains a statement
|
||||
*
|
||||
* @param statement The statement to examine
|
||||
* @return true if the live range contains the statement
|
||||
*/
|
||||
public boolean contains(Statement statement) {
|
||||
return contains(getIndex(statement));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the live range contains an index
|
||||
*
|
||||
* @param index
|
||||
* @return true if the live range contains the index
|
||||
*/
|
||||
private boolean contains(int index) {
|
||||
public boolean contains(int index) {
|
||||
for(LiveInterval interval : intervals) {
|
||||
if(interval.lastStatementIdx >= index) {
|
||||
if(interval.firstStatementIdx <= index) {
|
||||
|
@ -8,6 +8,7 @@ import dk.camelot64.kickc.passes.PassNCallGraphAnalysis;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Live ranges for all variables.
|
||||
@ -28,16 +29,16 @@ public class LiveRangeVariables {
|
||||
* Add a single statement to the live range of a variable.
|
||||
*
|
||||
* @param variable The variable
|
||||
* @param statement The statement to add
|
||||
* @param statementIdx Index of the statement to add
|
||||
* @return true if a live range was modified by the addition
|
||||
*/
|
||||
public boolean addAlive(VariableRef variable, Statement statement) {
|
||||
public boolean addAlive(VariableRef variable, int statementIdx) {
|
||||
LiveRange liveRange = liveRanges.get(variable);
|
||||
if(liveRange == null) {
|
||||
liveRange = new LiveRange();
|
||||
liveRanges.put(variable, liveRange);
|
||||
}
|
||||
return liveRange.add(statement);
|
||||
return liveRange.add(statementIdx);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,15 +57,14 @@ public class LiveRangeVariables {
|
||||
/**
|
||||
* Get all variables alive at a specific statement
|
||||
*
|
||||
* @param statement The statement
|
||||
* @param statementIdx Index of the statement
|
||||
* @return List of all live variables.
|
||||
*/
|
||||
public List<VariableRef> getAlive(Statement statement) {
|
||||
public List<VariableRef> getAlive(int statementIdx) {
|
||||
ArrayList<VariableRef> aliveVars = new ArrayList<>();
|
||||
for(VariableRef variable : liveRanges.keySet()) {
|
||||
LiveRange liveRange = liveRanges.get(variable);
|
||||
if(liveRange.contains(statement)) {
|
||||
aliveVars.add(variable);
|
||||
for(Map.Entry<VariableRef,LiveRange> entry : liveRanges.entrySet()) {
|
||||
if(entry.getValue().contains(statementIdx)) {
|
||||
aliveVars.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
return aliveVars;
|
||||
|
@ -43,7 +43,7 @@ public class LiveRangeVariablesEffective {
|
||||
this.statementLiveVariables = new LinkedHashMap<>();
|
||||
for(ControlFlowBlock block : program.getGraph().getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
statementLiveVariables.put(statement.getIndex(), liveRangeVariables.getAlive(statement));
|
||||
statementLiveVariables.put(statement.getIndex(), liveRangeVariables.getAlive(statement.getIndex()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -276,9 +276,8 @@ public class LiveRangeVariablesEffective {
|
||||
* @return All variables effectively alive at the statement on the call-path
|
||||
*/
|
||||
public Collection<VariableRef> getEffectiveAliveAtStmt(CallPath callPath) {
|
||||
LinkedHashSet<VariableRef> effectiveAlive = new LinkedHashSet<>();
|
||||
// Add alive at call
|
||||
effectiveAlive.addAll(callPath.getAlive());
|
||||
LinkedHashSet<VariableRef> effectiveAlive = new LinkedHashSet<>(callPath.getAlive());
|
||||
// Clear out any variables referenced in the method
|
||||
effectiveAlive.removeAll(referencedInProcedure);
|
||||
// Add alive at statement
|
||||
|
@ -80,7 +80,7 @@ public abstract class StatementBase implements Statement {
|
||||
}
|
||||
LiveRangeVariables liveRanges = program.getLiveRangeVariables();
|
||||
StringBuilder alive = new StringBuilder();
|
||||
alive.append(getAliveString(liveRanges.getAlive(this)));
|
||||
alive.append(getAliveString(liveRanges.getAlive(index)));
|
||||
LiveRangeVariablesEffective liveRangeVariablesEffective = program.getLiveRangeVariablesEffective();
|
||||
if(liveRangeVariablesEffective != null) {
|
||||
LiveRangeVariablesEffective.AliveCombinations aliveCombinations = liveRangeVariablesEffective.getAliveCombinations(this);
|
||||
|
@ -14,12 +14,12 @@ public class StatementInfos {
|
||||
private ControlFlowGraph graph;
|
||||
|
||||
/** Maps statement index to block label. */
|
||||
private Map<Integer, LabelRef> stmtBlocks;
|
||||
private Map<Integer, ControlFlowBlock> stmtBlocks;
|
||||
|
||||
/** Maps statement index to statement. */
|
||||
private Map<Integer, Statement> stmtIdx;
|
||||
|
||||
public StatementInfos(Program program, Map<Integer, LabelRef> stmtBlocks, Map<Integer, Statement> stmtIdx) {
|
||||
public StatementInfos(Program program, Map<Integer, ControlFlowBlock> stmtBlocks, Map<Integer, Statement> stmtIdx) {
|
||||
this.graph = program.getGraph();
|
||||
this.stmtBlocks = stmtBlocks;
|
||||
this.stmtIdx = stmtIdx;
|
||||
@ -32,7 +32,7 @@ public class StatementInfos {
|
||||
* @return The block label
|
||||
*/
|
||||
public LabelRef getBlockRef(Integer stmtIdx) {
|
||||
return stmtBlocks.get(stmtIdx);
|
||||
return stmtBlocks.get(stmtIdx).getLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,7 +42,7 @@ public class StatementInfos {
|
||||
* @return The block label
|
||||
*/
|
||||
public LabelRef getBlockRef(Statement stmt) {
|
||||
return stmtBlocks.get(stmt.getIndex());
|
||||
return stmtBlocks.get(stmt.getIndex()).getLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,7 +52,7 @@ public class StatementInfos {
|
||||
* @return The containing block
|
||||
*/
|
||||
public ControlFlowBlock getBlock(Statement stmt) {
|
||||
return graph.getBlock(getBlockRef(stmt));
|
||||
return stmtBlocks.get(stmt.getIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,7 +65,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
boolean modified = false;
|
||||
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
for(Statement stmt : block.getStatements()) {
|
||||
List<VariableRef> aliveNextStmt = liveRanges.getAlive(stmt);
|
||||
List<VariableRef> aliveNextStmt = liveRanges.getAlive(stmt.getIndex());
|
||||
Collection<VariableRef> definedNextStmt = referenceInfo.getDefinedVars(stmt);
|
||||
initLiveRange(liveRanges, definedNextStmt);
|
||||
Collection<PreviousStatement> previousStmts = getPreviousStatements(stmt);
|
||||
@ -76,7 +76,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
// Add all vars alive in the next statement
|
||||
for(VariableRef aliveVar : aliveNextStmt) {
|
||||
if(!definedNextStmt.contains(aliveVar)) {
|
||||
boolean addAlive = liveRanges.addAlive(aliveVar, previousStmt.getStatement());
|
||||
boolean addAlive = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx());
|
||||
modified |= addAlive;
|
||||
if(addAlive && getLog().isVerboseLiveRanges()) {
|
||||
getLog().append("Propagated alive var " + aliveVar + " to " + previousStmt.getStatement());
|
||||
@ -92,7 +92,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
for(VariableRef aliveVar : aliveNextStmt) {
|
||||
// Add all variables to previous that are not used inside the method
|
||||
if(procUsed.contains(aliveVar)) {
|
||||
boolean addUsedVar = liveRanges.addAlive(aliveVar, previousStmt.getStatement());
|
||||
boolean addUsedVar = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx());
|
||||
modified |= addUsedVar;
|
||||
if(addUsedVar && getLog().isVerboseLiveRanges()) {
|
||||
getLog().append("Propagated alive var used in method into method " + aliveVar + " to " + previousStmt.getStatement());
|
||||
@ -108,7 +108,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
for(VariableRef aliveVar : aliveNextStmt) {
|
||||
// Add all variables to previous that are not used inside the method
|
||||
if(!procUsed.contains(aliveVar)) {
|
||||
boolean addSkipVar = liveRanges.addAlive(aliveVar, previousStmt.getStatement());
|
||||
boolean addSkipVar = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx());
|
||||
modified |= addSkipVar;
|
||||
if(addSkipVar && getLog().isVerboseLiveRanges()) {
|
||||
getLog().append("Propagated alive var unused in method by skipping call " + aliveVar + " to " + previousStmt.getStatement());
|
||||
@ -127,7 +127,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
// Add all variables to previous that are used inside the method
|
||||
if(procUsed.contains(aliveVar)) {
|
||||
if(!definedNextStmt.contains(aliveVar)) {
|
||||
boolean usedVar = liveRanges.addAlive(aliveVar, previousStmt.getStatement());
|
||||
boolean usedVar = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx());
|
||||
modified |= usedVar;
|
||||
if(usedVar && getLog().isVerboseLiveRanges()) {
|
||||
getLog().append("Propagated alive used in method out of method " + aliveVar + " to " + previousStmt.getStatement());
|
||||
@ -164,13 +164,13 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
// If current statement is a phi add the used variables to previous based on the phi entries
|
||||
StatementPhiBlock phi = (StatementPhiBlock) stmt;
|
||||
ControlFlowBlock previousBlock =
|
||||
getProgram().getStatementInfos().getBlock(previousStmt.getStatement());
|
||||
getProgram().getStatementInfos().getBlock(previousStmt.getStatementIdx());
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
|
||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||
if(phiRValue.getPredecessor().equals(previousBlock.getLabel())) {
|
||||
if(phiRValue.getrValue() instanceof VariableRef) {
|
||||
VariableRef usedVar = (VariableRef) phiRValue.getrValue();
|
||||
boolean addUsed = liveRanges.addAlive(usedVar, previousStmt.getStatement());
|
||||
boolean addUsed = liveRanges.addAlive(usedVar, previousStmt.getStatementIdx());
|
||||
modified |= addUsed;
|
||||
if(addUsed && getLog().isVerboseLiveRanges()) {
|
||||
getLog().append("Adding used phi var " + usedVar + " to " + previousStmt.getStatement());
|
||||
@ -182,7 +182,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
} else {
|
||||
// Not a phi block - add used vars to all previous blocks
|
||||
for(VariableRef usedVar : usedNextStmt) {
|
||||
boolean addUsed = liveRanges.addAlive(usedVar, previousStmt.getStatement());
|
||||
boolean addUsed = liveRanges.addAlive(usedVar, previousStmt.getStatementIdx());
|
||||
modified |= addUsed;
|
||||
if(addUsed && getLog().isVerboseLiveRanges()) {
|
||||
getLog().append("Adding used var " + usedVar + " to " + previousStmt.getStatement());
|
||||
@ -346,6 +346,10 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
return statement;
|
||||
}
|
||||
|
||||
public int getStatementIdx() {
|
||||
return statement.getIndex();
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
@ -75,9 +75,8 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
||||
getProgram().getCallGraph().getCallers(procedure.getRef());
|
||||
for(CallGraph.CallBlock.Call caller : callers) {
|
||||
// Each caller creates its own call-paths
|
||||
StatementCall callStatement =
|
||||
(StatementCall) getProgram().getStatementInfos().getStatement(caller.getCallStatementIdx());
|
||||
ControlFlowBlock callBlock = getProgram().getStatementInfos().getBlock(callStatement);
|
||||
int callStatementIdx = caller.getCallStatementIdx();
|
||||
ControlFlowBlock callBlock = getProgram().getStatementInfos().getBlock(callStatementIdx);
|
||||
ScopeRef callScopeRef = callBlock.getScope();
|
||||
Scope callScope = getProgram().getScope().getScope(callScopeRef);
|
||||
if(callScope instanceof Procedure) {
|
||||
@ -95,7 +94,7 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
||||
Collection<VariableRef> alive = new LinkedHashSet<>();
|
||||
alive.addAll(callerPath.getAlive());
|
||||
alive.removeAll(referencedInCaller);
|
||||
alive.addAll(liveRangeVariables.getAlive(callStatement));
|
||||
alive.addAll(liveRangeVariables.getAlive(callStatementIdx));
|
||||
Pass2AliasElimination.Aliases innerAliases = getCallAliases(procedure, callBlock);
|
||||
Pass2AliasElimination.Aliases pathAliases = new Pass2AliasElimination.Aliases();
|
||||
pathAliases.addAll(callerPath.getPathAliases());
|
||||
|
@ -24,11 +24,11 @@ public class PassNStatementInfos extends Pass2SsaOptimization {
|
||||
*/
|
||||
@Override
|
||||
public boolean step() {
|
||||
LinkedHashMap<Integer, LabelRef> stmtBlocks = new LinkedHashMap<>();
|
||||
LinkedHashMap<Integer, ControlFlowBlock> stmtBlocks = new LinkedHashMap<>();
|
||||
LinkedHashMap<Integer, Statement> stmtIdx = new LinkedHashMap<>();
|
||||
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
stmtBlocks.put(statement.getIndex(), block.getLabel());
|
||||
stmtBlocks.put(statement.getIndex(), block);
|
||||
stmtIdx.put(statement.getIndex(), statement);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user