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

Added full compile log to test

This commit is contained in:
Jesper Gravgaard 2017-07-15 23:26:45 +02:00
parent 8e59603418
commit 0116c9e21d
24 changed files with 4134 additions and 212 deletions

View File

@ -0,0 +1,25 @@
package dk.camelot64.kickc;
/** Log of actions & results during compile*/
public class CompileLog {
StringBuilder log;
public CompileLog() {
this.log = new StringBuilder();
}
public void append(String msg) {
log.append(msg);
log.append("\n");
}
public StringBuilder getLog() {
return log;
}
@Override
public String toString() {
return log.toString();
}
}

View File

@ -17,11 +17,13 @@ public class Compiler {
private AsmProgram asmProgram;
private ControlFlowGraph graph;
private Scope symbols;
private CompileLog log;
public CompilationResult(AsmProgram asmProgram, ControlFlowGraph graph, Scope symbols) {
public CompilationResult(AsmProgram asmProgram, ControlFlowGraph graph, Scope symbols, CompileLog log) {
this.asmProgram = asmProgram;
this.graph = graph;
this.symbols = symbols;
this.log = log;
}
public AsmProgram getAsmProgram() {
@ -35,10 +37,15 @@ public class Compiler {
public Scope getSymbols() {
return symbols;
}
public CompileLog getLog() {
return log;
}
}
public CompilationResult compile(final CharStream input) throws IOException {
System.out.println(input.toString());
CompileLog log = new CompileLog();
log.append(input.toString());
KickCLexer lexer = new KickCLexer(input);
KickCParser parser = new KickCParser(new CommonTokenStream(lexer));
parser.setBuildParseTree(true);
@ -49,50 +56,50 @@ public class Compiler {
}
});
KickCParser.FileContext file = parser.file();
Pass1GenerateStatementSequence pass1GenerateStatementSequence = new Pass1GenerateStatementSequence();
Pass1GenerateStatementSequence pass1GenerateStatementSequence = new Pass1GenerateStatementSequence(log);
pass1GenerateStatementSequence.generate(file);
StatementSequence statementSequence = pass1GenerateStatementSequence.getSequence();
Scope programScope = pass1GenerateStatementSequence.getProgramScope();
Pass1TypeInference pass1TypeInference = new Pass1TypeInference();
pass1TypeInference.inferTypes(statementSequence, programScope);
System.out.println("PROGRAM");
System.out.println(statementSequence.toString());
System.out.println("SYMBOLS");
System.out.println(programScope.getSymbolTableContents());
log.append("PROGRAM");
log.append(statementSequence.toString());
log.append("SYMBOLS");
log.append(programScope.getSymbolTableContents());
Pass1GenerateControlFlowGraph pass1GenerateControlFlowGraph = new Pass1GenerateControlFlowGraph(programScope);
ControlFlowGraph controlFlowGraph = pass1GenerateControlFlowGraph.generate(statementSequence);
System.out.println("INITIAL CONTROL FLOW GRAPH");
System.out.println(controlFlowGraph.toString());
log.append("INITIAL CONTROL FLOW GRAPH");
log.append(controlFlowGraph.toString());
Pass1ProcedureCallParameters pass1ProcedureCallParameters =
new Pass1ProcedureCallParameters(programScope, controlFlowGraph);
controlFlowGraph = pass1ProcedureCallParameters.generate();
System.out.println("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL");
System.out.println(controlFlowGraph.toString());
log.append("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL");
log.append(controlFlowGraph.toString());
Pass1GenerateSingleStaticAssignmentForm pass1GenerateSingleStaticAssignmentForm =
new Pass1GenerateSingleStaticAssignmentForm(programScope, controlFlowGraph);
new Pass1GenerateSingleStaticAssignmentForm(log, programScope, controlFlowGraph);
pass1GenerateSingleStaticAssignmentForm.generate();
System.out.println("CONTROL FLOW GRAPH SSA");
System.out.println(controlFlowGraph.toString());
log.append("CONTROL FLOW GRAPH SSA");
log.append(controlFlowGraph.toString());
Pass1ProcedureCallsReturnValue pass1ProcedureCallsReturnValue =
new Pass1ProcedureCallsReturnValue(programScope, controlFlowGraph);
controlFlowGraph = pass1ProcedureCallsReturnValue.generate();
System.out.println("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN");
System.out.println(controlFlowGraph.toString());
log.append("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN");
log.append(controlFlowGraph.toString());
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 Pass2AliasElimination(controlFlowGraph, programScope));
optimizations.add(new Pass2RedundantPhiElimination(controlFlowGraph, programScope));
optimizations.add(new Pass2SelfPhiElimination(controlFlowGraph, programScope));
optimizations.add(new Pass2ConditionalJumpSimplification(controlFlowGraph, programScope));
optimizations.add(new Pass2CullEmptyBlocks(controlFlowGraph, programScope, log));
optimizations.add(new Pass2ConstantPropagation(controlFlowGraph, programScope, log));
optimizations.add(new Pass2ConstantAdditionElimination(controlFlowGraph, programScope, log));
optimizations.add(new Pass2AliasElimination(controlFlowGraph, programScope, log));
optimizations.add(new Pass2RedundantPhiElimination(controlFlowGraph, programScope, log));
optimizations.add(new Pass2SelfPhiElimination(controlFlowGraph, programScope, log));
optimizations.add(new Pass2ConditionalJumpSimplification(controlFlowGraph, programScope, log));
List<Pass2SsaAssertion> assertions = new ArrayList<>();
assertions.add(new Pass2AssertSymbols(controlFlowGraph, programScope));
@ -107,10 +114,10 @@ public class Compiler {
for (Pass2SsaOptimization optimization : optimizations) {
boolean stepOptimized = optimization.optimize();
if (stepOptimized) {
System.out.println("Succesful SSA optimization "+optimization);
log.append("Succesful SSA optimization "+optimization+"");
ssaOptimized = true;
System.out.println("CONTROL FLOW GRAPH");
System.out.println(controlFlowGraph.toString());
log.append("CONTROL FLOW GRAPH");
log.append(controlFlowGraph.toString());
}
}
}
@ -122,27 +129,27 @@ public class Compiler {
Pass3CodeGeneration pass3CodeGeneration = new Pass3CodeGeneration(controlFlowGraph, programScope);
AsmProgram asmProgram = pass3CodeGeneration.generate();
System.out.println("INITIAL ASM");
System.out.println(asmProgram.toString());
log.append("INITIAL ASM");
log.append(asmProgram.toString());
List<Pass4AsmOptimization> pass4Optimizations = new ArrayList<>();
pass4Optimizations.add(new Pass4NextJumpElimination(asmProgram));
pass4Optimizations.add(new Pass4UnnecesaryLoadElimination(asmProgram));
pass4Optimizations.add(new Pass4NextJumpElimination(asmProgram, log));
pass4Optimizations.add(new Pass4UnnecesaryLoadElimination(asmProgram, log));
boolean asmOptimized = true;
while(asmOptimized) {
asmOptimized = false;
for (Pass4AsmOptimization optimization : pass4Optimizations) {
boolean stepOtimized = optimization.optimize();
if(stepOtimized) {
System.out.println("Succesful ASM optimization "+optimization);
log.append("Succesful ASM optimization "+optimization);
asmOptimized = true;
System.out.println("ASSEMBLER");
System.out.println(asmProgram.toString());
log.append("ASSEMBLER");
log.append(asmProgram.toString());
}
}
}
return new CompilationResult(asmProgram, controlFlowGraph, programScope);
return new CompilationResult(asmProgram, controlFlowGraph, programScope, log);
}
}

