1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Working on outputting variable labels in ASM. Moving register allocation & constant values into symbol table.

This commit is contained in:
jespergravgaard 2017-08-20 21:09:03 +02:00
parent df631667a0
commit 2707bd5861
32 changed files with 2113 additions and 478 deletions

View File

@ -21,6 +21,8 @@ public class Compiler {
KickCParser.FileContext file = pass0ParseInput(input, log);
Program program = pass1GenerateSSA(file, log);
pass2OptimizeSSA(program);
log.append("FINAL SYMBOL TABLE");
log.append(program.getScope().getSymbolTableContents(program));
pass3Analysis(program);
pass4RegisterAllocation(program);
pass5GenerateAndOptimizeAsm(program);
@ -110,6 +112,10 @@ public class Compiler {
program.setGraph(pass1ProcedureCallsReturnValue.generate());
log.append("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN");
log.append(program.getGraph().toString(program));
log.append("INITIAL SSA SYMBOL TABLE");
log.append(program.getScope().getSymbolTableContents(program));
return program;
}
@ -204,7 +210,7 @@ public class Compiler {
private void pass4RegisterAllocation(Program program) {
new Pass4ZeroPageAllocation(program).allocate();
new Pass4RegistersFinalize(program).allocate(false);
new Pass4RegistersFinalize(program).allocate(true);
// Initial Code generation
new Pass4CodeGeneration(program).generate();

View File

@ -1,7 +1,8 @@
Features
- Move the main code into a main() function, and disallow code outside functions. The main function per default has no parameters and exits with RTS.
- Add a for loop for(init;condition;increment) {stmt} -> { init; do { stmt; increment } while (condition) }
- Add for loop for(byte i: 1..100) { } and for(byte i : 100..0) {} (plus maybe .+. and .-. to make the inc/dec unambiguous)
- Improve locality of block sequence for if(cond) { stmt1; } else { stmt2; } to if(!cond) goto @else stmt1; jmp @end; @else: stmt2; @end:
- Optimize if/else by swapping if & else if cond is easier to evaluate than !cond.
- Add literal char syntax ( 'c' == (byte) 3 )
- Add signed bytes
- Add signed words
- Add Fixed Point number types fixed[8.8], fixed[16.8] - maybe even fixed[24.4]
@ -22,16 +23,23 @@ Features
+ Create a proper main function for the compiler
+ Add ++/-- incrementing/decrementing operators.
+ Optimize if's without else if(expr) { stmt; } -> $1=!expr; if($1) goto @1; stmt; @1:
+ Add a for loop for(init;condition;increment) {stmt} -> { init; do { stmt; increment } while (condition) }
+ Add for loop for(byte i: 1..100) { } and for(byte i : 100..0) {} (plus maybe .+. and .-. to make the inc/dec unambiguous)
Assembler Improvements
- Make generated ASM human readable.
+ Use hex-numbers
- add labels for constants and zp-variables.
+ Eliminate unnecessary labels in ASM
- Eliminate CPX from DEX, CPX #0, BNE la1
- Eliminate LDA from DEC $2, LDA $2, BNE la1
- Eliminate LDA from STA $11, LDA $11
- Better ASM static value analysis
- Not just constants - but also other values (value of var, value of var1[var2], value of var+4 etc.)
- Also analyze back/forward through block entry/exit
- Also analyze value of flags (eg. N=N(var1))
- Eliminate CPX from DEX, CPX #0, BNE la1 (using ASM static value analysis for N flag - it might be worth annotating CPX with the fact that only the N-flag is relevant - or creating a special instruction for setting the N-flag)
- Eliminate LDA from DEC $2, LDA $2, BNE la1 (using ASM static value analysis for N flag - it might be worth annotating LDA $2 with the fact that only the N-flag is relevant - or creating a special instruction for setting the N-flag)
- Eliminate LDA from STA $11, LDA $11 (using ASM static value analysis of A-register)
- Optimize by allowing resequencing of ASM (statements and phi assignments) in a final phase.
- ASM loop analysis: If all usages of a register has the same value move the assignment out of the loop (if the assignment is simple enough).
+ Eliminate unnecessary labels in ASM
Known Problems
+ Procedures that modify variables outside their scope does not work. Outer vars must be transfered in/out like parameters/return values to get it working.
@ -45,7 +53,11 @@ Register Allocation
- Optimize by finding optimal sequence for multiple phi assignments in entry-segments.
- Avoid clobbering alive vars
- Maybe support several fragments for the same operation with different cost and clobbering profiles.
- Add memory registers (if we need to free some ZP)
- Add memory registers (if we need to free some ZP).
- Implement fast combination elimination based on live ranges (skipping the ASM-code.)
- Improve combination testing by finding live range overlaps and not creating combinations that would create an overlap conflict.
- Combinations should be created in a tree-structure instead of just doing all combinations
- Example: For equivalence classes a, b, c if a&c have overlapping live ranges they can never have the same register. Therefore the combination iterator should not create combinations where C has the same register as a.
+ Limit number of combinations tested
+ Equivalences not tested through combinaitons should be tested individually afterwards.
+ Matrix Phi operation (instead of separate statements)

View File

@ -47,8 +47,12 @@ public class RegisterAllocation {
/** A zero page address used as a register for a single byte variable. */
public static class RegisterZpByte implements Register {
/** The ZP address used for the byte. */
private int zp;
/** The name used as a label for the register in the ASM code. */
private String name;
public RegisterZpByte(int zp) {
this.zp = zp;
}

View File

@ -6,7 +6,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
/** A fixed size array of another type */
public class SymbolTypeArray extends SymbolTypePointer {
private int size;
/** The fixed size of the array. Can by null, if the type is not known yet. (It will be constant before the compilation is done) */
private Integer size;
@JsonCreator
public SymbolTypeArray(
@ -16,40 +17,39 @@ public class SymbolTypeArray extends SymbolTypePointer {
this.size = size;
}
public SymbolTypeArray(SymbolType elementType) {
super(elementType);
this.size = null;
}
public int getSize() {
return size;
}
public void setSize(int size) {
public void setSize(Integer size) {
this.size = size;
}
@Override
public String getTypeName() {
return getElementType().getTypeName()+"["+size+"]";
return getElementType().getTypeName()+"["+(size==null?"":size)+"]";
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
SymbolTypeArray that = (SymbolTypeArray) o;
return size == that.size;
return size != null ? size.equals(that.size) : that.size == null;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + size;
result = 31 * result + (size != null ? size.hashCode() : 0);
return result;
}
}

View File

@ -2,32 +2,28 @@ package dk.camelot64.kickc.icl;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* A Symbol (variable, jump label, etc.)
*/
/** A Variable (or a Constant) */
public abstract class Variable implements Symbol {
/**
* The name of the symbol.
*/
/** The name of the variable. */
private String name;
/**
* Scope
*/
/** The scope containing the variable */
@JsonIgnore
private Scope scope;
/**
* The type of the symbol. VAR means tha type is unknown, and has not been inferred yet.
*/
/** The type of the variable. VAR means tha type is unknown, and has not been inferred yet. */
private SymbolType type;
/**
* true if the symbol type is infered (not declared)
*/
/** true if the symbol type is infered (not declared) */
private boolean inferredType;
/** If the variable is assigned to an ASM register, this contains the register. If null the variable has no no allocation (yet). Constants are never assigned to registers. */
private RegisterAllocation.Register allocation;
/** If the variable is a constant this is the constant value. If null the variable is not considered constant.*/
private Constant constant;
public Variable(String name, Scope scope, SymbolType type) {
this.name = name;
this.scope = scope;
@ -74,6 +70,26 @@ public abstract class Variable implements Symbol {
this.name = name;
}
public String getName() {
return name;
}
public RegisterAllocation.Register getAllocation() {
return allocation;
}
public void setAllocation(RegisterAllocation.Register allocation) {
this.allocation = allocation;
}
public Constant getConstant() {
return constant;
}
public void setConstant(Constant constant) {
this.constant = constant;
}
@JsonIgnore
public abstract boolean isVersioned();
@ -86,16 +102,21 @@ public abstract class Variable implements Symbol {
if (o == null || getClass() != o.getClass()) return false;
Variable variable = (Variable) o;
if (inferredType != variable.inferredType) return false;
if (!name.equals(variable.name)) return false;
if (!getFullName().equals(variable.getFullName())) return false;
return type.equals(variable.type);
if (name != null ? !name.equals(variable.name) : variable.name != null) return false;
if (scope != null ? !scope.equals(variable.scope) : variable.scope != null) return false;
if (type != null ? !type.equals(variable.type) : variable.type != null) return false;
if (allocation != null ? !allocation.equals(variable.allocation) : variable.allocation != null) return false;
return constant != null ? constant.equals(variable.constant) : variable.constant == null;
}
@Override
public int hashCode() {
int result = getFullName().hashCode();
result = 31 * result + type.hashCode();
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (scope != null ? scope.hashCode() : 0);
result = 31 * result + (type != null ? type.hashCode() : 0);
result = 31 * result + (inferredType ? 1 : 0);
result = 31 * result + (allocation != null ? allocation.hashCode() : 0);
result = 31 * result + (constant != null ? constant.hashCode() : 0);
return result;
}

View File

@ -414,11 +414,15 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
@Override
public SymbolType visitTypeArray(KickCParser.TypeArrayContext ctx) {
SymbolType elementType = (SymbolType) visit(ctx.typeDecl());
Constant size = ParseTreeConstantEvaluator.evaluate(ctx.expr());
if (size instanceof ConstantInteger) {
return new SymbolTypeArray(elementType, ((ConstantInteger) size).getNumber());
if(ctx.expr()!=null) {
Constant size = ParseTreeConstantEvaluator.evaluate(ctx.expr());
if (size instanceof ConstantInteger) {
return new SymbolTypeArray(elementType, ((ConstantInteger) size).getNumber());
} else {
throw new RuntimeException("Array size not a constant integer " + ctx.getText());
}
} else {
throw new RuntimeException("Array size not a constant integer " + ctx.getText());
return new SymbolTypeArray(elementType);
}
}

View File

@ -1,142 +0,0 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.icl.*;
/**
* Register Allocation for variables
*/
public class Pass3CustomRegisters {
private Program program;
public Pass3CustomRegisters(Program program) {
this.program = program;
}
public void allocate() {
RegisterAllocation allocation = program.getAllocation();
// Register allocation for loopnest.kc
allocation.setRegister(new VariableRef("nest2::j#2"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("nest2::j#1"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("nest2::i#2"), RegisterAllocation.getRegisterY());
allocation.setRegister(new VariableRef("nest2::i#1"), RegisterAllocation.getRegisterY());
// Register allocation for fibmem.kc
/*
allocation.setRegister(new VariableRef("i#1"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("i#2"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("$1"), new RegisterAllocation.RegisterAByte());
allocation.setRegister(new VariableRef("$3"), new RegisterAllocation.RegisterALUByte());
allocation.setRegister(new VariableRef("$4"), new RegisterAllocation.RegisterAByte());
*/
// Registers for postinc.kc
/*
allocation.setRegister(new VariableRef("c#0"), RegisterAllocation.getRegisterA());
allocation.setRegister(new VariableRef("c#1"), RegisterAllocation.getRegisterA());
allocation.setRegister(new VariableRef("c#2"), RegisterAllocation.getRegisterA());
allocation.setRegister(new VariableRef("b#0"), new RegisterAllocation.RegisterZpByte(102));
allocation.setRegister(new VariableRef("b#1"), new RegisterAllocation.RegisterZpByte(102));
allocation.setRegister(new VariableRef("b#2"), new RegisterAllocation.RegisterZpByte(102));
allocation.setRegister(new VariableRef("$1"), new RegisterAllocation.RegisterZpByte(101));
allocation.setRegister(new VariableRef("a#0"), new RegisterAllocation.RegisterZpByte(103));
allocation.setRegister(new VariableRef("a#1"), new RegisterAllocation.RegisterZpByte(103));
allocation.setRegister(new VariableRef("a#2"), new RegisterAllocation.RegisterZpByte(103));
allocation.setRegister(new VariableRef("$0"), RegisterAllocation.getRegisterA());
allocation.setRegister(new VariableRef("i#0"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("i#1"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("i#2"), RegisterAllocation.getRegisterX());
*/
// Optimal Registers for flipper-rex2.kc
/*
allocation.setRegister(new VariableRef("plot::i#0"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("plot::i#1"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("plot::i#2"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("plot::i#3"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("plot::i#4"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("plot::x#0"), RegisterAllocation.getRegisterY());
allocation.setRegister(new VariableRef("plot::x#1"), RegisterAllocation.getRegisterY());
allocation.setRegister(new VariableRef("plot::x#2"), RegisterAllocation.getRegisterY());
allocation.setRegister(new VariableRef("plot::y#0"), new RegisterAllocation.RegisterZpByte(100));
allocation.setRegister(new VariableRef("plot::y#1"), new RegisterAllocation.RegisterZpByte(100));
allocation.setRegister(new VariableRef("plot::y#2"), new RegisterAllocation.RegisterZpByte(100));
allocation.setRegister(new VariableRef("plot::y#3"), new RegisterAllocation.RegisterZpByte(100));
allocation.setRegister(new VariableRef("plot::y#4"), new RegisterAllocation.RegisterZpByte(100));
allocation.setRegister(new VariableRef("plot::line#0"), new RegisterAllocation.RegisterZpPointerByte(101));
allocation.setRegister(new VariableRef("plot::line#1"), new RegisterAllocation.RegisterZpPointerByte(101));
allocation.setRegister(new VariableRef("plot::line#2"), new RegisterAllocation.RegisterZpPointerByte(101));
allocation.setRegister(new VariableRef("plot::line#3"), new RegisterAllocation.RegisterZpPointerByte(101));
allocation.setRegister(new VariableRef("plot::line#4"), new RegisterAllocation.RegisterZpPointerByte(101));
allocation.setRegister(new VariableRef("plot::$3"), RegisterAllocation.getRegisterA());
allocation.setRegister(new VariableRef("prepare::i#0"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("prepare::i#1"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("prepare::i#2"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("flip::srcIdx#0"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("flip::srcIdx#0"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("flip::srcIdx#1"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("flip::srcIdx#2"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("flip::srcIdx#3"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("flip::srcIdx#4"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("flip::dstIdx#0"), RegisterAllocation.getRegisterY());
allocation.setRegister(new VariableRef("flip::dstIdx#1"), RegisterAllocation.getRegisterY());
allocation.setRegister(new VariableRef("flip::dstIdx#2"), RegisterAllocation.getRegisterY());
allocation.setRegister(new VariableRef("flip::dstIdx#3"), RegisterAllocation.getRegisterY());
allocation.setRegister(new VariableRef("flip::dstIdx#4"), RegisterAllocation.getRegisterY());
allocation.setRegister(new VariableRef("flip::dstIdx#5"), RegisterAllocation.getRegisterY());
allocation.setRegister(new VariableRef("flip::c#0"), new RegisterAllocation.RegisterZpByte(103));
allocation.setRegister(new VariableRef("flip::c#1"), new RegisterAllocation.RegisterZpByte(103));
allocation.setRegister(new VariableRef("flip::c#2"), new RegisterAllocation.RegisterZpByte(103));
allocation.setRegister(new VariableRef("flip::r#0"), new RegisterAllocation.RegisterZpByte(104));
allocation.setRegister(new VariableRef("flip::r#1"), new RegisterAllocation.RegisterZpByte(104));
allocation.setRegister(new VariableRef("flip::r#2"), new RegisterAllocation.RegisterZpByte(104));
allocation.setRegister(new VariableRef("flip::r#3"), new RegisterAllocation.RegisterZpByte(104));
allocation.setRegister(new VariableRef("flip::r#4"), new RegisterAllocation.RegisterZpByte(104));
allocation.setRegister(new VariableRef("flip::i#0"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("flip::i#1"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("flip::i#2"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("flip::$0"), RegisterAllocation.getRegisterA());
allocation.setRegister(new VariableRef("flip::$8"), RegisterAllocation.getRegisterA());
allocation.setRegister(new VariableRef("flip::$4"), RegisterAllocation.getRegisterA());
allocation.setRegister(new VariableRef("main::$1"), RegisterAllocation.getRegisterA());
allocation.setRegister(new VariableRef("main::$3"), RegisterAllocation.getRegisterA());
allocation.setRegister(new VariableRef("main::c#0"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("main::c#1"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("main::c#2"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("main::c#3"), RegisterAllocation.getRegisterX());
allocation.setRegister(new VariableRef("main::c#4"), RegisterAllocation.getRegisterX());
*/
}
int currentZp = 2;
private void performAllocation(Scope scope, RegisterAllocation allocation) {
for (Symbol symbol : scope.getAllSymbols()) {
if (symbol instanceof Scope) {
performAllocation((Scope) symbol, allocation);
} else if (symbol instanceof VariableIntermediate || symbol instanceof VariableVersion) {
Variable var = (Variable) symbol;
if (symbol.getType().equals(SymbolTypeBasic.BYTE)) {
allocation.setRegister(var.getRef(), new RegisterAllocation.RegisterZpByte(currentZp++));
} else if (symbol.getType().equals(SymbolTypeBasic.WORD)) {
allocation.setRegister(var.getRef(), new RegisterAllocation.RegisterZpWord(currentZp));
currentZp = currentZp + 2;
} else if (symbol.getType().equals(SymbolTypeBasic.BOOLEAN)) {
allocation.setRegister(var.getRef(), new RegisterAllocation.RegisterZpBool(currentZp++));
} else if (symbol.getType().equals(SymbolTypeBasic.VOID)) {
// No need to setRegister register for VOID value
} else if (symbol.getType() instanceof SymbolTypePointer) {
allocation.setRegister(var.getRef(), new RegisterAllocation.RegisterZpPointerByte(currentZp));
currentZp = currentZp + 2;
} else {
throw new RuntimeException("Unhandled variable type " + symbol);
}
}
}
}
}

View File

@ -29,14 +29,14 @@ public class Pass4RegistersFinalize extends Pass2Base {
private void reallocateZp(LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet) {
for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
RegisterAllocation.Register register = equivalenceClass.getRegister();
if(register.isZp()) {
String before = register.toString();
if(register==null || register.isZp()) {
String before = register==null?null:register.toString();
VariableRef variable = equivalenceClass.getVariables().get(0);
Variable symbol = getProgram().getScope().getVariable(variable);
register = allocateNewRegisterZp(symbol.getType());
equivalenceClass.setRegister(register);
if(!before.equals(register.toString())) {
getLog().append("Re-allocated ZP register from " + before + " to " + register.toString());
if(before==null || !before.equals(register.toString())) {
getLog().append("Allocated " + (before==null?"":("(was "+before+") ")) + equivalenceClass.toString());
}
}
}

View File

@ -25,14 +25,6 @@ public class Pass4ZeroPageAllocation extends Pass2Base {
getLog().append(liveRangeEquivalenceClass.toString());
}
// Coalesce over copy assignments
//EquivalenceClassCopyCoalescer equivalenceClassCopyCoalescer = new EquivalenceClassCopyCoalescer(liveRangeEquivalenceClassSet);
//equivalenceClassCopyCoalescer.visitGraph(getGraph());
//getLog().append("Copy Coalesced equivalence classes");
//for (LiveRangeEquivalenceClass liveRangeEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
// getLog().append(liveRangeEquivalenceClass.toString());
//}
// Add all other variables one by one to an available equivalence class - or create a new one
EquivalenceClassAdder equivalenceClassAdder = new EquivalenceClassAdder(liveRangeEquivalenceClassSet);
equivalenceClassAdder.visitGraph(getGraph());
@ -42,14 +34,13 @@ public class Pass4ZeroPageAllocation extends Pass2Base {
}
// Allocate zeropage registers to equivalence classes
RegisterAllocation allocation = new RegisterAllocation();
for (LiveRangeEquivalenceClass liveRangeEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
List<VariableRef> variables = liveRangeEquivalenceClass.getVariables();
Variable firstVar = getProgram().getScope().getVariable(variables.get(0));
RegisterAllocation.Register zpRegister = allocateNewRegisterZp(firstVar.getType());
liveRangeEquivalenceClass.setRegister(zpRegister);
getLog().append("Allocated " + zpRegister + " to " + liveRangeEquivalenceClass);
}
// for (LiveRangeEquivalenceClass liveRangeEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
// List<VariableRef> variables = liveRangeEquivalenceClass.getVariables();
// Variable firstVar = getProgram().getScope().getVariable(variables.get(0));
// RegisterAllocation.Register zpRegister = allocateNewRegisterZp(firstVar.getType());
// liveRangeEquivalenceClass.setRegister(zpRegister);
// getLog().append("Allocated " + zpRegister + " to " + liveRangeEquivalenceClass);
// }
getProgram().setLiveRangeEquivalenceClassSet(liveRangeEquivalenceClassSet);
}
@ -69,8 +60,6 @@ public class Pass4ZeroPageAllocation extends Pass2Base {
if (assignment.getlValue() instanceof VariableRef) {
VariableRef lValVar = (VariableRef) assignment.getlValue();
List<VariableRef> preferences = new ArrayList<>();
//addPreference(preferences, assignment.getrValue1());
//addPreference(preferences, assignment.getrValue2());
addToEquivalenceClassSet(lValVar, preferences);
}
return null;
@ -106,48 +95,6 @@ public class Pass4ZeroPageAllocation extends Pass2Base {
}
}
private void addPreference(List<VariableRef> preferences, RValue rValue) {
if (rValue instanceof VariableRef) {
preferences.add((VariableRef) rValue);
}
}
}
/**
* Coalesce equivalence classes when they do not overlap based on all copy assignments to variables.
*/
private class EquivalenceClassCopyCoalescer extends ControlFlowGraphBaseVisitor<Void> {
private LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet;
EquivalenceClassCopyCoalescer(LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet) {
this.liveRangeEquivalenceClassSet = liveRangeEquivalenceClassSet;
}
@Override
public Void visitAssignment(StatementAssignment assignment) {
if (assignment.getlValue() instanceof VariableRef) {
LiveRangeEquivalenceClass lValEquivalenceClass =
liveRangeEquivalenceClassSet.getEquivalenceClass((VariableRef) assignment.getlValue());
if (lValEquivalenceClass != null && assignment.getOperator() == null && assignment.getrValue1() == null && assignment.getrValue2() instanceof VariableRef) {
// Found copy assignment to a variable in an equivalence class - attempt to coalesce
VariableRef assignVar = (VariableRef) assignment.getrValue2();
LiveRangeEquivalenceClass assignVarEquivalenceClass = liveRangeEquivalenceClassSet.getOrCreateEquivalenceClass(assignVar);
if (lValEquivalenceClass.equals(assignVarEquivalenceClass)) {
getLog().append("Coalesced (already) " + assignment + " in " + lValEquivalenceClass);
} else if (!lValEquivalenceClass.getLiveRange().overlaps(assignVarEquivalenceClass.getLiveRange())) {
lValEquivalenceClass.addAll(assignVarEquivalenceClass);
liveRangeEquivalenceClassSet.remove(assignVarEquivalenceClass);
getLog().append("Coalesced " + assignment + " into " + lValEquivalenceClass);
} else {
getLog().append("Not coalescing " + assignment);
}
}
}
return null;
}
}
/**

View File

@ -24,6 +24,10 @@ public class TestCompilationOutput extends TestCase {
helper = new ReferenceHelper("dk/camelot64/kickc/test/ref/");
}
public void testInMemArray() throws IOException, URISyntaxException {
compileAndCompare("inmemarray");
}
public void testVoronoi() throws IOException, URISyntaxException {
compileAndCompare("voronoi");
}

View File

@ -0,0 +1,15 @@
byte* SCREEN = $0400;
byte[] TXT = { 3, 1, 13, 5, 12, 15, 20, 32};
main();
void main() {
byte j = 0;
for(byte i : 0..100) {
SCREEN[i] = TXT[j];
if(++j==8) {
j = 0;
}
}
}

View File

@ -391,6 +391,83 @@ CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
to:@2
@end: scope:[] from @2
INITIAL SSA SYMBOL TABLE
(byte~) $0
(byte~) $1
(boolean~) $10
(byte~) $11
(byte*~) $12
(byte~) $13
(byte~) $14
(boolean~) $15
(byte~) $2
(byte~) $3
(byte*~) $4
(byte*~) $5
(byte~) $6
(byte*~) $7
(byte~) $8
(boolean~) $9
(label) @1
(label) @2
(label) @3
(label) @begin
(label) @end
(byte[1000]) SCREEN
(byte[1000]) SCREEN#0
(byte) STAR
(byte) STAR#0
(byte) STAR#1
(byte) STAR#2
(byte) STAR#3
(byte*) cursor
(byte*) cursor#0
(byte*) cursor#1
(byte*) cursor#2
(byte*) cursor#3
(byte*) cursor#4
(byte*) cursor#5
(byte) e
(byte) e#0
(byte) e#1
(byte) e#2
(byte) e#3
(byte) e#4
(byte) e#5
(byte) x
(byte) x#0
(byte) x#1
(byte) x#2
(byte) x#3
(byte) x#4
(byte) x0
(byte) x0#0
(byte) x1
(byte) x1#0
(byte) x1#1
(byte) x1#2
(byte) x1#3
(byte) xd
(byte) xd#0
(byte) xd#1
(byte) xd#2
(byte) xd#3
(byte) y
(byte) y#0
(byte) y#1
(byte) y#2
(byte) y#3
(byte) y#4
(byte) y0
(byte) y0#0
(byte) y1
(byte) y1#0
(byte) yd
(byte) yd#0
(byte) yd#1
(byte) yd#2
(byte) yd#3
Constant (byte) STAR#0 (byte) 81
Constant (byte[1000]) SCREEN#0 (word) 1024
Constant (byte) x0#0 (byte) 0
@ -948,6 +1025,38 @@ Multiple usages for variable. Not optimizing sub-constant (byte) y#2
Multiple usages for variable. Not optimizing sub-constant (byte*) cursor#1
Multiple usages for variable. Not optimizing sub-constant (byte) y#2
Multiple usages for variable. Not optimizing sub-constant (byte*) cursor#1
FINAL SYMBOL TABLE
(label) @1
(label) @2
(label) @3
(label) @begin
(label) @end
(byte[1000]) SCREEN
(byte) STAR
(byte*) cursor
(byte*) cursor#1
(byte*) cursor#2
(byte*) cursor#3
(byte*) cursor#5
(byte) e
(byte) e#1
(byte) e#2
(byte) e#3
(byte) e#5
(byte) x
(byte) x#1
(byte) x#2
(byte) x0
(byte) x1
(byte) xd
(byte) y
(byte) y#1
(byte) y#2
(byte) y#4
(byte) y0
(byte) y1
(byte) yd
Block Sequence Planned @begin @1 @3 @2 @end
Added new block during phi lifting @5(between @2 and @1)
Added new block during phi lifting @6(between @1 and @2)
@ -1146,10 +1255,10 @@ Complete equivalence classes
[ x#2 x#1 ]
[ e#3 e#5 e#1 e#2 ]
[ y#2 y#4 y#1 ]
Allocated zp ptr byte:2 to zp ptr byte:2 [ cursor#3 cursor#5 cursor#1 cursor#2 ]
Allocated zp byte:4 to zp byte:4 [ x#2 x#1 ]
Allocated zp byte:5 to zp byte:5 [ e#3 e#5 e#1 e#2 ]
Allocated zp byte:6 to zp byte:6 [ y#2 y#4 y#1 ]
Allocated zp ptr byte:2 [ cursor#3 cursor#5 cursor#1 cursor#2 ]
Allocated zp byte:4 [ x#2 x#1 ]
Allocated zp byte:5 [ e#3 e#5 e#1 e#2 ]
Allocated zp byte:6 [ y#2 y#4 y#1 ]
INITIAL ASM
//SEG0 @begin
bbegin:
@ -1263,7 +1372,7 @@ REGISTER UPLIFT SCOPES
Uplift Scope [] 55: zp byte:5 [ e#3 e#5 e#1 e#2 ] 46.75: zp ptr byte:2 [ cursor#3 cursor#5 cursor#1 cursor#2 ] 29.33: zp byte:6 [ y#2 y#4 y#1 ] 14.67: zp byte:4 [ x#2 x#1 ]
Uplifting [] best 1210 combination reg byte x [ e#3 e#5 e#1 e#2 ] zp ptr byte:2 [ cursor#3 cursor#5 cursor#1 cursor#2 ] zp byte:6 [ y#2 y#4 y#1 ] zp byte:4 [ x#2 x#1 ]
Re-allocated ZP register from zp byte:6 to zp byte:5
Allocated (was zp byte:6) zp byte:5 [ y#2 y#4 y#1 ]
Removing instruction jmp b1
Removing instruction jmp b3
Removing instruction jmp b2

View File

@ -197,6 +197,28 @@ main::@return: scope:[main] from main::@1
to:@return
@end: scope:[] from @2
INITIAL SSA SYMBOL TABLE
(label) @2
(label) @begin
(label) @end
(byte[15]) fibs
(byte[15]) fibs#0
(byte[15]) fibs#1
(byte[15]) fibs#2
(void()) main()
(byte~) main::$0
(byte~) main::$1
(byte~) main::$2
(byte~) main::$3
(byte~) main::$4
(boolean~) main::$5
(label) main::@1
(label) main::@return
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
Culled Empty Block (label) @2
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@ -428,6 +450,20 @@ main::@return: scope:[main] from main::@1
Multiple usages for variable. Not optimizing sub-constant (byte) main::i#2
Multiple usages for variable. Not optimizing sub-constant (byte) main::i#2
Multiple usages for variable. Not optimizing sub-constant (byte) main::i#2
FINAL SYMBOL TABLE
(label) @begin
(label) @end
(byte[15]) fibs
(void()) main()
(byte~) main::$1
(byte~) main::$3
(byte~) main::$4
(label) main::@1
(label) main::@return
(byte) main::i
(byte) main::i#1
(byte) main::i#2
Block Sequence Planned @begin @end main main::@1 main::@return
Added new block during phi lifting main::@3(between main::@1 and main::@1)
Block Sequence Planned @begin @end main main::@1 main::@return main::@3
@ -554,10 +590,10 @@ Complete equivalence classes
[ main::$1 ]
[ main::$3 ]
[ main::$4 ]
Allocated zp byte:2 to zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 to zp byte:3 [ main::$1 ]
Allocated zp byte:4 to zp byte:4 [ main::$3 ]
Allocated zp byte:5 to zp byte:5 [ main::$4 ]
Allocated zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 [ main::$1 ]
Allocated zp byte:4 [ main::$3 ]
Allocated zp byte:5 [ main::$4 ]
INITIAL ASM
//SEG0 @begin
bbegin:

View File

@ -1033,6 +1033,183 @@ plot::@return: scope:[plot] from plot::@3
to:@return
@end: scope:[] from @5
INITIAL SSA SYMBOL TABLE
(label) @5
(label) @begin
(label) @end
(byte*) RASTER
(byte*) RASTER#0
(byte*) RASTER#1
(byte*) RASTER#10
(byte*) RASTER#2
(byte*) RASTER#3
(byte*) RASTER#4
(byte*) RASTER#5
(byte*) RASTER#6
(byte*) RASTER#7
(byte*) RASTER#8
(byte*) RASTER#9
(byte[1000]) SCREEN
(byte[1000]) SCREEN#0
(byte[1000]) SCREEN#1
(byte[1000]) SCREEN#10
(byte[1000]) SCREEN#11
(byte[1000]) SCREEN#2
(byte[1000]) SCREEN#3
(byte[1000]) SCREEN#4
(byte[1000]) SCREEN#5
(byte[1000]) SCREEN#6
(byte[1000]) SCREEN#7
(byte[1000]) SCREEN#8
(byte[1000]) SCREEN#9
(byte[256]) buffer1
(byte[256]) buffer1#0
(byte[256]) buffer1#1
(byte[256]) buffer1#10
(byte[256]) buffer1#11
(byte[256]) buffer1#12
(byte[256]) buffer1#13
(byte[256]) buffer1#14
(byte[256]) buffer1#15
(byte[256]) buffer1#16
(byte[256]) buffer1#17
(byte[256]) buffer1#18
(byte[256]) buffer1#19
(byte[256]) buffer1#2
(byte[256]) buffer1#20
(byte[256]) buffer1#21
(byte[256]) buffer1#22
(byte[256]) buffer1#3
(byte[256]) buffer1#4
(byte[256]) buffer1#5
(byte[256]) buffer1#6
(byte[256]) buffer1#7
(byte[256]) buffer1#8
(byte[256]) buffer1#9
(byte[256]) buffer2
(byte[256]) buffer2#0
(byte[256]) buffer2#1
(byte[256]) buffer2#10
(byte[256]) buffer2#11
(byte[256]) buffer2#12
(byte[256]) buffer2#13
(byte[256]) buffer2#14
(byte[256]) buffer2#15
(byte[256]) buffer2#16
(byte[256]) buffer2#2
(byte[256]) buffer2#3
(byte[256]) buffer2#4
(byte[256]) buffer2#5
(byte[256]) buffer2#6
(byte[256]) buffer2#7
(byte[256]) buffer2#8
(byte[256]) buffer2#9
(void()) flip()
(byte~) flip::$0
(byte~) flip::$1
(boolean~) flip::$2
(boolean~) flip::$3
(byte~) flip::$4
(boolean~) flip::$5
(label) flip::@1
(label) flip::@2
(label) flip::@3
(label) flip::@4
(label) flip::@5
(label) flip::@return
(byte) flip::c
(byte) flip::c#0
(byte) flip::c#1
(byte) flip::c#2
(byte) flip::dstIdx
(byte) flip::dstIdx#0
(byte) flip::dstIdx#1
(byte) flip::dstIdx#2
(byte) flip::dstIdx#3
(byte) flip::dstIdx#4
(byte) flip::dstIdx#5
(byte) flip::i
(byte) flip::i#0
(byte) flip::i#1
(byte) flip::i#2
(byte) flip::r
(byte) flip::r#0
(byte) flip::r#1
(byte) flip::r#2
(byte) flip::r#3
(byte) flip::r#4
(byte) flip::srcIdx
(byte) flip::srcIdx#0
(byte) flip::srcIdx#1
(byte) flip::srcIdx#2
(byte) flip::srcIdx#3
(byte) flip::srcIdx#4
(void()) main()
(byte~) main::$1
(boolean~) main::$2
(byte~) main::$3
(boolean~) main::$4
(boolean~) main::$5
(label) main::@1
(label) main::@10
(label) main::@11
(label) main::@2
(label) main::@3
(label) main::@4
(label) main::@6
(label) main::@7
(label) main::@9
(label) main::@return
(byte) main::c
(byte) main::c#0
(byte) main::c#1
(byte) main::c#2
(byte) main::c#3
(byte) main::c#4
(byte) main::c#5
(void()) plot()
(byte~) plot::$0
(byte*~) plot::$1
(byte*~) plot::$2
(byte~) plot::$3
(boolean~) plot::$4
(byte*~) plot::$5
(boolean~) plot::$6
(label) plot::@1
(label) plot::@2
(label) plot::@3
(label) plot::@return
(byte) plot::i
(byte) plot::i#0
(byte) plot::i#1
(byte) plot::i#2
(byte) plot::i#3
(byte) plot::i#4
(byte*) plot::line
(byte*) plot::line#0
(byte*) plot::line#1
(byte*) plot::line#2
(byte*) plot::line#3
(byte*) plot::line#4
(byte) plot::x
(byte) plot::x#0
(byte) plot::x#1
(byte) plot::x#2
(byte) plot::y
(byte) plot::y#0
(byte) plot::y#1
(byte) plot::y#2
(byte) plot::y#3
(byte) plot::y#4
(void()) prepare()
(boolean~) prepare::$0
(label) prepare::@1
(label) prepare::@return
(byte) prepare::i
(byte) prepare::i#0
(byte) prepare::i#1
(byte) prepare::i#2
Culled Empty Block (label) @5
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@ -3491,6 +3668,78 @@ Multiple usages for variable. Not optimizing sub-constant (byte) flip::srcIdx#2
Multiple usages for variable. Not optimizing sub-constant (byte) flip::i#2
Multiple usages for variable. Not optimizing sub-constant (byte) flip::i#2
Multiple usages for variable. Not optimizing sub-constant (byte) plot::i#2
FINAL SYMBOL TABLE
(label) @begin
(label) @end
(byte*) RASTER
(byte[1000]) SCREEN
(byte[256]) buffer1
(byte[256]) buffer2
(void()) flip()
(byte~) flip::$0
(byte~) flip::$4
(label) flip::@1
(label) flip::@2
(label) flip::@3
(label) flip::@4
(label) flip::@return
(byte) flip::c
(byte) flip::c#1
(byte) flip::c#2
(byte) flip::dstIdx
(byte) flip::dstIdx#1
(byte) flip::dstIdx#2
(byte) flip::dstIdx#3
(byte) flip::dstIdx#5
(byte) flip::i
(byte) flip::i#1
(byte) flip::i#2
(byte) flip::r
(byte) flip::r#1
(byte) flip::r#2
(byte) flip::srcIdx
(byte) flip::srcIdx#1
(byte) flip::srcIdx#2
(byte) flip::srcIdx#3
(void()) main()
(byte~) main::$1
(byte~) main::$3
(label) main::@10
(label) main::@11
(label) main::@3
(label) main::@4
(label) main::@6
(label) main::@7
(label) main::@return
(byte) main::c
(byte) main::c#1
(byte) main::c#2
(void()) plot()
(byte~) plot::$3
(label) plot::@1
(label) plot::@2
(label) plot::@3
(label) plot::@return
(byte) plot::i
(byte) plot::i#1
(byte) plot::i#2
(byte) plot::i#3
(byte*) plot::line
(byte*) plot::line#1
(byte*) plot::line#2
(byte) plot::x
(byte) plot::x#1
(byte) plot::x#2
(byte) plot::y
(byte) plot::y#1
(byte) plot::y#2
(void()) prepare()
(label) prepare::@1
(label) prepare::@return
(byte) prepare::i
(byte) prepare::i#1
(byte) prepare::i#2
Block Sequence Planned @begin @end main main::@3 main::@4 main::@6 main::@7 main::@10 main::@11 main::@return plot plot::@1 plot::@2 plot::@3 plot::@return flip flip::@1 flip::@2 flip::@4 flip::@3 flip::@return prepare prepare::@1 prepare::@return
Added new block during phi lifting main::@12(between main::@6 and main::@3)
Added new block during phi lifting plot::@5(between plot::@3 and plot::@1)
@ -4091,22 +4340,22 @@ Complete equivalence classes
[ plot::$3 ]
[ flip::$0 ]
[ flip::$4 ]
Allocated zp byte:2 to zp byte:2 [ main::c#2 main::c#1 ]
Allocated zp ptr byte:3 to zp ptr byte:3 [ plot::line#2 plot::line#1 ]
Allocated zp byte:5 to zp byte:5 [ plot::y#2 plot::y#1 ]
Allocated zp byte:6 to zp byte:6 [ plot::i#2 plot::i#3 plot::i#1 ]
Allocated zp byte:7 to zp byte:7 [ plot::x#2 plot::x#1 ]
Allocated zp byte:8 to zp byte:8 [ flip::r#2 flip::r#1 ]
Allocated zp byte:9 to zp byte:9 [ flip::srcIdx#2 flip::srcIdx#3 flip::srcIdx#1 ]
Allocated zp byte:10 to zp byte:10 [ flip::dstIdx#3 flip::dstIdx#5 flip::dstIdx#2 flip::dstIdx#1 ]
Allocated zp byte:11 to zp byte:11 [ flip::c#2 flip::c#1 ]
Allocated zp byte:12 to zp byte:12 [ flip::i#2 flip::i#1 ]
Allocated zp byte:13 to zp byte:13 [ prepare::i#2 prepare::i#1 ]
Allocated zp byte:14 to zp byte:14 [ main::$1 ]
Allocated zp byte:15 to zp byte:15 [ main::$3 ]
Allocated zp byte:16 to zp byte:16 [ plot::$3 ]
Allocated zp byte:17 to zp byte:17 [ flip::$0 ]
Allocated zp byte:18 to zp byte:18 [ flip::$4 ]
Allocated zp byte:2 [ main::c#2 main::c#1 ]
Allocated zp ptr byte:3 [ plot::line#2 plot::line#1 ]
Allocated zp byte:5 [ plot::y#2 plot::y#1 ]
Allocated zp byte:6 [ plot::i#2 plot::i#3 plot::i#1 ]
Allocated zp byte:7 [ plot::x#2 plot::x#1 ]
Allocated zp byte:8 [ flip::r#2 flip::r#1 ]
Allocated zp byte:9 [ flip::srcIdx#2 flip::srcIdx#3 flip::srcIdx#1 ]
Allocated zp byte:10 [ flip::dstIdx#3 flip::dstIdx#5 flip::dstIdx#2 flip::dstIdx#1 ]
Allocated zp byte:11 [ flip::c#2 flip::c#1 ]
Allocated zp byte:12 [ flip::i#2 flip::i#1 ]
Allocated zp byte:13 [ prepare::i#2 prepare::i#1 ]
Allocated zp byte:14 [ main::$1 ]
Allocated zp byte:15 [ main::$3 ]
Allocated zp byte:16 [ plot::$3 ]
Allocated zp byte:17 [ flip::$0 ]
Allocated zp byte:18 [ flip::$4 ]
INITIAL ASM
//SEG0 @begin
bbegin:
@ -4431,9 +4680,9 @@ Uplifting [main] best 125624 combination reg byte a [ main::$1 ] reg byte a [ ma
Uplifting [prepare] best 125524 combination reg byte x [ prepare::i#2 prepare::i#1 ]
Uplifting [] best 125524 combination
Coalescing zero page register [ zp byte:5 [ plot::y#2 plot::y#1 ] ] with [ zp byte:8 [ flip::r#2 flip::r#1 ] ]
Re-allocated ZP register from zp ptr byte:3 to zp ptr byte:2
Re-allocated ZP register from zp byte:5 to zp byte:4
Re-allocated ZP register from zp byte:11 to zp byte:5
Allocated (was zp ptr byte:3) zp ptr byte:2 [ plot::line#2 plot::line#1 ]
Allocated (was zp byte:5) zp byte:4 [ plot::y#2 plot::y#1 flip::r#2 flip::r#1 ]
Allocated (was zp byte:11) zp byte:5 [ flip::c#2 flip::c#1 ]
Removing instruction jmp bend
Removing instruction jmp b3
Removing instruction jmp b4

View File

@ -162,6 +162,25 @@ main::@return: scope:[main] from main::@1
to:@end
@end: scope:[] from @2
INITIAL SSA SYMBOL TABLE
(label) @1
(label) @2
(label) @begin
(label) @end
(byte*) SCREEN
(byte*) SCREEN#0
(byte*) SCREEN#1
(byte*) SCREEN#2
(byte*) SCREEN#3
(void()) main()
(boolean~) main::$0
(label) main::@1
(label) main::@return
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
Culled Empty Block (label) @2
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@ -330,6 +349,18 @@ main::@return: scope:[main] from main::@1
Multiple usages for variable. Not optimizing sub-constant (byte) main::i#2
Multiple usages for variable. Not optimizing sub-constant (byte) main::i#2
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(byte*) SCREEN
(void()) main()
(label) main::@1
(label) main::@return
(byte) main::i
(byte) main::i#1
(byte) main::i#2
Block Sequence Planned @begin @1 @end main main::@1 main::@return
Added new block during phi lifting main::@3(between main::@1 and main::@1)
Block Sequence Planned @begin @1 @end main main::@1 main::@return main::@3
@ -437,7 +468,7 @@ Initial phi equivalence classes
[ main::i#2 main::i#1 ]
Complete equivalence classes
[ main::i#2 main::i#1 ]
Allocated zp byte:2 to zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:2 [ main::i#2 main::i#1 ]
INITIAL ASM
//SEG0 @begin
bbegin:

View File

@ -241,6 +241,39 @@ main::@return: scope:[main] from main::@2
to:@end
@end: scope:[] from @2
INITIAL SSA SYMBOL TABLE
(label) @1
(label) @2
(label) @begin
(label) @end
(byte*) SCREEN1
(byte*) SCREEN1#0
(byte*) SCREEN1#1
(byte*) SCREEN1#2
(byte*) SCREEN1#3
(byte*) SCREEN2
(byte*) SCREEN2#0
(byte*) SCREEN2#1
(byte*) SCREEN2#2
(byte*) SCREEN2#3
(byte*) SCREEN2#4
(byte*) SCREEN2#5
(void()) main()
(boolean~) main::$0
(boolean~) main::$1
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::j
(byte) main::j#0
(byte) main::j#1
(byte) main::j#2
Culled Empty Block (label) @2
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@ -557,6 +590,23 @@ main::@return: scope:[main] from main::@2
Multiple usages for variable. Not optimizing sub-constant (byte) main::i#2
Multiple usages for variable. Not optimizing sub-constant (byte) main::j#2
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(byte*) SCREEN1
(byte*) SCREEN2
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@return
(byte) main::i
(byte) main::i#1
(byte) main::i#2
(byte) main::j
(byte) main::j#1
(byte) main::j#2
Block Sequence Planned @begin @1 @end main main::@1 main::@2 main::@return
Added new block during phi lifting main::@5(between main::@1 and main::@1)
Added new block during phi lifting main::@6(between main::@2 and main::@2)
@ -703,8 +753,8 @@ Initial phi equivalence classes
Complete equivalence classes
[ main::i#2 main::i#1 ]
[ main::j#2 main::j#1 ]
Allocated zp byte:2 to zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 to zp byte:3 [ main::j#2 main::j#1 ]
Allocated zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 [ main::j#2 main::j#1 ]
INITIAL ASM
//SEG0 @begin
bbegin:

View File

@ -203,6 +203,31 @@ main::@return: scope:[main] from main::@2
to:@return
@end: scope:[] from @2
INITIAL SSA SYMBOL TABLE
(label) @2
(label) @begin
(label) @end
(byte*) SCREEN
(byte*) SCREEN#0
(byte*) SCREEN#1
(byte*) SCREEN#2
(byte*) SCREEN#3
(byte*) SCREEN#4
(void()) main()
(boolean~) main::$0
(boolean~) main::$1
(boolean~) main::$2
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::i#3
(byte) main::i#4
Culled Empty Block (label) @2
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@ -441,6 +466,19 @@ main::@return: scope:[main] from main::@2
to:@return
@end: scope:[] from @begin
FINAL SYMBOL TABLE
(label) @begin
(label) @end
(byte*) SCREEN
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
(byte) main::i
(byte) main::i#1
(byte) main::i#2
Block Sequence Planned @begin @end main main::@1 main::@3 main::@2 main::@return
Added new block during phi lifting main::@5(between main::@2 and main::@1)
Block Sequence Planned @begin @end main main::@1 main::@3 main::@2 main::@return main::@5
@ -558,7 +596,7 @@ Initial phi equivalence classes
[ main::i#2 main::i#1 ]
Complete equivalence classes
[ main::i#2 main::i#1 ]
Allocated zp byte:2 to zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:2 [ main::i#2 main::i#1 ]
INITIAL ASM
//SEG0 @begin
bbegin:

View File

@ -156,6 +156,29 @@ CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
to:@2
@end: scope:[] from @2
INITIAL SSA SYMBOL TABLE
(boolean~) $0
(boolean~) $1
(byte~) $2
(boolean~) $3
(label) @1
(label) @2
(label) @3
(label) @begin
(label) @end
(byte) i
(byte) i#0
(byte) i#1
(byte) i#2
(byte) i#3
(byte) i#4
(byte) s
(byte) s#0
(byte) s#1
(byte) s#2
(byte) s#3
(byte) s#4
Constant (byte) i#0 (byte) 10
Constant (byte) s#0 (byte) 0
Succesful SSA optimization Pass2ConstantPropagation
@ -278,6 +301,20 @@ CONTROL FLOW GRAPH
to:@2
@end: scope:[] from @2
FINAL SYMBOL TABLE
(label) @1
(label) @2
(label) @3
(label) @begin
(label) @end
(byte) i
(byte) i#1
(byte) i#2
(byte) s
(byte) s#1
(byte) s#2
(byte) s#4
Block Sequence Planned @begin @1 @3 @2 @end
Added new block during phi lifting @5(between @2 and @1)
Added new block during phi lifting @6(between @1 and @2)
@ -403,8 +440,8 @@ Initial phi equivalence classes
Complete equivalence classes
[ i#2 i#1 ]
[ s#2 s#4 s#1 ]
Allocated zp byte:2 to zp byte:2 [ i#2 i#1 ]
Allocated zp byte:3 to zp byte:3 [ s#2 s#4 s#1 ]
Allocated zp byte:2 [ i#2 i#1 ]
Allocated zp byte:3 [ s#2 s#4 s#1 ]
INITIAL ASM
//SEG0 @begin
bbegin:

View File

@ -258,6 +258,36 @@ nest::@return: scope:[nest] from nest::@1
to:@return
@end: scope:[] from @3
INITIAL SSA SYMBOL TABLE
(label) @3
(label) @begin
(label) @end
(byte*) SCREEN
(byte*) SCREEN#0
(byte*) SCREEN#1
(byte*) SCREEN#2
(byte*) SCREEN#3
(byte*) SCREEN#4
(byte*) SCREEN#5
(void()) main()
(boolean~) main::$1
(label) main::@1
(label) main::@3
(label) main::@return
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::i#3
(void()) nest()
(boolean~) nest::$0
(label) nest::@1
(label) nest::@return
(byte) nest::j
(byte) nest::j#0
(byte) nest::j#1
(byte) nest::j#2
Culled Empty Block (label) @3
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@ -554,6 +584,24 @@ nest::@return: scope:[nest] from nest::@1
to:@return
@end: scope:[] from @begin
FINAL SYMBOL TABLE
(label) @begin
(label) @end
(byte*) SCREEN
(void()) main()
(label) main::@1
(label) main::@3
(label) main::@return
(byte) main::i
(byte) main::i#1
(byte) main::i#2
(void()) nest()
(label) nest::@1
(label) nest::@return
(byte) nest::j
(byte) nest::j#1
(byte) nest::j#2
Block Sequence Planned @begin @end main main::@1 main::@3 main::@return nest nest::@1 nest::@return
Added new block during phi lifting main::@4(between main::@3 and main::@1)
Added new block during phi lifting nest::@3(between nest::@1 and nest::@1)
@ -733,8 +781,8 @@ Initial phi equivalence classes
Complete equivalence classes
[ main::i#2 main::i#1 ]
[ nest::j#2 nest::j#1 ]
Allocated zp byte:2 to zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 to zp byte:3 [ nest::j#2 nest::j#1 ]
Allocated zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 [ nest::j#2 nest::j#1 ]
INITIAL ASM
//SEG0 @begin
bbegin:

View File

@ -559,6 +559,84 @@ nest2::@return: scope:[nest2] from nest2::@3
to:@return
@end: scope:[] from @4
INITIAL SSA SYMBOL TABLE
(label) @4
(label) @begin
(label) @end
(byte*) SCREEN
(byte*) SCREEN#0
(byte*) SCREEN#1
(byte*) SCREEN#10
(byte*) SCREEN#11
(byte*) SCREEN#12
(byte*) SCREEN#13
(byte*) SCREEN#14
(byte*) SCREEN#2
(byte*) SCREEN#3
(byte*) SCREEN#4
(byte*) SCREEN#5
(byte*) SCREEN#6
(byte*) SCREEN#7
(byte*) SCREEN#8
(byte*) SCREEN#9
(void()) main()
(boolean~) main::$1
(boolean~) main::$2
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@5
(label) main::@return
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::i#3
(byte) main::i#4
(byte) main::i#5
(byte) main::j
(byte) main::j#0
(byte) main::j#1
(byte) main::j#2
(byte) main::j#3
(void()) nest1()
(boolean~) nest1::$1
(boolean~) nest1::$2
(label) nest1::@1
(label) nest1::@2
(label) nest1::@3
(label) nest1::@5
(label) nest1::@return
(byte) nest1::i
(byte) nest1::i#0
(byte) nest1::i#1
(byte) nest1::i#2
(byte) nest1::i#3
(byte) nest1::i#4
(byte) nest1::i#5
(byte) nest1::j
(byte) nest1::j#0
(byte) nest1::j#1
(byte) nest1::j#2
(byte) nest1::j#3
(void()) nest2()
(boolean~) nest2::$0
(boolean~) nest2::$1
(label) nest2::@1
(label) nest2::@2
(label) nest2::@3
(label) nest2::@return
(byte) nest2::i
(byte) nest2::i#0
(byte) nest2::i#1
(byte) nest2::i#2
(byte) nest2::i#3
(byte) nest2::i#4
(byte) nest2::j
(byte) nest2::j#0
(byte) nest2::j#1
(byte) nest2::j#2
Culled Empty Block (label) @4
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@ -1446,6 +1524,46 @@ nest2::@return: scope:[nest2] from nest2::@3
to:@return
@end: scope:[] from @begin
FINAL SYMBOL TABLE
(label) @begin
(label) @end
(byte*) SCREEN
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@5
(label) main::@return
(byte) main::i
(byte) main::i#1
(byte) main::i#2
(byte) main::j
(byte) main::j#1
(byte) main::j#2
(void()) nest1()
(label) nest1::@1
(label) nest1::@2
(label) nest1::@3
(label) nest1::@5
(label) nest1::@return
(byte) nest1::i
(byte) nest1::i#1
(byte) nest1::i#2
(byte) nest1::j
(byte) nest1::j#1
(byte) nest1::j#2
(void()) nest2()
(label) nest2::@1
(label) nest2::@2
(label) nest2::@3
(label) nest2::@return
(byte) nest2::i
(byte) nest2::i#1
(byte) nest2::i#2
(byte) nest2::j
(byte) nest2::j#1
(byte) nest2::j#2
Block Sequence Planned @begin @end main main::@1 main::@2 main::@5 main::@3 main::@return nest1 nest1::@1 nest1::@2 nest1::@5 nest1::@3 nest1::@return nest2 nest2::@1 nest2::@2 nest2::@3 nest2::@return
Added new block during phi lifting main::@6(between main::@3 and main::@1)
Added new block during phi lifting main::@7(between main::@5 and main::@2)
@ -1922,12 +2040,12 @@ Complete equivalence classes
[ nest1::j#2 nest1::j#1 ]
[ nest2::i#2 nest2::i#1 ]
[ nest2::j#2 nest2::j#1 ]
Allocated zp byte:2 to zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 to zp byte:3 [ main::j#2 main::j#1 ]
Allocated zp byte:4 to zp byte:4 [ nest1::i#2 nest1::i#1 ]
Allocated zp byte:5 to zp byte:5 [ nest1::j#2 nest1::j#1 ]
Allocated zp byte:6 to zp byte:6 [ nest2::i#2 nest2::i#1 ]
Allocated zp byte:7 to zp byte:7 [ nest2::j#2 nest2::j#1 ]
Allocated zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 [ main::j#2 main::j#1 ]
Allocated zp byte:4 [ nest1::i#2 nest1::i#1 ]
Allocated zp byte:5 [ nest1::j#2 nest1::j#1 ]
Allocated zp byte:6 [ nest2::i#2 nest2::i#1 ]
Allocated zp byte:7 [ nest2::j#2 nest2::j#1 ]
INITIAL ASM
//SEG0 @begin
bbegin:

View File

@ -248,6 +248,35 @@ main::@return: scope:[main] from main::@1
to:@return
@end: scope:[] from @2
INITIAL SSA SYMBOL TABLE
(label) @2
(label) @begin
(label) @end
(void()) main()
(boolean~) main::$0
(boolean~) main::$1
(boolean~) main::$2
(label) main::@1
(label) main::@2
(label) main::@4
(label) main::@8
(label) main::@return
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::i#3
(byte) main::i#4
(byte) main::i#5
(byte) main::s
(byte) main::s#0
(byte) main::s#1
(byte) main::s#2
(byte) main::s#3
(byte) main::s#4
(byte) main::s#5
(byte) main::s#6
Culled Empty Block (label) @2
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@ -421,6 +450,23 @@ main::@return: scope:[main] from main::@1
to:@return
@end: scope:[] from @begin
FINAL SYMBOL TABLE
(label) @begin
(label) @end
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@4
(label) main::@8
(label) main::@return
(byte) main::i
(byte) main::i#1
(byte) main::i#2
(byte) main::s
(byte) main::s#1
(byte) main::s#2
(byte) main::s#3
Block Sequence Planned @begin @end main main::@1 main::@return main::@2 main::@8 main::@4
Block Sequence Planned @begin @end main main::@1 main::@return main::@2 main::@8 main::@4
CONTROL FLOW GRAPH - PHI LIFTED
@ -568,8 +614,8 @@ Initial phi equivalence classes
Complete equivalence classes
[ main::i#2 main::i#1 ]
[ main::s#3 main::s#1 main::s#2 ]
Allocated zp byte:2 to zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 to zp byte:3 [ main::s#3 main::s#1 main::s#2 ]
Allocated zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 [ main::s#3 main::s#1 main::s#2 ]
INITIAL ASM
//SEG0 @begin
bbegin:

View File

@ -116,6 +116,22 @@ CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
to:@end
@end: scope:[] from @1
INITIAL SSA SYMBOL TABLE
(byte~) $0
(byte~) $1
(byte~) $2
(boolean~) $3
(label) @1
(label) @begin
(label) @end
(byte) i
(byte) i#0
(byte) i#1
(byte) i#2
(byte[16]) p
(byte[16]) p#0
(byte[16]) p#1
Constant (byte[16]) p#0 (word) 4352
Constant (byte) i#0 (byte) 5
Succesful SSA optimization Pass2ConstantPropagation
@ -223,6 +239,16 @@ Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
FINAL SYMBOL TABLE
(byte~) $1
(label) @1
(label) @begin
(label) @end
(byte) i
(byte) i#1
(byte) i#2
(byte[16]) p
Block Sequence Planned @begin @1 @end
Added new block during phi lifting @3(between @1 and @1)
Block Sequence Planned @begin @1 @end @3
@ -306,8 +332,8 @@ Added variable $1 to zero page equivalence class [ $1 ]
Complete equivalence classes
[ i#2 i#1 ]
[ $1 ]
Allocated zp byte:2 to zp byte:2 [ i#2 i#1 ]
Allocated zp byte:3 to zp byte:3 [ $1 ]
Allocated zp byte:2 [ i#2 i#1 ]
Allocated zp byte:3 [ $1 ]
INITIAL ASM
//SEG0 @begin
bbegin:

View File

@ -312,6 +312,63 @@ inccnt::@return: scope:[inccnt] from inccnt
to:@return
@end: scope:[] from @3
INITIAL SSA SYMBOL TABLE
(label) @3
(label) @begin
(label) @end
(byte[256]) SCREEN
(byte[256]) SCREEN#0
(byte[256]) SCREEN#1
(byte[256]) SCREEN#2
(byte[256]) SCREEN#3
(byte) cnt
(byte) cnt#0
(byte) cnt#1
(byte) cnt#10
(byte) cnt#11
(byte) cnt#12
(byte) cnt#13
(byte) cnt#14
(byte) cnt#2
(byte) cnt#3
(byte) cnt#4
(byte) cnt#5
(byte) cnt#6
(byte) cnt#7
(byte) cnt#8
(byte) cnt#9
(byte) cnt2
(byte) cnt2#0
(byte) cnt2#1
(byte) cnt2#10
(byte) cnt2#11
(byte) cnt2#12
(byte) cnt2#13
(byte) cnt2#2
(byte) cnt2#3
(byte) cnt2#4
(byte) cnt2#5
(byte) cnt2#6
(byte) cnt2#7
(byte) cnt2#8
(byte) cnt2#9
(byte()) inccnt()
(label) inccnt::@return
(byte) inccnt::return
(byte) inccnt::return#0
(byte) inccnt::return#1
(byte) inccnt::return#2
(byte) inccnt::return#3
(byte) inccnt::return#4
(byte) inccnt::return#5
(byte) inccnt::return#6
(void()) main()
(byte~) main::$0
(byte~) main::$1
(label) main::@1
(label) main::@2
(label) main::@return
Constant (byte) cnt#0 (byte) 0
Constant (byte) cnt2#0 (byte) 0
Constant (byte[256]) SCREEN#0 (word) 1024
@ -539,6 +596,28 @@ Not aliassing across scopes: inccnt::return#0 cnt#1
Not aliassing across scopes: main::$0 inccnt::return#0
Not aliassing across scopes: main::$1 inccnt::return#0
Not aliassing across scopes: inccnt::return#0 cnt#1
FINAL SYMBOL TABLE
(label) @begin
(label) @end
(byte[256]) SCREEN
(byte) cnt
(byte) cnt#1
(byte) cnt#12
(byte) cnt#3
(byte) cnt2
(byte) cnt2#1
(byte) cnt2#11
(byte()) inccnt()
(label) inccnt::@return
(byte) inccnt::return
(byte) inccnt::return#0
(void()) main()
(byte~) main::$0
(byte~) main::$1
(label) main::@1
(label) main::@2
(label) main::@return
Block Sequence Planned @begin @end main main::@1 main::@2 main::@return inccnt inccnt::@return
Block Sequence Planned @begin @end main main::@1 main::@2 main::@return inccnt inccnt::@return
CONTROL FLOW GRAPH - PHI LIFTED
@ -711,12 +790,12 @@ Complete equivalence classes
[ main::$1 ]
[ cnt#1 ]
[ inccnt::return#0 ]
Allocated zp byte:2 to zp byte:2 [ cnt#12 cnt#3 ]
Allocated zp byte:3 to zp byte:3 [ cnt2#11 cnt2#1 ]
Allocated zp byte:4 to zp byte:4 [ main::$0 ]
Allocated zp byte:5 to zp byte:5 [ main::$1 ]
Allocated zp byte:6 to zp byte:6 [ cnt#1 ]
Allocated zp byte:7 to zp byte:7 [ inccnt::return#0 ]
Allocated zp byte:2 [ cnt#12 cnt#3 ]
Allocated zp byte:3 [ cnt2#11 cnt2#1 ]
Allocated zp byte:4 [ main::$0 ]
Allocated zp byte:5 [ main::$1 ]
Allocated zp byte:6 [ cnt#1 ]
Allocated zp byte:7 [ inccnt::return#0 ]
INITIAL ASM
//SEG0 @begin
bbegin:

View File

@ -241,6 +241,39 @@ inccnt::@return: scope:[inccnt] from inccnt
to:@return
@end: scope:[] from @3
INITIAL SSA SYMBOL TABLE
(label) @3
(label) @begin
(label) @end
(byte[256]) SCREEN
(byte[256]) SCREEN#0
(byte[256]) SCREEN#1
(byte[256]) SCREEN#2
(byte[256]) SCREEN#3
(byte) cnt
(byte) cnt#0
(byte) cnt#1
(byte) cnt#10
(byte) cnt#11
(byte) cnt#12
(byte) cnt#13
(byte) cnt#14
(byte) cnt#15
(byte) cnt#2
(byte) cnt#3
(byte) cnt#4
(byte) cnt#5
(byte) cnt#6
(byte) cnt#7
(byte) cnt#8
(byte) cnt#9
(void()) inccnt()
(label) inccnt::@return
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@return
Constant (byte) cnt#0 (byte) 0
Constant (byte[256]) SCREEN#0 (word) 1024
Succesful SSA optimization Pass2ConstantPropagation
@ -418,6 +451,22 @@ inccnt::@return: scope:[inccnt] from inccnt
to:@return
@end: scope:[] from @begin
FINAL SYMBOL TABLE
(label) @begin
(label) @end
(byte[256]) SCREEN
(byte) cnt
(byte) cnt#1
(byte) cnt#10
(byte) cnt#13
(byte) cnt#3
(void()) inccnt()
(label) inccnt::@return
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@return
Block Sequence Planned @begin @end main main::@1 main::@2 main::@return inccnt inccnt::@return
Block Sequence Planned @begin @end main main::@1 main::@2 main::@return inccnt inccnt::@return
CONTROL FLOW GRAPH - PHI LIFTED
@ -554,9 +603,9 @@ Complete equivalence classes
[ cnt#13 cnt#3 ]
[ cnt#1 ]
[ cnt#10 ]
Allocated zp byte:2 to zp byte:2 [ cnt#13 cnt#3 ]
Allocated zp byte:3 to zp byte:3 [ cnt#1 ]
Allocated zp byte:4 to zp byte:4 [ cnt#10 ]
Allocated zp byte:2 [ cnt#13 cnt#3 ]
Allocated zp byte:3 [ cnt#1 ]
Allocated zp byte:4 [ cnt#10 ]
INITIAL ASM
//SEG0 @begin
bbegin:

View File

@ -773,6 +773,89 @@ rvaluevar::@return: scope:[rvaluevar] from rvaluevar::@1
to:@return
@end: scope:[] from @6
INITIAL SSA SYMBOL TABLE
(label) @6
(label) @begin
(label) @end
(void()) lvalue()
(boolean~) lvalue::$0
(label) lvalue::@1
(label) lvalue::@2
(label) lvalue::@return
(byte[1024]) lvalue::SCREEN
(byte[1024]) lvalue::SCREEN#0
(byte[1024]) lvalue::SCREEN#1
(byte[1024]) lvalue::SCREEN#2
(byte) lvalue::i
(byte) lvalue::i#0
(byte) lvalue::i#1
(byte) lvalue::i#2
(byte) lvalue::i#3
(void()) lvaluevar()
(boolean~) lvaluevar::$0
(label) lvaluevar::@1
(label) lvaluevar::@2
(label) lvaluevar::@return
(byte) lvaluevar::b
(byte) lvaluevar::b#0
(byte) lvaluevar::b#1
(byte) lvaluevar::b#2
(byte) lvaluevar::i
(byte) lvaluevar::i#0
(byte) lvaluevar::i#1
(byte) lvaluevar::i#2
(byte) lvaluevar::i#3
(byte*) lvaluevar::screen
(byte*) lvaluevar::screen#0
(byte*) lvaluevar::screen#1
(byte*) lvaluevar::screen#2
(byte*) lvaluevar::screen#3
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@4
(label) main::@return
(void()) rvalue()
(byte~) rvalue::$0
(byte~) rvalue::$1
(boolean~) rvalue::$2
(byte~) rvalue::$3
(label) rvalue::@1
(label) rvalue::@2
(label) rvalue::@return
(byte[1024]) rvalue::SCREEN
(byte[1024]) rvalue::SCREEN#0
(byte[1024]) rvalue::SCREEN#1
(byte[1024]) rvalue::SCREEN#2
(byte) rvalue::b
(byte) rvalue::b#0
(byte) rvalue::b#1
(byte) rvalue::b#2
(byte) rvalue::i
(byte) rvalue::i#0
(byte) rvalue::i#1
(byte) rvalue::i#2
(byte) rvalue::i#3
(void()) rvaluevar()
(boolean~) rvaluevar::$0
(byte~) rvaluevar::$1
(label) rvaluevar::@1
(label) rvaluevar::@2
(label) rvaluevar::@return
(byte) rvaluevar::b
(byte) rvaluevar::b#0
(byte) rvaluevar::i
(byte) rvaluevar::i#0
(byte) rvaluevar::i#1
(byte) rvaluevar::i#2
(byte) rvaluevar::i#3
(byte*) rvaluevar::screen
(byte*) rvaluevar::screen#0
(byte*) rvaluevar::screen#1
(byte*) rvaluevar::screen#2
(byte*) rvaluevar::screen#3
Culled Empty Block (label) @6
Culled Empty Block (label) main::@4
Succesful SSA optimization Pass2CullEmptyBlocks
@ -1471,6 +1554,58 @@ rvaluevar::@return: scope:[rvaluevar] from rvaluevar::@1
Multiple usages for variable. Not optimizing sub-constant (byte) rvalue::i#2
Multiple usages for variable. Not optimizing sub-constant (byte) rvalue::i#2
FINAL SYMBOL TABLE
(label) @begin
(label) @end
(void()) lvalue()
(label) lvalue::@1
(label) lvalue::@2
(label) lvalue::@return
(byte[1024]) lvalue::SCREEN
(byte) lvalue::i
(byte) lvalue::i#1
(byte) lvalue::i#2
(void()) lvaluevar()
(label) lvaluevar::@1
(label) lvaluevar::@2
(label) lvaluevar::@return
(byte) lvaluevar::b
(byte) lvaluevar::i
(byte) lvaluevar::i#1
(byte) lvaluevar::i#2
(byte*) lvaluevar::screen
(byte*) lvaluevar::screen#1
(byte*) lvaluevar::screen#2
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
(void()) rvalue()
(label) rvalue::@1
(label) rvalue::@2
(label) rvalue::@return
(byte[1024]) rvalue::SCREEN
(byte) rvalue::b
(byte) rvalue::b#0
(byte) rvalue::b#1
(byte) rvalue::b#2
(byte) rvalue::i
(byte) rvalue::i#1
(byte) rvalue::i#2
(void()) rvaluevar()
(label) rvaluevar::@1
(label) rvaluevar::@2
(label) rvaluevar::@return
(byte) rvaluevar::b
(byte) rvaluevar::b#0
(byte) rvaluevar::i
(byte) rvaluevar::i#1
(byte) rvaluevar::i#2
(byte*) rvaluevar::screen
(byte*) rvaluevar::screen#1
(byte*) rvaluevar::screen#2
Block Sequence Planned @begin @end main main::@1 main::@2 main::@3 main::@return lvaluevar lvaluevar::@1 lvaluevar::@return lvaluevar::@2 rvaluevar rvaluevar::@1 rvaluevar::@return rvaluevar::@2 rvalue rvalue::@1 rvalue::@return rvalue::@2 lvalue lvalue::@1 lvalue::@return lvalue::@2
Block Sequence Planned @begin @end main main::@1 main::@2 main::@3 main::@return lvaluevar lvaluevar::@1 lvaluevar::@return lvaluevar::@2 rvaluevar rvaluevar::@1 rvaluevar::@return rvaluevar::@2 rvalue rvalue::@1 rvalue::@return rvalue::@2 lvalue lvalue::@1 lvalue::@return lvalue::@2
CONTROL FLOW GRAPH - PHI LIFTED
@ -1867,16 +2002,16 @@ Complete equivalence classes
[ rvalue::b#0 ]
[ rvalue::b#1 ]
[ rvalue::b#2 ]
Allocated zp byte:2 to zp byte:2 [ lvaluevar::i#2 lvaluevar::i#1 ]
Allocated zp ptr byte:3 to zp ptr byte:3 [ lvaluevar::screen#2 lvaluevar::screen#1 ]
Allocated zp byte:5 to zp byte:5 [ rvaluevar::i#2 rvaluevar::i#1 ]
Allocated zp ptr byte:6 to zp ptr byte:6 [ rvaluevar::screen#2 rvaluevar::screen#1 ]
Allocated zp byte:8 to zp byte:8 [ rvalue::i#2 rvalue::i#1 ]
Allocated zp byte:9 to zp byte:9 [ lvalue::i#2 lvalue::i#1 ]
Allocated zp byte:10 to zp byte:10 [ rvaluevar::b#0 ]
Allocated zp byte:11 to zp byte:11 [ rvalue::b#0 ]
Allocated zp byte:12 to zp byte:12 [ rvalue::b#1 ]
Allocated zp byte:13 to zp byte:13 [ rvalue::b#2 ]
Allocated zp byte:2 [ lvaluevar::i#2 lvaluevar::i#1 ]
Allocated zp ptr byte:3 [ lvaluevar::screen#2 lvaluevar::screen#1 ]
Allocated zp byte:5 [ rvaluevar::i#2 rvaluevar::i#1 ]
Allocated zp ptr byte:6 [ rvaluevar::screen#2 rvaluevar::screen#1 ]
Allocated zp byte:8 [ rvalue::i#2 rvalue::i#1 ]
Allocated zp byte:9 [ lvalue::i#2 lvalue::i#1 ]
Allocated zp byte:10 [ rvaluevar::b#0 ]
Allocated zp byte:11 [ rvalue::b#0 ]
Allocated zp byte:12 [ rvalue::b#1 ]
Allocated zp byte:13 [ rvalue::b#2 ]
INITIAL ASM
//SEG0 @begin
bbegin:
@ -2115,7 +2250,7 @@ Uplifting [lvalue] best 1575 combination reg byte x [ lvalue::i#2 lvalue::i#1 ]
Uplifting [main] best 1575 combination
Uplifting [] best 1575 combination
Coalescing zero page register [ zp ptr byte:3 [ lvaluevar::screen#2 lvaluevar::screen#1 ] ] with [ zp ptr byte:6 [ rvaluevar::screen#2 rvaluevar::screen#1 ] ]
Re-allocated ZP register from zp ptr byte:3 to zp ptr byte:2
Allocated (was zp ptr byte:3) zp ptr byte:2 [ lvaluevar::screen#2 lvaluevar::screen#1 rvaluevar::screen#2 rvaluevar::screen#1 ]
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp b2

View File

@ -193,6 +193,28 @@ main::@return: scope:[main] from main::@1
to:@return
@end: scope:[] from @2
INITIAL SSA SYMBOL TABLE
(label) @2
(label) @begin
(label) @end
(void()) main()
(boolean~) main::$0
(byte~) main::$1
(label) main::@1
(label) main::@2
(label) main::@return
(byte[1024]) main::SCREEN
(byte[1024]) main::SCREEN#0
(byte[1024]) main::SCREEN#1
(byte[1024]) main::SCREEN#2
(byte) main::b
(byte) main::b#0
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::i#3
Culled Empty Block (label) @2
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@ -341,6 +363,20 @@ main::@return: scope:[main] from main::@1
Multiple usages for variable. Not optimizing sub-constant (byte) main::i#2
Multiple usages for variable. Not optimizing sub-constant (byte) main::i#2
FINAL SYMBOL TABLE
(label) @begin
(label) @end
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@return
(byte[1024]) main::SCREEN
(byte) main::b
(byte) main::b#0
(byte) main::i
(byte) main::i#1
(byte) main::i#2
Block Sequence Planned @begin @end main main::@1 main::@return main::@2
Block Sequence Planned @begin @end main main::@1 main::@return main::@2
CONTROL FLOW GRAPH - PHI LIFTED
@ -448,8 +484,8 @@ Added variable main::b#0 to zero page equivalence class [ main::b#0 ]
Complete equivalence classes
[ main::i#2 main::i#1 ]
[ main::b#0 ]
Allocated zp byte:2 to zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 to zp byte:3 [ main::b#0 ]
Allocated zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 [ main::b#0 ]
INITIAL ASM
//SEG0 @begin
bbegin:

View File

@ -228,6 +228,52 @@ sum::@return: scope:[sum] from sum
to:@return
@end: scope:[] from @4
INITIAL SSA SYMBOL TABLE
(byte~) $0
(byte~) $1
(byte~) $2
(byte~) $3
(byte~) $4
(label) @2
(label) @3
(label) @4
(label) @begin
(label) @end
(byte) s1
(byte) s1#0
(byte) s1#1
(byte) s1#2
(byte) s2
(byte) s2#0
(byte) s2#1
(byte) s3
(byte) s3#0
(byte) s4
(byte) s4#0
(byte()) sum((byte) sum::a , (byte) sum::b)
(byte~) sum::$0
(label) sum::@return
(byte) sum::a
(byte) sum::a#0
(byte) sum::a#1
(byte) sum::a#2
(byte) sum::a#3
(byte) sum::b
(byte) sum::b#0
(byte) sum::b#1
(byte) sum::b#2
(byte) sum::b#3
(byte) sum::return
(byte) sum::return#0
(byte) sum::return#1
(byte) sum::return#2
(byte) sum::return#3
(byte) sum::return#4
(byte) sum::return#5
(byte) sum::return#6
(byte) sum::return#7
(byte) sum::return#8
Constant (byte) sum::a#0 (byte) 1
Constant (byte) sum::b#0 (byte) 2
Constant (byte) sum::a#1 (byte) 3
@ -317,6 +363,30 @@ sum::@return: scope:[sum] from sum
Not aliassing across scopes: s1#0 sum::return#0
Not aliassing across scopes: s2#0 sum::return#0
Not aliassing across scopes: s3#0 sum::return#0
FINAL SYMBOL TABLE
(byte~) $3
(label) @2
(label) @3
(label) @4
(label) @begin
(label) @end
(byte) s1
(byte) s1#0
(byte) s2
(byte) s2#0
(byte) s3
(byte) s3#0
(byte) s4
(byte) s4#0
(byte()) sum((byte) sum::a , (byte) sum::b)
(label) sum::@return
(byte) sum::a
(byte) sum::a#3
(byte) sum::b
(byte) sum::b#3
(byte) sum::return
(byte) sum::return#0
Block Sequence Planned @begin @2 @3 @4 @end sum sum::@return
Block Sequence Planned @begin @2 @3 @4 @end sum sum::@return
CONTROL FLOW GRAPH - PHI LIFTED
@ -488,14 +558,14 @@ Complete equivalence classes
[ $3 ]
[ s4#0 ]
[ sum::return#0 ]
Allocated zp byte:2 to zp byte:2 [ sum::a#3 ]
Allocated zp byte:3 to zp byte:3 [ sum::b#3 ]
Allocated zp byte:4 to zp byte:4 [ s1#0 ]
Allocated zp byte:5 to zp byte:5 [ s2#0 ]
Allocated zp byte:6 to zp byte:6 [ s3#0 ]
Allocated zp byte:7 to zp byte:7 [ $3 ]
Allocated zp byte:8 to zp byte:8 [ s4#0 ]
Allocated zp byte:9 to zp byte:9 [ sum::return#0 ]
Allocated zp byte:2 [ sum::a#3 ]
Allocated zp byte:3 [ sum::b#3 ]
Allocated zp byte:4 [ s1#0 ]
Allocated zp byte:5 [ s2#0 ]
Allocated zp byte:6 [ s3#0 ]
Allocated zp byte:7 [ $3 ]
Allocated zp byte:8 [ s4#0 ]
Allocated zp byte:9 [ sum::return#0 ]
INITIAL ASM
//SEG0 @begin
bbegin:
@ -590,8 +660,8 @@ Uplift Scope [sum] 2: zp byte:2 [ sum::a#3 ] 2: zp byte:3 [ sum::b#3 ] 1.6: zp b
Uplifting [] best 107 combination reg byte a [ s4#0 ] reg byte a [ $3 ] zp byte:6 [ s3#0 ] reg byte x [ s2#0 ] zp byte:4 [ s1#0 ]
Uplifting [sum] best 79 combination reg byte y [ sum::a#3 ] reg byte a [ sum::b#3 ] reg byte a [ sum::return#0 ]
Re-allocated ZP register from zp byte:4 to zp byte:2
Re-allocated ZP register from zp byte:6 to zp byte:3
Allocated (was zp byte:4) zp byte:2 [ s1#0 ]
Allocated (was zp byte:6) zp byte:3 [ s3#0 ]
Removing instruction jmp b2
Removing instruction jmp b3
Removing instruction jmp b4

View File

@ -98,6 +98,16 @@ main::@return: scope:[main] from main
to:@return
@end: scope:[] from @2
INITIAL SSA SYMBOL TABLE
(label) @2
(label) @begin
(label) @end
(byte*) SCREEN
(byte*) SCREEN#0
(byte*) SCREEN#1
(void()) main()
(label) main::@return
Culled Empty Block (label) @2
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@ -143,6 +153,13 @@ main::@return: scope:[main] from main
to:@return
@end: scope:[] from @begin
FINAL SYMBOL TABLE
(label) @begin
(label) @end
(byte*) SCREEN
(void()) main()
(label) main::@return
Block Sequence Planned @begin @end main main::@return
Block Sequence Planned @begin @end main main::@return
CONTROL FLOW GRAPH - PHI LIFTED

View File

@ -123,7 +123,7 @@ render: {
inc $5
lda $5
cmp #$28
bcc b2
bne b2
lda $3
clc
adc #$28
@ -134,7 +134,7 @@ render: {
inc $2
lda $2
cmp #$19
bcc b1
bne b1
rts
}
findcol: {

View File

@ -114,12 +114,12 @@ render::@5: scope:[render] from render::@2
[56] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 ]
[57] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 ]
[58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 render::colline#2 ]
[59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 ]
[59] if((byte) render::x#1!=(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 ]
to:render::@3
render::@3: scope:[render] from render::@5
[60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 ]
[61] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 ]
[62] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 ]
[62] if((byte) render::y#1!=(byte) 25) goto render::@1 [ render::y#1 render::colline#1 ]
to:render::@return
render::@return: scope:[render] from render::@3
[63] return [ ]

File diff suppressed because it is too large Load Diff

View File

@ -63,30 +63,26 @@ void addpoint(byte x, byte y, byte c) {
}
void initscreen() {
byte* screen = SCREEN;
do {
for( byte* screen = SCREEN; screen<SCREEN+$03e8; ++screen) {
*screen = FILL;
} while(++screen<SCREEN+$03e8)
}
}
void render() {
byte* colline = COLORS;
byte y=0;
do {
byte x=0;
do {
for( byte y : 0.. 24) {
for( byte x : 0..39) {
byte col = findcol(x, y);
colline[x] = col;
} while(++x < 40)
}
colline = colline+40;
} while(++y < 25)
}
}
byte findcol(byte x, byte y) {
byte mindiff = 255;
byte mincol = 0;
byte i=0;
do {
for( byte i=0; i<numpoints; ++i) {
byte xp = XPOS[i];
byte yp = YPOS[i];
if(x==xp) {
@ -109,7 +105,7 @@ byte findcol(byte x, byte y) {
mindiff=diff;
mincol = COLS[i];
}
} while(++i<numpoints)
}
return mincol;
}