1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-05 07:40:39 +00:00

Implemented conditional simplification optimization

This commit is contained in:
jespergravgaard 2017-05-17 23:21:02 +02:00
parent 84c0b01354
commit d5ff6e3ea2
8 changed files with 196 additions and 17 deletions

View File

@ -26,7 +26,11 @@ public class AsmFragment {
this.bindings = new HashMap<>();
this.symbols = symbols;
StringBuilder signature = new StringBuilder();
signature.append(bind(conditionalJump.getCondition()));
if(conditionalJump.getRValue1()!=null) {
signature.append(bind(conditionalJump.getRValue1()));
signature.append(conditionalJump.getOperator().getOperator());
}
signature.append(bind(conditionalJump.getRValue2()));
signature.append("?");
signature.append(bind(conditionalJump.getDestination()));
setSignature(signature.toString());

View File

@ -0,0 +1,76 @@
package dk.camelot64.kickc.icl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Compiler Pass simplifying conditional jumps that are simple comparisons
*/
public class Pass2ConditionalJumpSimplification extends Pass2Optimization {
private Map<Variable, List<Statement>> allUsages;
public Pass2ConditionalJumpSimplification(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable);
}
/**
* Eliminate alias assignments replacing them with the aliased variable.
*/
@Override
public boolean optimize() {
final Map<LValue, StatementAssignment> assignments = getAllAssignments();
final Map<RValue, List<Statement>> usages = getAllUsages();
final List<Variable> simpleConditionVars = getSimpleConditions(assignments, usages);
removeAssignments(simpleConditionVars);
deleteSymbols(simpleConditionVars);
return (simpleConditionVars.size()>0);
}
private List<Variable> getSimpleConditions(final Map<LValue, StatementAssignment> assignments, final Map<RValue, List<Statement>> usages) {
final List<Variable> simpleConditionVars = new ArrayList<>();
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override
public Void visitConditionalJump(StatementConditionalJump conditionalJump) {
if(conditionalJump.getRValue1()==null && conditionalJump.getOperator()==null) {
RValue conditionRValue = conditionalJump.getRValue2();
if(conditionRValue instanceof Variable && usages.get(conditionRValue).size()==1) {
Variable conditionVar = (Variable) conditionRValue;
StatementAssignment conditionAssignment = assignments.get(conditionVar);
if(conditionAssignment.getOperator()!=null) {
switch (conditionAssignment.getOperator().getOperator()) {
case "==":
case "<>":
case "!=":
case "<":
case ">":
case "<=":
case "=<":
case ">=":
case "=>":
conditionalJump.setRValue1(conditionAssignment.getRValue1());
conditionalJump.setOperator(conditionAssignment.getOperator());
conditionalJump.setRValue2(conditionAssignment.getRValue2());
simpleConditionVars.add(conditionVar);
System.out.println("Simple Condition " + conditionVar + " " + conditionalJump);
break;
default:
}
}
}
}
return null;
}
};
visitor.visitGraph(getGraph());
return simpleConditionVars;
}
}

View File