View File

@ -10,6 +10,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
@ -33,26 +34,26 @@ public class AsmFragment {
private String signature;
public AsmFragment(StatementConditionalJump conditionalJump, ControlFlowBlock block, Scope symbols, ControlFlowGraph graph) {
this.bindings = new HashMap<>();
this.bindings = new LinkedHashMap<>();
this.symbols = symbols;
String conditionalJumpSignature = conditionalJumpSignature(conditionalJump, block, graph);
setSignature(conditionalJumpSignature);
}
public AsmFragment(StatementAssignment assignment, Scope symbols) {
this.bindings = new HashMap<>();
this.bindings = new LinkedHashMap<>();
this.symbols = symbols;
setSignature(assignmentSignature(assignment.getLValue(), assignment.getRValue1(), assignment.getOperator(), assignment.getRValue2()));
}
public AsmFragment(LValue lValue, RValue rValue, Scope symbols) {
this.bindings = new HashMap<>();
this.bindings = new LinkedHashMap<>();
this.symbols = symbols;
setSignature(assignmentSignature(lValue, null, null, rValue));
}
public AsmFragment(StatementAssignment assignment, StatementAssignment assignmentAlu, Scope symbols) {
this.bindings = new HashMap<>();
this.bindings = new LinkedHashMap<>();
this.symbols = symbols;
setSignature(assignmentWithAluSignature(assignment, assignmentAlu));

View File

@ -3,6 +3,7 @@ package dk.camelot64.kickc.asm.parser;
import dk.camelot64.kickc.asm.*;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
@ -16,7 +17,7 @@ public class AsmProgramStaticRegisterValues {
public AsmProgramStaticRegisterValues(AsmProgram program) {
this.program = program;
this.values = new HashMap<>();
this.values = new LinkedHashMap<>();
initValues();
}

View File

@ -1,6 +1,8 @@
package dk.camelot64.kickc.icl;
import java.util.HashMap;
import dk.camelot64.kickc.CompileLog;
import java.util.LinkedHashMap;
import java.util.Map;
/**
@ -10,10 +12,12 @@ import java.util.Map;
*/
public class Pass1GenerateSingleStaticAssignmentForm {
private CompileLog log;
private Scope symbols;
private ControlFlowGraph controlFlowGraph;
public Pass1GenerateSingleStaticAssignmentForm(Scope symbols, ControlFlowGraph controlFlowGraph) {
public Pass1GenerateSingleStaticAssignmentForm(CompileLog log, Scope symbols, ControlFlowGraph controlFlowGraph) {
this.log = log;
this.symbols = symbols;
this.controlFlowGraph = controlFlowGraph;
}
@ -23,7 +27,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
versionAllUses();
boolean done;
do {
System.out.println("Completing Phi functions...");
log.append("Completing Phi functions...");
done = completePhiFunctions();
} while (!done);
}
@ -63,9 +67,9 @@ public class Pass1GenerateSingleStaticAssignmentForm {
private void versionAllUses() {
for (ControlFlowBlock block : controlFlowGraph.getAllBlocks()) {
// Newest version of variables in the block.
Map<VariableUnversioned, VariableVersion> blockVersions = new HashMap<>();
Map<VariableUnversioned, VariableVersion> blockVersions = new LinkedHashMap<>();
// New phi functions introduced in the block to create versions of variables.
Map<VariableUnversioned, VariableVersion> blockNewPhis = new HashMap<>();
Map<VariableUnversioned, VariableVersion> blockNewPhis = new LinkedHashMap<>();
for (Statement statement : block.getStatements()) {
if(statement instanceof StatementReturn) {
StatementReturn statementReturn = (StatementReturn) statement;
@ -163,7 +167,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
* false if new phis were added, meaning another iteration is needed.
*/
private boolean completePhiFunctions() {
Map<Label, Map<VariableUnversioned, VariableVersion>> newPhis = new HashMap<>();
Map<Label, Map<VariableUnversioned, VariableVersion>> newPhis = new LinkedHashMap<>();
Map<Label, Map<VariableUnversioned, VariableVersion>> symbolMap = buildSymbolMap();
for (ControlFlowBlock block : this.controlFlowGraph.getAllBlocks()) {
for (Statement statement : block.getStatements()) {
@ -183,7 +187,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
// No previous symbol found in predecessor block. Look in new phi functions.
Map<VariableUnversioned, VariableVersion> predecessorNewPhis = newPhis.get(predecessorLabel);
if (predecessorNewPhis == null) {
predecessorNewPhis = new HashMap<>();
predecessorNewPhis = new LinkedHashMap<>();
newPhis.put(predecessorLabel, predecessorNewPhis);
}
previousSymbol = predecessorNewPhis.get(unversioned);
@ -216,7 +220,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
* Maps Control Flow Block Label -> ( Unversioned Symbol -> Versioned Symbol) for all relevant symbols.
*/
private Map<Label, Map<VariableUnversioned, VariableVersion>> buildSymbolMap() {
Map<Label, Map<VariableUnversioned, VariableVersion>> symbolMap = new HashMap<>();
Map<Label, Map<VariableUnversioned, VariableVersion>> symbolMap = new LinkedHashMap<>();
for (ControlFlowBlock block : this.controlFlowGraph.getAllBlocks()) {
for (Statement statement : block.getStatements()) {
if (statement instanceof StatementAssignment) {
@ -228,7 +232,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
VariableUnversioned unversioned = versioned.getVersionOf();
Map<VariableUnversioned, VariableVersion> blockMap = symbolMap.get(label);
if (blockMap == null) {
blockMap = new HashMap<>();
blockMap = new LinkedHashMap<>();
symbolMap.put(label, blockMap);
}
blockMap.put(unversioned, versioned);
@ -240,7 +244,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
Label label = block.getLabel();
Map<VariableUnversioned, VariableVersion> blockMap = symbolMap.get(label);
if (blockMap == null) {
blockMap = new HashMap<>();
blockMap = new LinkedHashMap<>();
symbolMap.put(label, blockMap);
}
blockMap.put(unversioned, versioned);
@ -253,7 +257,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
VariableUnversioned unversioned = versioned.getVersionOf();
Map<VariableUnversioned, VariableVersion> blockMap = symbolMap.get(label);
if (blockMap == null) {
blockMap = new HashMap<>();
blockMap = new LinkedHashMap<>();
symbolMap.put(label, blockMap);
}
blockMap.put(unversioned, versioned);

View File

@ -1,5 +1,6 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.parser.KickCBaseVisitor;
import dk.camelot64.kickc.parser.KickCParser;
import org.antlr.v4.runtime.ParserRuleContext;
@ -14,11 +15,13 @@ import java.util.Stack;
*/
public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
private CompileLog log;
private Scope programScope;
private Stack<Scope> scopeStack;
private StatementSequence sequence;
public Pass1GenerateStatementSequence() {
public Pass1GenerateStatementSequence(CompileLog log) {
this.log = log;
this.programScope = new Scope();
this.scopeStack = new Stack<>();
scopeStack.push(programScope);
@ -214,7 +217,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
@Override
public Void visitStmtDeclaration(KickCParser.StmtDeclarationContext ctx) {
if (ctx.getChild(0).getText().equals("const")) {
System.out.println("Const!" + ctx.getText());
log.append("Const!" + ctx.getText());
}
SymbolType type = (SymbolType) visit(ctx.typeDecl());
VariableUnversioned lValue = getCurrentSymbols().addVariable(ctx.NAME().getText(), type);
@ -300,7 +303,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
@Override
public RValue visitExprCast(KickCParser.ExprCastContext ctx) {
System.out.println("Cast type ignored!");
log.append("Cast type ignored!");
return (RValue) visit(ctx.expr());
}
@ -449,7 +452,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
for (PrePostModifier mod : modifiers) {
Statement stmt = new StatementAssignment((LValue) mod.child, mod.operator, mod.child);
parser.sequence.addStatement(stmt);
System.out.println("Adding pre/post-modifier "+stmt);
parser.log.append("Adding pre/post-modifier "+stmt);
}
}

View File

@ -1,5 +1,7 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.CompileLog;
import java.util.*;
/**
@ -7,8 +9,8 @@ import java.util.*;
*/
public class Pass2AliasElimination extends Pass2SsaOptimization {
public Pass2AliasElimination(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
public Pass2AliasElimination(ControlFlowGraph graph, Scope scope, CompileLog log) {
super(graph, scope, log);
}
@ -28,7 +30,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
for (Variable var : aliasSet.getEliminateVars()) {
str.append(var + " ");
}
System.out.println("Alias " + str);
log.append("Alias " + str);
}
return (aliases.size() > 0);
}
@ -81,7 +83,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
}
public Map<Variable, Variable> getReplacements() {
HashMap<Variable, Variable> replacements = new HashMap<>();
HashMap<Variable, Variable> replacements = new LinkedHashMap<>();
for (AliasSet aliasSet : aliases) {
Variable keepVar = aliasSet.getKeepVar();
for (Variable var : aliasSet.getEliminateVars()) {
@ -232,7 +234,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
RValue phiRValue = previousSymbol.getRValue();
if (aliasSet.contains(phiRValue)) {
System.out.println("Alias candidate removed " + phiRValue);
log.append("Alias candidate removed " + phiRValue);
aliasSet.remove(phiRValue);
break;
}

View File

@ -1,5 +1,7 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.CompileLog;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -11,8 +13,8 @@ public class Pass2ConditionalJumpSimplification extends Pass2SsaOptimization {
private Map<Variable, List<Statement>> allUsages;
public Pass2ConditionalJumpSimplification(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
public Pass2ConditionalJumpSimplification(ControlFlowGraph graph, Scope scope, CompileLog log) {
super(graph, scope, log);
}
/**
@ -55,7 +57,7 @@ public class Pass2ConditionalJumpSimplification extends Pass2SsaOptimization {
conditionalJump.setOperator(conditionAssignment.getOperator());
conditionalJump.setRValue2(conditionAssignment.getRValue2());
simpleConditionVars.add(conditionVar);
System.out.println("Simple Condition " + conditionVar + " " + conditionalJump);
log.append("Simple Condition " + conditionVar + " " + conditionalJump);
break;
default:
}

View File

@ -1,5 +1,7 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.CompileLog;
import java.util.HashMap;
import java.util.Map;
@ -17,8 +19,8 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
private Map<Variable, Integer> usages;
public Pass2ConstantAdditionElimination(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
public Pass2ConstantAdditionElimination(ControlFlowGraph graph, Scope scope, CompileLog log) {
super(graph, scope, log);
}
/**
@ -64,7 +66,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
ConstantInteger idxConstant = (ConstantInteger) pointerDereferenceIndexed.getIndex();
int newPtr = ptrConstant.getNumber() + idxConstant.getNumber();
assignment.setLValue(new PointerDereferenceSimple(new ConstantInteger(newPtr)));
System.out.println("Consolidated assigned array index constant in assignment " + assignment.getLValue());
log.append("Consolidated assigned array index constant in assignment " + assignment.getLValue());
return true;
}
if(pointerDereferenceIndexed.getPointer() instanceof ConstantInteger && pointerDereferenceIndexed.getIndex() instanceof Variable) {
@ -74,7 +76,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
ConstantInteger ptrConstant = (ConstantInteger) pointerDereferenceIndexed.getPointer();
int newPtr = ptrConstant.getNumber() + consolidated.getNumber();
pointerDereferenceIndexed.setPointer(new ConstantInteger(newPtr));
System.out.println("Consolidated assigned array index constant in assignment " + assignment.getLValue());
log.append("Consolidated assigned array index constant in assignment " + assignment.getLValue());
return true;
}
}
@ -89,7 +91,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
assignment.setRValue1(null);
assignment.setOperator(new Operator("*"));
assignment.setRValue2(new ConstantInteger(newPtr));
System.out.println("Consolidated referenced array index constant in assignment " + assignment.getLValue());
log.append("Consolidated referenced array index constant in assignment " + assignment.getLValue());
return true;
}
if (assignment.getRValue1() instanceof ConstantInteger && assignment.getRValue2() instanceof Variable) {
@ -99,7 +101,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
ConstantInteger ptrConstant = (ConstantInteger) assignment.getRValue1();
int newPtr = ptrConstant.getNumber() + consolidated.getNumber();
assignment.setRValue1(new ConstantInteger(newPtr));
System.out.println("Consolidated referenced array index constant in assignment " + assignment.getLValue());
log.append("Consolidated referenced array index constant in assignment " + assignment.getLValue());
return true;
}
}
@ -113,7 +115,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
if (consolidated != null) {
ConstantInteger const1 = (ConstantInteger) assignment.getRValue1();
assignment.setRValue1(new ConstantInteger(const1.getNumber() + consolidated.getNumber()));
System.out.println("Consolidated constant in assignment " + assignment.getLValue());
log.append("Consolidated constant in assignment " + assignment.getLValue());
return true;
}
} else if (assignment.getRValue1() instanceof Variable && assignment.getRValue2() instanceof ConstantInteger) {
@ -128,7 +130,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
} else {
assignment.setRValue2(new ConstantInteger(newNumber));
}
System.out.println("Consolidated constant in assignment " + assignment.getLValue());
log.append("Consolidated constant in assignment " + assignment.getLValue());
return true;
}
}
@ -143,7 +145,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
*/
private ConstantInteger consolidateSubConstants(Variable variable) {
if(getUsages(variable) >1) {
System.out.println("Multiple usages for variable. Not optimizing sub-constant "+variable);
log.append("Multiple usages for variable. Not optimizing sub-constant "+variable);
return null;
}
StatementAssignment assignment = getGraph().getAssignment(variable);

View File

@ -1,13 +1,16 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.CompileLog;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/** Compiler Pass propagating constants in expressions eliminating constant variables */
public class Pass2ConstantPropagation extends Pass2SsaOptimization {
public Pass2ConstantPropagation(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
public Pass2ConstantPropagation(ControlFlowGraph graph, Scope scope, CompileLog log) {
super(graph, scope, log);
}
/**
@ -19,7 +22,7 @@ public class Pass2ConstantPropagation extends Pass2SsaOptimization {
final Map<Variable, Constant> constants = findConstantVariables();
for (Variable constantVar : constants.keySet()) {
Constant constantValue = constants.get(constantVar);
System.out.println("Constant " + constantVar + " " + constantValue);
log.append("Constant " + constantVar + " " + constantValue);
}
removeAssignments(constants.keySet());
deleteSymbols(constants.keySet());
@ -32,7 +35,7 @@ public class Pass2ConstantPropagation extends Pass2SsaOptimization {
* @return Map from Variable to the Constant value
*/
private Map<Variable, Constant> findConstantVariables() {
final Map<Variable, Constant> constants = new HashMap<>();
final Map<Variable, Constant> constants = new LinkedHashMap<>();
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override
public Void visitAssignment(StatementAssignment assignment) {

View File

@ -1,12 +1,14 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.CompileLog;
import java.util.*;
/** Pass that culls empty control flow blocks from the program */
public class Pass2CullEmptyBlocks extends Pass2SsaOptimization {
public Pass2CullEmptyBlocks(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
public Pass2CullEmptyBlocks(ControlFlowGraph graph, Scope scope, CompileLog log) {
super(graph, scope, log);
}
@Override
@ -23,7 +25,7 @@ public class Pass2CullEmptyBlocks extends Pass2SsaOptimization {
// Replace all jumps (default/conditional/call) to @removeBlock with a jump to the default successor
final List<ControlFlowBlock> predecessors = getGraph().getPredecessors(removeBlock);
for (ControlFlowBlock predecessor : predecessors) {
Map<Label, Label> replace = new HashMap<>();
Map<Label, Label> replace = new LinkedHashMap<>();
replace.put(removeBlock.getLabel(), successor.getLabel());
if (removeBlock.getLabel().equals(predecessor.getDefaultSuccessor())) {
predecessor.setDefaultSuccessor(successor.getLabel());
@ -61,7 +63,7 @@ public class Pass2CullEmptyBlocks extends Pass2SsaOptimization {
phiFixVisitor.visitBlock(successor);
getGraph().getAllBlocks().remove(removeBlock);
getSymbols().remove(removeBlock.getLabel());
System.out.println("Culled Empty Block " + removeBlock.getLabel());
log.append("Culled Empty Block " + removeBlock.getLabel());
}
return remove.size()>0;
}

View File

@ -1,13 +1,16 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.CompileLog;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/** Compiler Pass eliminating redundant phi functions */
public class Pass2RedundantPhiElimination extends Pass2SsaOptimization {
public Pass2RedundantPhiElimination(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
public Pass2RedundantPhiElimination(ControlFlowGraph graph, Scope scope, CompileLog log) {
super(graph, scope, log);
}
/**
@ -21,7 +24,7 @@ public class Pass2RedundantPhiElimination extends Pass2SsaOptimization {
replaceVariables(aliases);
for (Variable var : aliases.keySet()) {
RValue alias = aliases.get(var);
System.out.println("Redundant Phi " + var + " " + alias);
log.append("Redundant Phi " + var + " " + alias);
}
return aliases.size()>0;
}
@ -31,7 +34,7 @@ public class Pass2RedundantPhiElimination extends Pass2SsaOptimization {
* @return Map from (phi) Variable to the previous value
*/
private Map<Variable, RValue> findRedundantPhis() {
final Map<Variable, RValue> aliases = new HashMap<>();
final Map<Variable, RValue> aliases = new LinkedHashMap<>();
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override
public Void visitPhi(StatementPhi phi) {

View File

@ -1,12 +1,14 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.CompileLog;
import java.util.Iterator;
/** Compiler Pass eliminating phi self assignments */
public class Pass2SelfPhiElimination extends Pass2SsaOptimization {
public Pass2SelfPhiElimination(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
public Pass2SelfPhiElimination(ControlFlowGraph graph, Scope scope, CompileLog log) {
super(graph, scope, log);
}
/**
@ -23,7 +25,7 @@ public class Pass2SelfPhiElimination extends Pass2SsaOptimization {
if (previousSymbol.getRValue().equals(phi.getLValue())) {
iterator.remove();
optimized[0] = Boolean.TRUE;
System.out.println("Self Phi Eliminated "+phi.getLValue());
log.append("Self Phi Eliminated "+phi.getLValue());
}
}
return null;

View File

@ -1,5 +1,7 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.CompileLog;
import java.util.*;
/**
@ -8,14 +10,20 @@ import java.util.*;
*/
public abstract class Pass2SsaOptimization {
protected CompileLog log;
private ControlFlowGraph graph;
private Scope scope;
public Pass2SsaOptimization(ControlFlowGraph graph, Scope scope) {
public Pass2SsaOptimization(ControlFlowGraph graph, Scope scope,CompileLog log) {
this.log = log;
this.graph = graph;
this.scope = scope;
}
public CompileLog getLog() {
return log;
}
public ControlFlowGraph getGraph() {
return graph;
}
@ -270,7 +278,7 @@ public abstract class Pass2SsaOptimization {
}
public Map<LValue, StatementAssignment> getAllAssignments() {
final HashMap<LValue, StatementAssignment> assignments = new HashMap<>();
final HashMap<LValue, StatementAssignment> assignments = new LinkedHashMap<>();
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override
public Void visitAssignment(StatementAssignment assignment) {
@ -283,7 +291,7 @@ public abstract class Pass2SsaOptimization {
}
public Map<RValue, List<Statement>> getAllUsages() {
final HashMap<RValue, List<Statement>> usages = new HashMap<>();
final HashMap<RValue, List<Statement>> usages = new LinkedHashMap<>();
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override
public Void visitAssignment(StatementAssignment assignment) {
@ -326,7 +334,7 @@ public abstract class Pass2SsaOptimization {
}
protected Map<Variable, Integer> countVarUsages() {
final HashMap<Variable, Integer> usages = new HashMap<>();
final HashMap<Variable, Integer> usages = new LinkedHashMap<>();
ControlFlowGraphBaseVisitor usageVisitor = new ControlFlowGraphBaseVisitor() {
private void addUsage(RValue rVal) {
if(rVal instanceof Variable) {

View File

@ -90,7 +90,14 @@ public class Pass3CodeGeneration {
private void genBlockEntryPoints(AsmProgram asm, ControlFlowBlock block) {
if (block.hasPhiStatements()) {
for (ControlFlowBlock predecessor : graph.getPredecessors(block)) {
List<ControlFlowBlock> predecessors = new ArrayList<>(graph.getPredecessors(block));
Collections.sort(predecessors, new Comparator<ControlFlowBlock>() {
@Override
public int compare(ControlFlowBlock o1, ControlFlowBlock o2) {
return o1.getLabel().getFullName().compareTo(o2.getLabel().getFullName());
}
});
for (ControlFlowBlock predecessor : predecessors) {
if (block.getLabel().equals(predecessor.getConditionalSuccessor())) {
genBlockPhiTransition(asm, predecessor, block);
asm.addInstruction("JMP", AsmAddressingMode.ABS, block.getLabel().getFullName().replace('@', 'B').replace(':','_'));

View File

@ -1,5 +1,6 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.asm.AsmLine;
import dk.camelot64.kickc.asm.AsmProgram;
@ -11,10 +12,12 @@ import java.util.List;
**/
public abstract class Pass4AsmOptimization {
protected CompileLog log;
private AsmProgram program;
public Pass4AsmOptimization(AsmProgram program) {
public Pass4AsmOptimization(AsmProgram program, CompileLog log) {
this.program = program;
this.log = log;
}
/**
@ -28,11 +31,15 @@ public abstract class Pass4AsmOptimization {
return program;
}
public CompileLog getLog() {
return log;
}
public void remove(List<AsmLine> remove) {
for (Iterator<AsmLine> iterator = program.getLines().iterator(); iterator.hasNext(); ) {
AsmLine line = iterator.next();
if (remove.contains(line)) {
System.out.println("Removing instruction "+line.getAsm());
log.append("Removing instruction "+line.getAsm());
iterator.remove();
}
}

View File

@ -1,5 +1,6 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.asm.AsmInstruction;
import dk.camelot64.kickc.asm.AsmLabel;
import dk.camelot64.kickc.asm.AsmLine;
@ -11,8 +12,8 @@ import java.util.List;
/** Optimize assembler code by removing jumps to labels immediately following the jump */
public class Pass4NextJumpElimination extends Pass4AsmOptimization {
public Pass4NextJumpElimination(AsmProgram program) {
super(program);
public Pass4NextJumpElimination(AsmProgram program, CompileLog log) {
super(program, log);
}
public boolean optimize() {

View File

@ -1,5 +1,6 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.asm.*;
import dk.camelot64.kickc.asm.parser.AsmProgramStaticRegisterValues;
@ -9,8 +10,8 @@ import java.util.List;
/** Maps out register values entering all instructions. Removes unnecessary loads / clears / sets */
public class Pass4UnnecesaryLoadElimination extends Pass4AsmOptimization {
public Pass4UnnecesaryLoadElimination(AsmProgram program) {
super(program);
public Pass4UnnecesaryLoadElimination(AsmProgram program, CompileLog log) {
super(program, log);
}
@Override

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.icl;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/** Register Allocation for Variable Symbols */
@ -10,7 +11,7 @@ public class RegisterAllocation {
private Map<Variable, Register> allocation;
public RegisterAllocation() {
this.allocation = new HashMap<>();
this.allocation = new LinkedHashMap<>();
}
/**

View File

@ -1,5 +1,7 @@
package dk.camelot64.kickc.test;
import com.sun.org.apache.xpath.internal.SourceTree;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import dk.camelot64.kickc.Compiler;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
@ -34,13 +36,15 @@ public class TestCompilationOutput {
}
private void testFile(String fileName) throws IOException, URISyntaxException {
String InputPath = testPath + fileName + ".kc";
CharStream input = CharStreams.fromFileName(InputPath);
String inputPath = testPath + fileName + ".kc";
System.out.println("Testing output for "+inputPath);
CharStream input = CharStreams.fromFileName(inputPath);
Compiler compiler = new Compiler();
Compiler.CompilationResult output = compiler.compile(input);
assertOutput(fileName, ".asm", output.getAsmProgram().toString());
assertOutput(fileName, ".sym", output.getSymbols().getSymbolTableContents());
assertOutput(fileName, ".cfg", output.getGraph().toString());
assertOutput(fileName, ".asm", output.getAsmProgram().toString());
assertOutput(fileName, ".log", output.getLog().toString());
}
private void assertOutput(
@ -48,7 +52,14 @@ public class TestCompilationOutput {
String extension,
String outputString) throws IOException, URISyntaxException {
// Read reference file
List<String> refLines = loadReferenceLines(fileName, extension);
List<String> refLines = null;
try {
refLines = loadReferenceLines(fileName, extension);
} catch (Exception e) {
writeOutputFile(fileName, extension, outputString);
System.out.println("Error loading reference."+e.getMessage());
return;
}
// Split output into outLines
List<String> outLines = getOutLines(outputString);
for (int i = 0; i < outLines.size(); i++) {

View File

@ -41,39 +41,39 @@ plot__B1_from_plot:
// (byte) plot::y#2 = (byte) 16 // zpby1=coby1
lda #16
sta 100
// (byte) plot::i#3 = (byte) 0 // xby=coby1
ldx #0
// (byte*) plot::line#2 = (word) 1236 // zpptrby1=cowo1
lda #<1236
sta 101
lda #>1236
sta 101+1
// (byte) plot::i#3 = (byte) 0 // xby=coby1
ldx #0
plot__B1_from_B15:
// (byte) plot::y#2 = (byte) plot::y#0 // register copy
// (byte*) plot::line#2 = (byte*) plot::line#0 // register copy
// (byte) plot::i#3 = (byte) plot::i#0 // register copy
// (byte) plot::y#2 = (byte) plot::y#1 // register copy
// (byte) plot::i#3 = (byte) plot::i#1 // register copy
// (byte*) plot::line#2 = (byte*) plot::line#1 // register copy
plot__B1:
plot__B2_from_B1:
// (byte) plot::x#2 = (byte) 0 // yby=coby1
ldy #0
// (byte) plot::i#2 = (byte) plot::i#3 // register copy
plot__B2_from_B2:
// (byte) plot::x#2 = (byte) plot::x#0 // register copy
// (byte) plot::i#2 = (byte) plot::i#0 // register copy
// (byte) plot::x#2 = (byte) plot::x#1 // register copy
// (byte) plot::i#2 = (byte) plot::i#1 // register copy
plot__B2:
// (byte~) plot::$3 (word) 4096 *idx (byte) plot::i#2 // aby=cowo1_staridx_xby
lda 4096,x
// *((byte*) plot::line#2 + (byte) plot::x#2) (byte~) plot::$3 // ptr_zpptrby1_yby=aby
sta (101),y
// (byte) plot::i#0 ++ (byte) plot::i#2 // xby=_inc_xby
// (byte) plot::i#1 ++ (byte) plot::i#2 // xby=_inc_xby
inx
// (byte) plot::x#0 ++ (byte) plot::x#2 // yby=_inc_yby
// (byte) plot::x#1 ++ (byte) plot::x#2 // yby=_inc_yby
iny
// if((byte) plot::x#0<(byte) 16) goto plot::@2 // yby_lt_coby1_then_la1
// if((byte) plot::x#1<(byte) 16) goto plot::@2 // yby_lt_coby1_then_la1
cpy #16
bcc plot__B2_from_B2
B15:
// (byte*) plot::line#0 (byte*) plot::line#2 + (byte) 40 // zpptrby1=zpptrby1_plus_coby1
// (byte*) plot::line#1 (byte*) plot::line#2 + (byte) 40 // zpptrby1=zpptrby1_plus_coby1
lda 101
clc
adc #40
@ -81,9 +81,9 @@ B15:
bcc !+
inc 101+1
!:
// (byte) plot::y#0 -- (byte) plot::y#2 // zpby1=_dec_zpby1
// (byte) plot::y#1 -- (byte) plot::y#2 // zpby1=_dec_zpby1
dec 100
// if((byte) plot::y#0!=(byte) 0) goto plot::@1 // zpby1_neq_0_then_la1
// if((byte) plot::y#1!=(byte) 0) goto plot::@1 // zpby1_neq_0_then_la1
lda 100
bne plot__B1_from_B15
plot__Breturn:
@ -93,48 +93,48 @@ flip__B1_from_flip:
// (byte) flip::r#2 = (byte) 16 // zpby1=coby1
lda #16
sta 104
// (byte) flip::dstIdx#5 = (byte) 15 // yby=coby1
ldy #15
// (byte) flip::srcIdx#3 = (byte) 0 // xby=coby1
ldx #0
// (byte) flip::dstIdx#5 = (byte) 15 // yby=coby1
ldy #15
flip__B1_from_B11:
// (byte) flip::r#2 = (byte) flip::r#0 // register copy
// (byte) flip::dstIdx#5 = (byte) flip::dstIdx#1 // register copy
// (byte) flip::srcIdx#3 = (byte) flip::srcIdx#0 // register copy
// (byte) flip::r#2 = (byte) flip::r#1 // register copy
// (byte) flip::srcIdx#3 = (byte) flip::srcIdx#1 // register copy
// (byte) flip::dstIdx#5 = (byte) flip::dstIdx#2 // register copy
flip__B1:
flip__B2_from_B1:
// (byte) flip::dstIdx#3 = (byte) flip::dstIdx#5 // register copy
// (byte) flip::srcIdx#2 = (byte) flip::srcIdx#3 // register copy
// (byte) flip::c#2 = (byte) 16 // zpby1=coby1
lda #16
sta 103
// (byte) flip::dstIdx#3 = (byte) flip::dstIdx#5 // register copy
// (byte) flip::srcIdx#2 = (byte) flip::srcIdx#3 // register copy
flip__B2_from_B2:
// (byte) flip::dstIdx#3 = (byte) flip::dstIdx#0 // register copy
// (byte) flip::srcIdx#2 = (byte) flip::srcIdx#0 // register copy
// (byte) flip::c#2 = (byte) flip::c#0 // register copy
// (byte) flip::c#2 = (byte) flip::c#1 // register copy
// (byte) flip::dstIdx#3 = (byte) flip::dstIdx#1 // register copy
// (byte) flip::srcIdx#2 = (byte) flip::srcIdx#1 // register copy
flip__B2:
// (byte~) flip::$0 (word) 4096 *idx (byte) flip::srcIdx#2 // aby=cowo1_staridx_xby
lda 4096,x
// *((word) 4352 + (byte) flip::dstIdx#3) (byte~) flip::$0 // ptr_cowo1_yby=aby
sta 4352,y
// (byte) flip::srcIdx#0 ++ (byte) flip::srcIdx#2 // xby=_inc_xby
// (byte) flip::srcIdx#1 ++ (byte) flip::srcIdx#2 // xby=_inc_xby
inx
// (byte) flip::dstIdx#0 (byte) flip::dstIdx#3 + (byte) 16 // yby=yby_plus_coby1
// (byte) flip::dstIdx#1 (byte) flip::dstIdx#3 + (byte) 16 // yby=yby_plus_coby1
tya
clc
adc #16
tay
// (byte) flip::c#0 -- (byte) flip::c#2 // zpby1=_dec_zpby1
// (byte) flip::c#1 -- (byte) flip::c#2 // zpby1=_dec_zpby1
dec 103
// if((byte) flip::c#0!=(byte) 0) goto flip::@2 // zpby1_neq_0_then_la1
// if((byte) flip::c#1!=(byte) 0) goto flip::@2 // zpby1_neq_0_then_la1
lda 103
bne flip__B2_from_B2
B11:
// (byte) flip::dstIdx#1 -- (byte) flip::dstIdx#0 // yby=_dec_yby
// (byte) flip::dstIdx#2 -- (byte) flip::dstIdx#1 // yby=_dec_yby
dey
// (byte) flip::r#0 -- (byte) flip::r#2 // zpby1=_dec_zpby1
// (byte) flip::r#1 -- (byte) flip::r#2 // zpby1=_dec_zpby1
dec 104
// if((byte) flip::r#0!=(byte) 0) goto flip::@1 // zpby1_neq_0_then_la1
// if((byte) flip::r#1!=(byte) 0) goto flip::@1 // zpby1_neq_0_then_la1
lda 104
bne flip__B1_from_B11
flip__B3_from_B11:
@ -159,14 +159,14 @@ prepare__B1_from_prepare:
// (byte) prepare::i#2 = (byte) 0 // xby=coby1
ldx #0
prepare__B1_from_B1:
// (byte) prepare::i#2 = (byte) prepare::i#0 // register copy
// (byte) prepare::i#2 = (byte) prepare::i#1 // register copy
prepare__B1:
// *((word) 4096 + (byte) prepare::i#2) (byte) prepare::i#2 // ptr_cowo1_xby=xby
txa
sta 4096,x
// (byte) prepare::i#0 ++ (byte) prepare::i#2 // xby=_inc_xby
// (byte) prepare::i#1 ++ (byte) prepare::i#2 // xby=_inc_xby
inx
// if((byte) prepare::i#0!=(byte) 0) goto prepare::@1 // xby_neq_0_then_la1
// if((byte) prepare::i#1!=(byte) 0) goto prepare::@1 // xby_neq_0_then_la1
cpx #0
bne prepare__B1_from_B1
prepare__Breturn:

View File

@ -1,79 +1,64 @@
@2: from @20 @6 @BEGIN
(byte) c#2 ← phi( @20/(byte) 25 @6/(byte) c#1 @BEGIN/(byte) 25 )
to:@3
@BEGIN: from
call prepare param-assignment
to:@2
@20: from @19
if(true) goto @2
to:@END
prepare::@1: from prepare prepare::@1
(byte) prepare::i#2 ← phi( prepare/(byte) 0 prepare::@1/(byte) prepare::i#0 )
*((word) 4096 + (byte) prepare::i#2) ← (byte) prepare::i#2
(byte) prepare::i#0 ← ++ (byte) prepare::i#2
if((byte) prepare::i#0!=(byte) 0) goto prepare::@1
to:prepare::@return
flip::@2: from flip::@1 flip::@2
(byte) flip::dstIdx#3 ← phi( flip::@1/(byte) flip::dstIdx#5 flip::@2/(byte) flip::dstIdx#0 )
(byte) flip::srcIdx#2 ← phi( flip::@1/(byte) flip::srcIdx#3 flip::@2/(byte) flip::srcIdx#0 )
(byte) flip::c#2 ← phi( flip::@1/(byte) 16 flip::@2/(byte) flip::c#0 )
(byte~) flip::$0 ← (word) 4096 *idx (byte) flip::srcIdx#2
*((word) 4352 + (byte) flip::dstIdx#3) ← (byte~) flip::$0
(byte) flip::srcIdx#0 ← ++ (byte) flip::srcIdx#2
(byte) flip::dstIdx#0 ← (byte) flip::dstIdx#3 + (byte) 16
(byte) flip::c#0 ← -- (byte) flip::c#2
if((byte) flip::c#0!=(byte) 0) goto flip::@2
to:@11
@2: from @20 @6 @BEGIN
(byte) c#2 ← phi( @20/(byte) 25 @6/(byte) c#1 @BEGIN/(byte) 25 )
to:@3
@3: from @2 @3
(byte~) $1 ← * (word) 53266
if((byte~) $1!=(byte) 254) goto @3
to:@4
@4: from @3 @4
(byte~) $3 ← * (word) 53266
if((byte~) $3!=(byte) 255) goto @4
to:@6
@11: from flip::@2
(byte) flip::dstIdx#1 ← -- (byte) flip::dstIdx#0
(byte) flip::r#0 ← -- (byte) flip::r#2
if((byte) flip::r#0!=(byte) 0) goto flip::@1
to:flip::@3
plot::@return: from @15
return
to:@RETURN
plot::@2: from plot::@1 plot::@2
(byte) plot::x#2 ← phi( plot::@1/(byte) 0 plot::@2/(byte) plot::x#0 )
(byte) plot::i#2 ← phi( plot::@1/(byte) plot::i#3 plot::@2/(byte) plot::i#0 )
(byte~) plot::$3 ← (word) 4096 *idx (byte) plot::i#2
*((byte*) plot::line#2 + (byte) plot::x#2) ← (byte~) plot::$3
(byte) plot::i#0 ← ++ (byte) plot::i#2
(byte) plot::x#0 ← ++ (byte) plot::x#2
if((byte) plot::x#0<(byte) 16) goto plot::@2
to:@15
@6: from @4
(byte) c#1 ← -- (byte) c#2
if((byte) c#1!=(byte) 0) goto @2
to:@7
plot::@1: from @15 plot
(byte) plot::y#2 ← phi( @15/(byte) plot::y#0 plot/(byte) 16 )
(byte*) plot::line#2 ← phi( @15/(byte*) plot::line#0 plot/(word) 1236 )
(byte) plot::i#3 ← phi( @15/(byte) plot::i#0 plot/(byte) 0 )
to:plot::@2
@7: from @6
call flip param-assignment
to:@19
@19: from @7
call plot param-assignment
to:@20
@20: from @19
if(true) goto @2
to:@END
prepare: from @BEGIN
to:prepare::@1
prepare::@1: from prepare prepare::@1
(byte) prepare::i#2 ← phi( prepare/(byte) 0 prepare::@1/(byte) prepare::i#1 )
*((word) 4096 + (byte) prepare::i#2) ← (byte) prepare::i#2
(byte) prepare::i#1 ← ++ (byte) prepare::i#2
if((byte) prepare::i#1!=(byte) 0) goto prepare::@1
to:prepare::@return
prepare::@return: from prepare::@1
return
to:@RETURN
flip: from @7
to:flip::@1
prepare: from @BEGIN
to:prepare::@1
@7: from @6
call flip param-assignment
to:@19
flip::@1: from @11 flip
(byte) flip::r#2 ← phi( @11/(byte) flip::r#0 flip/(byte) 16 )
(byte) flip::dstIdx#5 ← phi( @11/(byte) flip::dstIdx#1 flip/(byte) 15 )
(byte) flip::srcIdx#3 ← phi( @11/(byte) flip::srcIdx#0 flip/(byte) 0 )
(byte) flip::r#2 ← phi( @11/(byte) flip::r#1 flip/(byte) 16 )
(byte) flip::srcIdx#3 ← phi( @11/(byte) flip::srcIdx#1 flip/(byte) 0 )
(byte) flip::dstIdx#5 ← phi( @11/(byte) flip::dstIdx#2 flip/(byte) 15 )
to:flip::@2
@15: from plot::@2
(byte*) plot::line#0 ← (byte*) plot::line#2 + (byte) 40
(byte) plot::y#0 ← -- (byte) plot::y#2
if((byte) plot::y#0!=(byte) 0) goto plot::@1
to:plot::@return
flip::@2: from flip::@1 flip::@2
(byte) flip::c#2 ← phi( flip::@1/(byte) 16 flip::@2/(byte) flip::c#1 )
(byte) flip::dstIdx#3 ← phi( flip::@1/(byte) flip::dstIdx#5 flip::@2/(byte) flip::dstIdx#1 )
(byte) flip::srcIdx#2 ← phi( flip::@1/(byte) flip::srcIdx#3 flip::@2/(byte) flip::srcIdx#1 )
(byte~) flip::$0 ← (word) 4096 *idx (byte) flip::srcIdx#2
*((word) 4352 + (byte) flip::dstIdx#3) ← (byte~) flip::$0
(byte) flip::srcIdx#1 ← ++ (byte) flip::srcIdx#2
(byte) flip::dstIdx#1 ← (byte) flip::dstIdx#3 + (byte) 16
(byte) flip::c#1 ← -- (byte) flip::c#2
if((byte) flip::c#1!=(byte) 0) goto flip::@2
to:@11
@11: from flip::@2
(byte) flip::dstIdx#2 ← -- (byte) flip::dstIdx#1
(byte) flip::r#1 ← -- (byte) flip::r#2
if((byte) flip::r#1!=(byte) 0) goto flip::@1
to:flip::@3
flip::@3: from @11 flip::@3
(byte) flip::i#2 ← phi( @11/(byte) 0 flip::@3/(byte) flip::i#1 )
(byte~) flip::$4 ← (word) 4352 *idx (byte) flip::i#2
@ -81,16 +66,31 @@ flip::@3: from @11 flip::@3
(byte) flip::i#1 ← ++ (byte) flip::i#2
if((byte) flip::i#1!=(byte) 0) goto flip::@3
to:flip::@return
@END: from @20
@19: from @7
call plot param-assignment
to:@20
plot: from @19
to:plot::@1
@3: from @2 @3
(byte~) $1 ← * (word) 53266
if((byte~) $1!=(byte) 254) goto @3
to:@4
flip::@return: from flip::@3
return
to:@RETURN
plot: from @19
to:plot::@1
plot::@1: from @15 plot
(byte) plot::y#2 ← phi( @15/(byte) plot::y#1 plot/(byte) 16 )
(byte) plot::i#3 ← phi( @15/(byte) plot::i#1 plot/(byte) 0 )
(byte*) plot::line#2 ← phi( @15/(byte*) plot::line#1 plot/(word) 1236 )
to:plot::@2
plot::@2: from plot::@1 plot::@2
(byte) plot::x#2 ← phi( plot::@1/(byte) 0 plot::@2/(byte) plot::x#1 )
(byte) plot::i#2 ← phi( plot::@1/(byte) plot::i#3 plot::@2/(byte) plot::i#1 )
(byte~) plot::$3 ← (word) 4096 *idx (byte) plot::i#2
*((byte*) plot::line#2 + (byte) plot::x#2) ← (byte~) plot::$3
(byte) plot::i#1 ← ++ (byte) plot::i#2
(byte) plot::x#1 ← ++ (byte) plot::x#2
if((byte) plot::x#1<(byte) 16) goto plot::@2
to:@15
@15: from plot::@2
(byte*) plot::line#1 ← (byte*) plot::line#2 + (byte) 40
(byte) plot::y#1 ← -- (byte) plot::y#2
if((byte) plot::y#1!=(byte) 0) goto plot::@1
to:plot::@return
plot::@return: from @15
return
to:@RETURN
@END: from @20

File diff suppressed because it is too large Load Diff

View File

@ -26,21 +26,21 @@
(label) flip::@3
(label) flip::@return
(byte) flip::c
(byte) flip::c#0 zp byte:103
(byte) flip::c#1 zp byte:103
(byte) flip::c#2 zp byte:103
(byte) flip::dstIdx
(byte) flip::dstIdx#0 reg byte y
(byte) flip::dstIdx#1 reg byte y
(byte) flip::dstIdx#2 reg byte y
(byte) flip::dstIdx#3 reg byte y
(byte) flip::dstIdx#5 reg byte y
(byte) flip::i
(byte) flip::i#1 reg byte x
(byte) flip::i#2 reg byte x
(byte) flip::r
(byte) flip::r#0 zp byte:104
(byte) flip::r#1 zp byte:104
(byte) flip::r#2 zp byte:104
(byte) flip::srcIdx
(byte) flip::srcIdx#0 reg byte x
(byte) flip::srcIdx#1 reg byte x
(byte) flip::srcIdx#2 reg byte x
(byte) flip::srcIdx#3 reg byte x
@ -50,23 +50,23 @@
(label) plot::@2
(label) plot::@return
(byte) plot::i
(byte) plot::i#0 reg byte x
(byte) plot::i#1 reg byte x
(byte) plot::i#2 reg byte x
(byte) plot::i#3 reg byte x
(byte*) plot::line
(byte*) plot::line#0 zp ptr byte:101
(byte*) plot::line#1 zp ptr byte:101
(byte*) plot::line#2 zp ptr byte:101
(byte) plot::x
(byte) plot::x#0 reg byte y
(byte) plot::x#1 reg byte y
(byte) plot::x#2 reg byte y
(byte) plot::y
(byte) plot::y#0 zp byte:100
(byte) plot::y#1 zp byte:100
(byte) plot::y#2 zp byte:100
(void()) prepare()
(label) prepare::@1
(label) prepare::@return
(byte) prepare::i
(byte) prepare::i#0 reg byte x
(byte) prepare::i#1 reg byte x
(byte) prepare::i#2 reg byte x