1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-23 23:32:55 +00:00

Merged compiler optimizatins from Travis Fisher.

This commit is contained in:
jespergravgaard 2019-04-11 21:15:32 +02:00
commit 5157854692
9 changed files with 55 additions and 63 deletions

View File

@ -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) { public static String getAsmNumber(Number number) {
if(number instanceof Long || number instanceof Integer) { if(number instanceof Long || number instanceof Integer) {
if(number.longValue() >= 0L && number.longValue() <= 9L) { if(number.longValue() >= 0L && number.longValue() <= 255L) {
return String.format("%d", number.longValue()); return shortNumberStrings[number.intValue()];
} else { } else {
return String.format("$%x", number.longValue()); return String.format("$%x", number.longValue());
} }

View File

@ -22,24 +22,6 @@ public class LiveRange {
this.intervals = new ArrayList<>(); 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. * 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 * Determines if the live range contains an index
* *
* @param index * @param index
* @return true if the live range contains the index * @return true if the live range contains the index
*/ */
private boolean contains(int index) { public boolean contains(int index) {
for(LiveInterval interval : intervals) { for(LiveInterval interval : intervals) {
if(interval.lastStatementIdx >= index) { if(interval.lastStatementIdx >= index) {
if(interval.firstStatementIdx <= index) { if(interval.firstStatementIdx <= index) {

View File

@ -8,6 +8,7 @@ import dk.camelot64.kickc.passes.PassNCallGraphAnalysis;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Live ranges for all variables. * Live ranges for all variables.
@ -28,16 +29,16 @@ public class LiveRangeVariables {
* Add a single statement to the live range of a variable. * Add a single statement to the live range of a variable.
* *
* @param variable The 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 * @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); LiveRange liveRange = liveRanges.get(variable);
if(liveRange == null) { if(liveRange == null) {
liveRange = new LiveRange(); liveRange = new LiveRange();
liveRanges.put(variable, 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 * Get all variables alive at a specific statement
* *
* @param statement The statement * @param statementIdx Index of the statement
* @return List of all live variables. * @return List of all live variables.
*/ */
public List<VariableRef> getAlive(Statement statement) { public List<VariableRef> getAlive(int statementIdx) {
ArrayList<VariableRef> aliveVars = new ArrayList<>(); ArrayList<VariableRef> aliveVars = new ArrayList<>();
for(VariableRef variable : liveRanges.keySet()) { for(Map.Entry<VariableRef,LiveRange> entry : liveRanges.entrySet()) {
LiveRange liveRange = liveRanges.get(variable); if(entry.getValue().contains(statementIdx)) {
if(liveRange.contains(statement)) { aliveVars.add(entry.getKey());
aliveVars.add(variable);
} }
} }
return aliveVars; return aliveVars;

View File

@ -43,7 +43,7 @@ public class LiveRangeVariablesEffective {
this.statementLiveVariables = new LinkedHashMap<>(); this.statementLiveVariables = new LinkedHashMap<>();
for(ControlFlowBlock block : program.getGraph().getAllBlocks()) { for(ControlFlowBlock block : program.getGraph().getAllBlocks()) {
for(Statement statement : block.getStatements()) { 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 * @return All variables effectively alive at the statement on the call-path
*/ */
public Collection<VariableRef> getEffectiveAliveAtStmt(CallPath callPath) { public Collection<VariableRef> getEffectiveAliveAtStmt(CallPath callPath) {
LinkedHashSet<VariableRef> effectiveAlive = new LinkedHashSet<>();
// Add alive at call // Add alive at call
effectiveAlive.addAll(callPath.getAlive()); LinkedHashSet<VariableRef> effectiveAlive = new LinkedHashSet<>(callPath.getAlive());
// Clear out any variables referenced in the method // Clear out any variables referenced in the method
effectiveAlive.removeAll(referencedInProcedure); effectiveAlive.removeAll(referencedInProcedure);
// Add alive at statement // Add alive at statement

View File

@ -80,7 +80,7 @@ public abstract class StatementBase implements Statement {
} }
LiveRangeVariables liveRanges = program.getLiveRangeVariables(); LiveRangeVariables liveRanges = program.getLiveRangeVariables();
StringBuilder alive = new StringBuilder(); StringBuilder alive = new StringBuilder();
alive.append(getAliveString(liveRanges.getAlive(this))); alive.append(getAliveString(liveRanges.getAlive(index)));
LiveRangeVariablesEffective liveRangeVariablesEffective = program.getLiveRangeVariablesEffective(); LiveRangeVariablesEffective liveRangeVariablesEffective = program.getLiveRangeVariablesEffective();
if(liveRangeVariablesEffective != null) { if(liveRangeVariablesEffective != null) {
LiveRangeVariablesEffective.AliveCombinations aliveCombinations = liveRangeVariablesEffective.getAliveCombinations(this); LiveRangeVariablesEffective.AliveCombinations aliveCombinations = liveRangeVariablesEffective.getAliveCombinations(this);

View File

@ -14,12 +14,12 @@ public class StatementInfos {
private ControlFlowGraph graph; private ControlFlowGraph graph;
/** Maps statement index to block label. */ /** Maps statement index to block label. */
private Map<Integer, LabelRef> stmtBlocks; private Map<Integer, ControlFlowBlock> stmtBlocks;
/** Maps statement index to statement. */ /** Maps statement index to statement. */
private Map<Integer, Statement> stmtIdx; 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.graph = program.getGraph();
this.stmtBlocks = stmtBlocks; this.stmtBlocks = stmtBlocks;
this.stmtIdx = stmtIdx; this.stmtIdx = stmtIdx;
@ -32,7 +32,7 @@ public class StatementInfos {
* @return The block label * @return The block label
*/ */
public LabelRef getBlockRef(Integer stmtIdx) { 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 * @return The block label
*/ */
public LabelRef getBlockRef(Statement stmt) { 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 * @return The containing block
*/ */
public ControlFlowBlock getBlock(Statement stmt) { public ControlFlowBlock getBlock(Statement stmt) {
return graph.getBlock(getBlockRef(stmt)); return stmtBlocks.get(stmt.getIndex());
} }
/** /**

View File

@ -65,7 +65,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
boolean modified = false; boolean modified = false;
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) { for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
for(Statement stmt : block.getStatements()) { for(Statement stmt : block.getStatements()) {
List<VariableRef> aliveNextStmt = liveRanges.getAlive(stmt); List<VariableRef> aliveNextStmt = liveRanges.getAlive(stmt.getIndex());
Collection<VariableRef> definedNextStmt = referenceInfo.getDefinedVars(stmt); Collection<VariableRef> definedNextStmt = referenceInfo.getDefinedVars(stmt);
initLiveRange(liveRanges, definedNextStmt); initLiveRange(liveRanges, definedNextStmt);
Collection<PreviousStatement> previousStmts = getPreviousStatements(stmt); Collection<PreviousStatement> previousStmts = getPreviousStatements(stmt);
@ -76,7 +76,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
// Add all vars alive in the next statement // Add all vars alive in the next statement
for(VariableRef aliveVar : aliveNextStmt) { for(VariableRef aliveVar : aliveNextStmt) {
if(!definedNextStmt.contains(aliveVar)) { if(!definedNextStmt.contains(aliveVar)) {
boolean addAlive = liveRanges.addAlive(aliveVar, previousStmt.getStatement()); boolean addAlive = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx());
modified |= addAlive; modified |= addAlive;
if(addAlive && getLog().isVerboseLiveRanges()) { if(addAlive && getLog().isVerboseLiveRanges()) {
getLog().append("Propagated alive var " + aliveVar + " to " + previousStmt.getStatement()); getLog().append("Propagated alive var " + aliveVar + " to " + previousStmt.getStatement());
@ -92,7 +92,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
for(VariableRef aliveVar : aliveNextStmt) { for(VariableRef aliveVar : aliveNextStmt) {
// Add all variables to previous that are not used inside the method // Add all variables to previous that are not used inside the method
if(procUsed.contains(aliveVar)) { if(procUsed.contains(aliveVar)) {
boolean addUsedVar = liveRanges.addAlive(aliveVar, previousStmt.getStatement()); boolean addUsedVar = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx());
modified |= addUsedVar; modified |= addUsedVar;
if(addUsedVar && getLog().isVerboseLiveRanges()) { if(addUsedVar && getLog().isVerboseLiveRanges()) {
getLog().append("Propagated alive var used in method into method " + aliveVar + " to " + previousStmt.getStatement()); 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) { for(VariableRef aliveVar : aliveNextStmt) {
// Add all variables to previous that are not used inside the method // Add all variables to previous that are not used inside the method
if(!procUsed.contains(aliveVar)) { if(!procUsed.contains(aliveVar)) {
boolean addSkipVar = liveRanges.addAlive(aliveVar, previousStmt.getStatement()); boolean addSkipVar = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx());
modified |= addSkipVar; modified |= addSkipVar;
if(addSkipVar && getLog().isVerboseLiveRanges()) { if(addSkipVar && getLog().isVerboseLiveRanges()) {
getLog().append("Propagated alive var unused in method by skipping call " + aliveVar + " to " + previousStmt.getStatement()); 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 // Add all variables to previous that are used inside the method
if(procUsed.contains(aliveVar)) { if(procUsed.contains(aliveVar)) {
if(!definedNextStmt.contains(aliveVar)) { if(!definedNextStmt.contains(aliveVar)) {
boolean usedVar = liveRanges.addAlive(aliveVar, previousStmt.getStatement()); boolean usedVar = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx());
modified |= usedVar; modified |= usedVar;
if(usedVar && getLog().isVerboseLiveRanges()) { if(usedVar && getLog().isVerboseLiveRanges()) {
getLog().append("Propagated alive used in method out of method " + aliveVar + " to " + previousStmt.getStatement()); 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 // If current statement is a phi add the used variables to previous based on the phi entries
StatementPhiBlock phi = (StatementPhiBlock) stmt; StatementPhiBlock phi = (StatementPhiBlock) stmt;
ControlFlowBlock previousBlock = ControlFlowBlock previousBlock =
getProgram().getStatementInfos().getBlock(previousStmt.getStatement()); getProgram().getStatementInfos().getBlock(previousStmt.getStatementIdx());
for(StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) { for(StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) { for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
if(phiRValue.getPredecessor().equals(previousBlock.getLabel())) { if(phiRValue.getPredecessor().equals(previousBlock.getLabel())) {
if(phiRValue.getrValue() instanceof VariableRef) { if(phiRValue.getrValue() instanceof VariableRef) {
VariableRef usedVar = (VariableRef) phiRValue.getrValue(); VariableRef usedVar = (VariableRef) phiRValue.getrValue();
boolean addUsed = liveRanges.addAlive(usedVar, previousStmt.getStatement()); boolean addUsed = liveRanges.addAlive(usedVar, previousStmt.getStatementIdx());
modified |= addUsed; modified |= addUsed;
if(addUsed && getLog().isVerboseLiveRanges()) { if(addUsed && getLog().isVerboseLiveRanges()) {
getLog().append("Adding used phi var " + usedVar + " to " + previousStmt.getStatement()); getLog().append("Adding used phi var " + usedVar + " to " + previousStmt.getStatement());
@ -182,7 +182,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
} else { } else {
// Not a phi block - add used vars to all previous blocks // Not a phi block - add used vars to all previous blocks
for(VariableRef usedVar : usedNextStmt) { for(VariableRef usedVar : usedNextStmt) {
boolean addUsed = liveRanges.addAlive(usedVar, previousStmt.getStatement()); boolean addUsed = liveRanges.addAlive(usedVar, previousStmt.getStatementIdx());
modified |= addUsed; modified |= addUsed;
if(addUsed && getLog().isVerboseLiveRanges()) { if(addUsed && getLog().isVerboseLiveRanges()) {
getLog().append("Adding used var " + usedVar + " to " + previousStmt.getStatement()); getLog().append("Adding used var " + usedVar + " to " + previousStmt.getStatement());
@ -346,6 +346,10 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
return statement; return statement;
} }
public int getStatementIdx() {
return statement.getIndex();
}
public Type getType() { public Type getType() {
return type; return type;
} }

View File

@ -75,9 +75,8 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
getProgram().getCallGraph().getCallers(procedure.getRef()); getProgram().getCallGraph().getCallers(procedure.getRef());
for(CallGraph.CallBlock.Call caller : callers) { for(CallGraph.CallBlock.Call caller : callers) {
// Each caller creates its own call-paths // Each caller creates its own call-paths
StatementCall callStatement = int callStatementIdx = caller.getCallStatementIdx();
(StatementCall) getProgram().getStatementInfos().getStatement(caller.getCallStatementIdx()); ControlFlowBlock callBlock = getProgram().getStatementInfos().getBlock(callStatementIdx);
ControlFlowBlock callBlock = getProgram().getStatementInfos().getBlock(callStatement);
ScopeRef callScopeRef = callBlock.getScope(); ScopeRef callScopeRef = callBlock.getScope();
Scope callScope = getProgram().getScope().getScope(callScopeRef); Scope callScope = getProgram().getScope().getScope(callScopeRef);
if(callScope instanceof Procedure) { if(callScope instanceof Procedure) {
@ -95,7 +94,7 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
Collection<VariableRef> alive = new LinkedHashSet<>(); Collection<VariableRef> alive = new LinkedHashSet<>();
alive.addAll(callerPath.getAlive()); alive.addAll(callerPath.getAlive());
alive.removeAll(referencedInCaller); alive.removeAll(referencedInCaller);
alive.addAll(liveRangeVariables.getAlive(callStatement)); alive.addAll(liveRangeVariables.getAlive(callStatementIdx));
Pass2AliasElimination.Aliases innerAliases = getCallAliases(procedure, callBlock); Pass2AliasElimination.Aliases innerAliases = getCallAliases(procedure, callBlock);
Pass2AliasElimination.Aliases pathAliases = new Pass2AliasElimination.Aliases(); Pass2AliasElimination.Aliases pathAliases = new Pass2AliasElimination.Aliases();
pathAliases.addAll(callerPath.getPathAliases()); pathAliases.addAll(callerPath.getPathAliases());

View File

@ -24,11 +24,11 @@ public class PassNStatementInfos extends Pass2SsaOptimization {
*/ */
@Override @Override
public boolean step() { public boolean step() {
LinkedHashMap<Integer, LabelRef> stmtBlocks = new LinkedHashMap<>(); LinkedHashMap<Integer, ControlFlowBlock> stmtBlocks = new LinkedHashMap<>();
LinkedHashMap<Integer, Statement> stmtIdx = new LinkedHashMap<>(); LinkedHashMap<Integer, Statement> stmtIdx = new LinkedHashMap<>();
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) { for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
for(Statement statement : block.getStatements()) { for(Statement statement : block.getStatements()) {
stmtBlocks.put(statement.getIndex(), block.getLabel()); stmtBlocks.put(statement.getIndex(), block);
stmtIdx.put(statement.getIndex(), statement); stmtIdx.put(statement.getIndex(), statement);
} }
} }