@ -1,8 +1,6 @@
package dk.camelot64.kickc.icl;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.*;
/**
* Optimization performed during Compiler Pass 2.
@ -66,8 +64,11 @@ public abstract class Pass2Optimization {
@Override
public Void visitConditionalJump(StatementConditionalJump conditionalJump) {
if(getAlias(aliases, conditionalJump.getCondition())!=null) {
conditionalJump.setCondition(getAlias(aliases, conditionalJump.getCondition()));
if(getAlias(aliases, conditionalJump.getRValue1())!=null) {
conditionalJump.setRValue1(getAlias(aliases, conditionalJump.getRValue1()));
}
if(getAlias(aliases, conditionalJump.getRValue2())!=null) {
conditionalJump.setRValue2(getAlias(aliases, conditionalJump.getRValue2()));
}
return null;
}
@ -196,5 +197,59 @@ public abstract class Pass2Optimization {
}
}
public Map<LValue, StatementAssignment> getAllAssignments() {
final HashMap<LValue, StatementAssignment> assignments = new HashMap<>();
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override
public Void visitAssignment(StatementAssignment assignment) {
assignments.put(assignment.getLValue(), assignment);
return null;
}
};
visitor.visitGraph(getGraph());
return assignments;
}
public Map<RValue, List<Statement>> getAllUsages() {
final HashMap<RValue, List<Statement>> usages = new HashMap<>();
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override
public Void visitAssignment(StatementAssignment assignment) {
addUsage(assignment.getRValue1(), assignment);
addUsage(assignment.getRValue2(), assignment);
return null;
}
@Override
public Void visitConditionalJump(StatementConditionalJump conditionalJump) {
addUsage(conditionalJump.getRValue1(), conditionalJump);
addUsage(conditionalJump.getRValue2(), conditionalJump);
return null;
}
@Override
public Void visitPhi(StatementPhi phi) {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
addUsage(previousSymbol.getRValue(), phi);
}
return null;
}
private void addUsage(RValue rValue, Statement statement) {
if (rValue == null) {
return;
}
List<Statement> use = usages.get(rValue);
if (use == null) {
use = new ArrayList<>();
usages.put(rValue, use);
}
use.add(statement);
}
};
visitor.visitGraph(getGraph());
return usages;
}
}

View File

@ -25,5 +25,4 @@ public class Pass3RegisterAllocation {
symbols.setAllocation(allocation);
}
}

View File

@ -5,35 +5,75 @@ package dk.camelot64.kickc.icl;
* Intermediate form used for compiler optimization.
* <br>
* <i> if ( Y<sub>j</sub> ) goto XX </i>
* <br>
* The condition may be a single boolean variable, or a comparison between two variables (==, &lt;&gt;, &lt;, &gt;, &lt;=, &gt;= )
*
*/
public class StatementConditionalJump implements Statement {
private RValue condition;
private RValue rValue1;
private Operator operator;
private RValue rValue2;
private Label destination;
public StatementConditionalJump(RValue condition, Label destination) {
this.condition = condition;
this.rValue1 = null;
this.operator = null;
this.rValue2 = condition;
this.destination = destination;
}
public RValue getCondition() {
return condition;
public StatementConditionalJump(RValue rValue1, Operator operator, RValue rValue2, Label destination) {
this.rValue1 = rValue1;
this.operator = operator;
this.rValue2 = rValue2;
this.destination = destination;
}
public RValue getRValue1() {
return rValue1;
}
public Operator getOperator() {
return operator;
}
public RValue getRValue2() {
return rValue2;
}
public Label getDestination() {
return destination;
}
@Override
public String toString() {
return "if("+condition+") goto "+destination.getName();
public void setRValue1(RValue rValue1) {
this.rValue1 = rValue1;
}
public void setCondition(RValue condition) {
this.condition = condition;
public void setOperator(Operator operator) {
this.operator = operator;
}
public void setRValue2(RValue rValue2) {
this.rValue2 = rValue2;
}
public void setDestination(Label destination) {
this.destination = destination;
}
@Override
public String toString() {
StringBuilder out = new StringBuilder();
out.append("if(");
if(rValue1!=null) {
out.append(rValue1);
out.append(operator.getOperator());
}
out.append(rValue2);
out.append(") goto ");
out.append(destination.getName());
return out.toString();
}
}

View File

@ -0,0 +1,4 @@
lda {zpby1}
cmp #{coby1}
bcc {la1}
beq {la1}

View File

@ -42,6 +42,7 @@ public class Main {
optimizations.add(new Pass2AliasElimination(controlFlowGraph, symbolTable));
optimizations.add(new Pass2RedundantPhiElimination(controlFlowGraph, symbolTable));
optimizations.add(new Pass2SelfPhiElimination(controlFlowGraph, symbolTable));
optimizations.add(new Pass2ConditionalJumpSimplification(controlFlowGraph, symbolTable));
boolean optimized = true;
while (optimized) {

View File

@ -2,7 +2,7 @@ byte n1 = 0;
byte n2 = 1;
byte i = 0;
byte fib = 0;
while(i<=10) {
while(i<=11) {
fib = n1 + n2;
n1 = n2;
n2 = fib;