1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-02 09:29:35 +00:00

Implemented usage counting in sub-constant elimination. Added some more fragments

This commit is contained in:
jespergravgaard 2017-06-17 11:09:59 +02:00
parent e5f1f7f387
commit 01a26b4710
13 changed files with 91 additions and 13 deletions

View File

@ -0,0 +1,3 @@
lda {zpby1}
clc
adc #{coby1}

View File

@ -0,0 +1,3 @@
lda {zpby1}
clc
adc {zpby2}

View File

@ -0,0 +1 @@
sta {zpby1}

View File

@ -0,0 +1,3 @@
clc
adc #{coby1}
sta {zpby1}

View File

@ -32,7 +32,7 @@ public class ControlFlowGraphBaseVisitor<T> {
} else if(statement instanceof StatementPhi) {
return visitPhi((StatementPhi) statement);
} else if(statement instanceof StatementCall) {
return visitCallLValue((StatementCall) statement);
return visitCall((StatementCall) statement);
} else if(statement instanceof StatementReturn) {
return visitReturn((StatementReturn) statement);
} else if(statement instanceof StatementProcedureBegin) {
@ -76,7 +76,7 @@ public class ControlFlowGraphBaseVisitor<T> {
return null;
}
public T visitCallLValue(StatementCall callLValue) {
public T visitCall(StatementCall callLValue) {
return null;
}

View File

@ -156,7 +156,7 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
}
@Override
public StatementCall visitCallLValue(StatementCall callLValue) {
public StatementCall visitCall(StatementCall callLValue) {
LValue lValue = callLValue.getLValue();
String procedureName = callLValue.getProcedureName();
List<RValue> parameters = callLValue.getParameters();

View File

@ -19,7 +19,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
}
@Override
public StatementCall visitCallLValue(StatementCall origCall) {
public StatementCall visitCall(StatementCall origCall) {
// Procedure strategy implemented is currently variable-based transfer of parameters/return values
// Generate parameter passing assignments
Procedure procedure = origCall.getProcedure();

View File

@ -17,7 +17,7 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
}
@Override
public StatementCall visitCallLValue(StatementCall origCall) {
public StatementCall visitCall(StatementCall origCall) {
// Procedure strategy implemented is currently variable-based transfer of parameters/return values
// Generate return value assignment
Procedure procedure = origCall.getProcedure();

View File

@ -1,5 +1,8 @@
package dk.camelot64.kickc.icl;
import java.util.HashMap;
import java.util.Map;
/**
* Compiler Pass eliminating several additions of constants by consolidating them to a single (compile time) constant c1+v+c2 => (c1+c2)+v
*
@ -12,6 +15,8 @@ package dk.camelot64.kickc.icl;
*/
public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
private Map<Variable, Integer> usages;
public Pass2ConstantAdditionElimination(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
}
@ -24,6 +29,9 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
@Override
public boolean optimize() {
boolean optimized = false;
this.usages = countVarUsages();
// Examine all assigments - performing constant consolidation
for (ControlFlowBlock block : getGraph().getAllBlocks()) {
for (Statement statement : block.getStatements()) {
@ -116,6 +124,10 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
* @return The consolidated constant. Null if no sub-constants were found.
*/
private ConstantInteger consolidateSubConstants(Variable variable) {
if(usages.get(variable)>1) {
System.out.println("Multiple usages for variable. Not optimizing sub-constant "+variable);
return null;
}
StatementAssignment assignment = getGraph().getAssignment(variable);
if (assignment != null && assignment.getOperator() != null && "+".equals(assignment.getOperator().getOperator())) {
if (assignment.getRValue1() instanceof ConstantInteger) {

View File

@ -110,7 +110,7 @@ public abstract class Pass2SsaOptimization {
}
@Override
public Void visitCallLValue(StatementCall call) {
public Void visitCall(StatementCall call) {
if(call.getParameters()!=null) {
List<RValue> newParams = new ArrayList<>();
for (RValue parameter : call.getParameters()) {
@ -309,4 +309,57 @@ public abstract class Pass2SsaOptimization {
return usages;
}
protected Map<Variable, Integer> countVarUsages() {
final HashMap<Variable, Integer> usages = new HashMap<>();
ControlFlowGraphBaseVisitor usageVisitor = new ControlFlowGraphBaseVisitor() {
private void addUsage(RValue rVal) {
if(rVal instanceof Variable) {
Variable var = (Variable) rVal;
Integer usage = usages.get(var);
if (usage == null) {
usage = 0;
}
usage = usage + 1;
usages.put(var, usage);
} else if(rVal instanceof PointerDereference) {
throw new RuntimeException("Unexpected pointer dereference!");
}
}
@Override
public Object visitAssignment(StatementAssignment assignment) {
addUsage(assignment.getRValue1());
addUsage(assignment.getRValue2());
return null;
}
@Override
public Object visitReturn(StatementReturn aReturn) {
addUsage(aReturn.getValue());
return null;
}
@Override
public Object visitCall(StatementCall call) {
if(call.getParameters()!=null) {
for (RValue param : call.getParameters()) {
addUsage(param);
}
}
return null;
}
@Override
public Object visitPhi(StatementPhi phi) {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
addUsage(previousSymbol.getRValue());
}
return null;
}
};
usageVisitor.visitGraph(getGraph());
return usages;
}
}

View File

@ -53,13 +53,16 @@ public class Pass3RegisterAllocation {
//allocation.allocate(symbols.getVariable("$0"), new RegisterAllocation.RegisterAByte());
//allocation.allocate(symbols.getVariable("$2"), new RegisterAllocation.RegisterAByte());
//allocation.allocate(symbols.getVariable("$3"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("$1"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("$3"), new RegisterAllocation.RegisterALUByte());
allocation.allocate(symbols.getVariable("$4"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("$6"), new RegisterAllocation.RegisterALUByte());
allocation.allocate(symbols.getVariable("$7"), new RegisterAllocation.RegisterAByte());
//allocation.allocate(symbols.getVariable("$1"), new RegisterAllocation.RegisterAByte());
//allocation.allocate(symbols.getVariable("$3"), new RegisterAllocation.RegisterALUByte());
//allocation.allocate(symbols.getVariable("$4"), new RegisterAllocation.RegisterAByte());
//allocation.allocate(symbols.getVariable("$6"), new RegisterAllocation.RegisterALUByte());
//allocation.allocate(symbols.getVariable("$7"), new RegisterAllocation.RegisterAByte());
//allocation.allocate(symbols.getVariable("inc::a#2"), new RegisterAllocation.RegisterAByte());
//allocation.allocate(symbols.getVariable("bv#0"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("sum::b#0"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("inc::b#1"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("a#0"), new RegisterAllocation.RegisterAByte());
symbols.setAllocation(allocation);
}

View File

@ -64,7 +64,7 @@ public class Main {
List<Pass2SsaOptimization> optimizations = new ArrayList<>();
optimizations.add(new Pass2CullEmptyBlocks(controlFlowGraph, programScope));
optimizations.add(new Pass2ConstantPropagation(controlFlowGraph, programScope));
//optimizations.add(new Pass2ConstantAdditionElimination(controlFlowGraph, programScope));
optimizations.add(new Pass2ConstantAdditionElimination(controlFlowGraph, programScope));
optimizations.add(new Pass2AliasElimination(controlFlowGraph, programScope));
optimizations.add(new Pass2RedundantPhiElimination(controlFlowGraph, programScope));
optimizations.add(new Pass2SelfPhiElimination(controlFlowGraph, programScope));

View File

@ -1,6 +1,6 @@
byte a = 12;
byte s = sum(5,a);
a = a+s;
a = a+s+4;
a = sum(s, a);
byte sum(byte b1, byte b2) {