1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-08 14:37:40 +00:00

Fixed constant addition elimination. Moved ASM generation for a single statement to separate function - preparing for clobber analysis of register allocation. Added fibmem test. Tested ALU.

This commit is contained in:
jespergravgaard 2017-07-29 21:04:28 +02:00
parent 7f20f2a6ba
commit e34e01544b
20 changed files with 1241 additions and 216 deletions

View File

@ -144,9 +144,15 @@ public class Compiler {
log.append("\nVARIABLE REGISTER WEIGHTS");
log.append(program.getScope().getSymbolTableContents(Variable.class));
//new Pass3RegisterUplifting(program, log).uplift();
//log.append("REGISTER UPLIFTING");
//log.append(program.getScope().getSymbolTableContents(Variable.class));
new Pass3ZeroPageCoalesce(program, log).allocate();
new Pass3RegistersFinalize(program, log).allocate();
//new Pass4RegisterAllocationTrivial(program).allocate();
}

View File

@ -61,7 +61,9 @@ public class AsmFragment {
private String assignmentWithAluSignature(StatementAssignment assignment, StatementAssignment assignmentAlu) {
RValue assignmentRValue2 = assignment.getrValue2();
RegisterAllocation.Register rVal2Register = symbols.getRegister((Variable) assignmentRValue2);
Variable assignmentVar = symbols.getVariable((VariableRef) assignmentRValue2);
RegisterAllocation.Register rVal2Register = symbols.getRegister(assignmentVar);
if(!rVal2Register.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) {
throw new RuntimeException("Error! ALU register only allowed as rValue2. "+assignment);
}

View File

@ -0,0 +1,3 @@
ldy {zpby1}
lda {cowo1},y
sta {zpby1}

View File

@ -72,10 +72,7 @@ public class ControlFlowGraph {
* @param variable The variable to find the assignment for
* @return The assignment. null if the variable is not assigned. The variable is assigned by a Phi-statement instead.
*/
public StatementAssignment getAssignment(Variable variable) {
if(variable instanceof VariableUnversioned) {
throw new RuntimeException("Error attempting to get assignment of unversioned variable, which is not guaranteed to be unique "+variable);
}
public StatementAssignment getAssignment(VariableRef variable) {
for (ControlFlowBlock block : getAllBlocks()) {
for (Statement statement : block.getStatements()) {
if(statement instanceof StatementAssignment) {

View File

@ -151,12 +151,17 @@ public abstract class Scope implements Symbol {
}
@JsonIgnore
public Collection<Variable> getAllVariables() {
public Collection<Variable> getAllVariables(boolean includeSubScopes) {
Collection<Variable> vars = new ArrayList<>();
for (Symbol symbol : symbols.values()) {
if (symbol instanceof Variable) {
vars.add((Variable) symbol);
}
if(includeSubScopes && symbol instanceof Scope) {
Scope subScope = (Scope) symbol;
vars.addAll(subScope.getAllVariables(true));
}
}
return vars;
}

View File

@ -149,7 +149,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
return null;
}
Variable var = getSymbols().getVariable(variable);
StatementAssignment assignment = getGraph().getAssignment(var);
StatementAssignment assignment = getGraph().getAssignment(variable);
if (assignment != null && assignment.getOperator() != null && "+".equals(assignment.getOperator().getOperator())) {
if (assignment.getrValue1() instanceof ConstantInteger) {
ConstantInteger constant = (ConstantInteger) assignment.getrValue1();

View File

@ -0,0 +1,55 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.icl.*;
import java.util.Collection;
/*** Uplift one variable into the A register - and check if the program still works */
public class Pass3RegisterUplifting {
private Program program;
private CompileLog log;
public Pass3RegisterUplifting(Program program, CompileLog log) {
this.program = program;
this.log = log;
}
public Program getProgram() {
return program;
}
public CompileLog getLog() {
return log;
}
/** Uplift one variable */
public void uplift() {
VariableRegisterWeights variableRegisterWeights = program.getScope().getVariableRegisterWeights();
double maxWeight = 0.0;
Variable maxVar = null;
Collection<Variable> allVars = program.getScope().getAllVariables(true);
for (Variable variable : allVars) {
Double w = variableRegisterWeights.getWeight(variable.getRef());
if(w!=null && w>maxWeight) {
maxWeight = w;
maxVar = variable;
}
}
// Found max variable!
log.append("Attempting uplift of variable "+maxVar);
}
}

View File

@ -25,7 +25,7 @@ public class Pass4CodeGeneration {
// Generate entry points (if needed)
genBlockEntryPoints(asm, block);
// Generate label
asm.addLabel(block.getLabel().getFullName().replace('@', 'B').replace(':','_'));
asm.addLabel(block.getLabel().getFullName().replace('@', 'B').replace(':', '_'));
// Generate statements
genStatements(asm, block);
// Generate exit
@ -34,7 +34,7 @@ public class Pass4CodeGeneration {
if (defaultSuccessor.hasPhiBlock()) {
genBlockPhiTransition(asm, block, defaultSuccessor);
}
asm.addInstruction("JMP", AsmAddressingMode.ABS, defaultSuccessor.getLabel().getFullName().replace('@', 'B').replace(':','_'));
asm.addInstruction("JMP", AsmAddressingMode.ABS, defaultSuccessor.getLabel().getFullName().replace('@', 'B').replace(':', '_'));
}
}
return asm;
@ -42,60 +42,107 @@ public class Pass4CodeGeneration {
private void genStatements(AsmProgram asm, ControlFlowBlock block) {
Iterator<Statement> statementsIt = block.getStatements().iterator();
AsmCodegenAluState aluState = new AsmCodegenAluState();
while (statementsIt.hasNext()) {
Statement statement = statementsIt.next();
if (!(statement instanceof StatementPhiBlock)) {
if (statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;
LValue lValue = assignment.getlValue();
boolean isAlu = false;
if (lValue instanceof VariableRef) {
VariableRef lValueRef = (VariableRef) lValue;
Variable lValueVar = symbols.getVariable(lValueRef);
RegisterAllocation.Register lValRegister = symbols.getRegister(lValueVar);
if (lValRegister.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) {
asm.addComment(statement + " // ALU");
StatementAssignment assignmentAlu = assignment;
statement = statementsIt.next();
if (!(statement instanceof StatementAssignment)) {
throw new RuntimeException("Error! ALU statement must be followed immediately by assignment using the ALU. " + statement);
}
assignment = (StatementAssignment) statement;
AsmFragment asmFragment = new AsmFragment(assignment, assignmentAlu, symbols);
asm.addComment(statement.toString(symbols) + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
isAlu = true;
}
generateStatementAsm(asm, block, statement, aluState);
}
}
/**
* Generate ASM code for a single statement
*
* @param asm The ASM program to generate into
* @param block The block containing the statement
* @param statementsIt The iterator giving access to the next statement
* @param statement The statement to generate ASM code for
*/
public void generateStatementAsm(AsmProgram asm, ControlFlowBlock block, Statement statement, AsmCodegenAluState asmCodeAsmCodegenAluState) {
// IF the previous statement was added to the ALU register - generate the composite ASM fragment
if (asmCodeAsmCodegenAluState.hasAluAssignment()) {
StatementAssignment assignmentAlu = asmCodeAsmCodegenAluState.getAluAssignment();
if (!(statement instanceof StatementAssignment)) {
throw new RuntimeException("Error! ALU statement must be followed immediately by assignment using the ALU. " + statement);
}
StatementAssignment assignment = (StatementAssignment) statement;
AsmFragment asmFragment = new AsmFragment(assignment, assignmentAlu, symbols);
asm.addComment(statement.toString(symbols) + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
asmCodeAsmCodegenAluState.clear();
return;
}
if (!(statement instanceof StatementPhiBlock)) {
if (statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;
LValue lValue = assignment.getlValue();
boolean isAlu = false;
if (lValue instanceof VariableRef) {
VariableRef lValueRef = (VariableRef) lValue;
Variable lValueVar = symbols.getVariable(lValueRef);
RegisterAllocation.Register lValRegister = symbols.getRegister(lValueVar);
if (lValRegister.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) {
asm.addComment(statement + " // ALU");
StatementAssignment assignmentAlu = assignment;
asmCodeAsmCodegenAluState.setAluAssignment(assignmentAlu);
isAlu = true;
}
if (!isAlu) {
if(assignment.getOperator()==null && assignment.getrValue1()==null && isRegisterCopy(lValue, assignment.getrValue2())) {
asm.addComment(lValue.toString(symbols) + " = " + assignment.getrValue2().toString(symbols) + " // register copy "+getRegister(lValue));
} else {
AsmFragment asmFragment = new AsmFragment(assignment, symbols);
asm.addComment(statement.toString(symbols) + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
}
}
} else if (statement instanceof StatementConditionalJump) {
AsmFragment asmFragment = new AsmFragment((StatementConditionalJump) statement, block, symbols, graph);
asm.addComment(statement.toString(symbols) + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
} else if (statement instanceof StatementCall) {
StatementCall call = (StatementCall) statement;
ControlFlowBlock callSuccessor = graph.getCallSuccessor(block);
if (callSuccessor != null && callSuccessor.hasPhiBlock()) {
genBlockPhiTransition(asm, block, callSuccessor);
}
asm.addInstruction("jsr", AsmAddressingMode.ABS, call.getProcedure().getFullName());
} else if (statement instanceof StatementReturn) {
asm.addInstruction("rts", AsmAddressingMode.NON, null);
} else {
throw new RuntimeException("Statement not supported " + statement);
}
if (!isAlu) {
if (assignment.getOperator() == null && assignment.getrValue1() == null && isRegisterCopy(lValue, assignment.getrValue2())) {
asm.addComment(lValue.toString(symbols) + " = " + assignment.getrValue2().toString(symbols) + " // register copy " + getRegister(lValue));
} else {
AsmFragment asmFragment = new AsmFragment(assignment, symbols);
asm.addComment(statement.toString(symbols) + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
}
}
} else if (statement instanceof StatementConditionalJump) {
AsmFragment asmFragment = new AsmFragment((StatementConditionalJump) statement, block, symbols, graph);
asm.addComment(statement.toString(symbols) + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
} else if (statement instanceof StatementCall) {
StatementCall call = (StatementCall) statement;
ControlFlowBlock callSuccessor = graph.getCallSuccessor(block);
if (callSuccessor != null && callSuccessor.hasPhiBlock()) {
genBlockPhiTransition(asm, block, callSuccessor);
}
asm.addInstruction("jsr", AsmAddressingMode.ABS, call.getProcedure().getFullName());
} else if (statement instanceof StatementReturn) {
asm.addInstruction("rts", AsmAddressingMode.NON, null);
} else {
throw new RuntimeException("Statement not supported " + statement);
}
}
}
/**
* Contains previous assignment added to the ALU register between calls to generateStatementAsm
*/
public static class AsmCodegenAluState {
private StatementAssignment aluAssignment;
public void setAluAssignment(StatementAssignment aluAssignment) {
this.aluAssignment = aluAssignment;
}
public StatementAssignment getAluAssignment() {
return aluAssignment;
}
public boolean hasAluAssignment() {
return aluAssignment != null;
}
public void clear() {
aluAssignment = null;
}
}
private void genBlockEntryPoints(AsmProgram asm, ControlFlowBlock block) {
if (block.hasPhiBlock()) {
List<ControlFlowBlock> predecessors = new ArrayList<>(graph.getPredecessors(block));
@ -108,7 +155,7 @@ public class Pass4CodeGeneration {
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(':','_'));
asm.addInstruction("JMP", AsmAddressingMode.ABS, block.getLabel().getFullName().replace('@', 'B').replace(':', '_'));
}
}
}
@ -150,7 +197,7 @@ public class Pass4CodeGeneration {
private void genAsmMove(AsmProgram asm, LValue lValue, RValue rValue) {
if (isRegisterCopy(lValue, rValue)) {
asm.addComment(lValue.toString(symbols) + " = " + rValue.toString(symbols) + " // register copy "+getRegister(lValue));
asm.addComment(lValue.toString(symbols) + " = " + rValue.toString(symbols) + " // register copy " + getRegister(lValue));
} else {
AsmFragment asmFragment = new AsmFragment(lValue, rValue, symbols);
asm.addComment(lValue.toString(symbols) + " = " + rValue.toString(symbols) + " // " + asmFragment.getSignature());

View File

@ -21,13 +21,12 @@ public class Pass4RegisterAllocationTrivial {
performAllocation(symbols, allocation);
// Register allocation for fibmem.kc
/*
allocation.allocate(new VariableRef("i#1"), RegisterAllocation.getRegisterX());
allocation.allocate(new VariableRef("i#2"), RegisterAllocation.getRegisterX());
allocation.allocate(new VariableRef("$1"), new RegisterAllocation.RegisterAByte());
allocation.allocate(new VariableRef("$3"), new RegisterAllocation.RegisterALUByte());
//allocation.allocate(new VariableRef("$4"), new RegisterAllocation.RegisterAByte());
*/
allocation.allocate(new VariableRef("$4"), new RegisterAllocation.RegisterAByte());
// Registers for postinc.kc
/*

View File

@ -62,6 +62,12 @@ public class TestCompilationOutput extends TestCase {
tester.testFile("loopnest2");
}
public void testFibMem() throws IOException, URISyntaxException {
TestCompilationOutput tester = new TestCompilationOutput();
tester.testFile("fibmem");
}
private void testFile(String fileName) throws IOException, URISyntaxException {
String inputPath = testPath + fileName + ".kc";

View File

@ -706,8 +706,79 @@ CONTROL FLOW GRAPH
to:@END
@END: from @3
Consolidated constant in assignment cursor#0
Multiple usages for variable. Not optimizing sub-constant (byte) y#2
Multiple usages for variable. Not optimizing sub-constant (byte*) cursor#1
Succesful SSA optimization Pass2ConstantAdditionElimination
CONTROL FLOW GRAPH
@BEGIN: from
(byte) e#0 ← (byte) 24 / (byte) 2
(byte~) $3 ← (byte) 0 * (byte) 40
(byte*~) $4 ← (byte~) $3
(byte*) cursor#0 ← (byte*~) $4 + (word) 1024
to:@1
@1: from @3 @BEGIN
(byte) y#2 ← phi( @3/(byte) y#4 @BEGIN/(byte) 0 )
(byte) xd#1 ← phi( @BEGIN/(byte) 39 )
(byte) yd#1 ← phi( @BEGIN/(byte) 24 )
(byte) e#3 ← phi( @3/(byte) e#5 @BEGIN/(byte) e#0 )
(byte) x#2 ← phi( @3/(byte) x#1 @BEGIN/(byte) 0 )
(byte*) cursor#3 ← phi( @3/(byte*) cursor#5 @BEGIN/(byte*) cursor#0 )
*((byte*) cursor#3) ← (byte) 81
(byte) x#1 ← (byte) x#2 + (byte) 1
(byte*) cursor#1 ← (byte*) cursor#3 + (byte) 1
(byte) e#1 ← (byte) e#3 + (byte) yd#1
if((byte) xd#1<(byte) e#1) goto @2
to:@3
@2: from @1
(byte) y#1 ← (byte) y#2 + (byte) 1
(byte*) cursor#2 ← (byte*) cursor#1 + (byte) 40
(byte) e#2 ← (byte) e#1 - (byte) xd#1
to:@3
@3: from @1 @2
(byte) y#4 ← phi( @1/(byte) y#2 @2/(byte) y#1 )
(byte) e#5 ← phi( @1/(byte) e#1 @2/(byte) e#2 )
(byte*) cursor#5 ← phi( @1/(byte*) cursor#1 @2/(byte*) cursor#2 )
(byte~) $13 ← (byte) 39 + (byte) 1
if((byte) x#1<(byte~) $13) goto @1
to:@END
@END: from @3
Alias (byte~) $3 = (byte*~) $4
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@BEGIN: from
(byte) e#0 ← (byte) 24 / (byte) 2
(byte~) $3 ← (byte) 0 * (byte) 40
(byte*) cursor#0 ← (byte~) $3 + (word) 1024
to:@1
@1: from @3 @BEGIN
(byte) y#2 ← phi( @3/(byte) y#4 @BEGIN/(byte) 0 )
(byte) xd#1 ← phi( @BEGIN/(byte) 39 )
(byte) yd#1 ← phi( @BEGIN/(byte) 24 )
(byte) e#3 ← phi( @3/(byte) e#5 @BEGIN/(byte) e#0 )
(byte) x#2 ← phi( @3/(byte) x#1 @BEGIN/(byte) 0 )
(byte*) cursor#3 ← phi( @3/(byte*) cursor#5 @BEGIN/(byte*) cursor#0 )
*((byte*) cursor#3) ← (byte) 81
(byte) x#1 ← (byte) x#2 + (byte) 1
(byte*) cursor#1 ← (byte*) cursor#3 + (byte) 1
(byte) e#1 ← (byte) e#3 + (byte) yd#1
if((byte) xd#1<(byte) e#1) goto @2
to:@3
@2: from @1
(byte) y#1 ← (byte) y#2 + (byte) 1
(byte*) cursor#2 ← (byte*) cursor#1 + (byte) 40
(byte) e#2 ← (byte) e#1 - (byte) xd#1
to:@3
@3: from @1 @2
(byte) y#4 ← phi( @1/(byte) y#2 @2/(byte) y#1 )
(byte) e#5 ← phi( @1/(byte) e#1 @2/(byte) e#2 )
(byte*) cursor#5 ← phi( @1/(byte*) cursor#1 @2/(byte*) cursor#2 )
(byte~) $13 ← (byte) 39 + (byte) 1
if((byte) x#1<(byte~) $13) goto @1
to:@END
@END: from @3
Redundant Phi (byte) yd#1 (byte) 24
Redundant Phi (byte) xd#1 (byte) 39
Succesful SSA optimization Pass2RedundantPhiElimination
@ -715,8 +786,7 @@ CONTROL FLOW GRAPH
@BEGIN: from
(byte) e#0 ← (byte) 24 / (byte) 2
(byte~) $3 ← (byte) 0 * (byte) 40
(byte*~) $4 ← (word) 1024 + (byte~) $3
(byte*) cursor#0 ← (byte*~) $4 + (byte) 0
(byte*) cursor#0 ← (byte~) $3 + (word) 1024
to:@1
@1: from @3 @BEGIN
(byte) y#2 ← phi( @3/(byte) y#4 @BEGIN/(byte) 0 )
@ -749,40 +819,7 @@ Constant (byte~) $13 (byte) 40
Succesful SSA optimization Pass2ConstantPropagation
CONTROL FLOW GRAPH
@BEGIN: from
(byte*~) $4 ← (word) 1024 + (byte) 0
(byte*) cursor#0 ← (byte*~) $4 + (byte) 0
to:@1
@1: from @3 @BEGIN
(byte) y#2 ← phi( @3/(byte) y#4 @BEGIN/(byte) 0 )
(byte) e#3 ← phi( @3/(byte) e#5 @BEGIN/(byte) 12 )
(byte) x#2 ← phi( @3/(byte) x#1 @BEGIN/(byte) 0 )
(byte*) cursor#3 ← phi( @3/(byte*) cursor#5 @BEGIN/(byte*) cursor#0 )
*((byte*) cursor#3) ← (byte) 81
(byte) x#1 ← (byte) x#2 + (byte) 1
(byte*) cursor#1 ← (byte*) cursor#3 + (byte) 1
(byte) e#1 ← (byte) e#3 + (byte) 24
if((byte) 39<(byte) e#1) goto @2
to:@3
@2: from @1
(byte) y#1 ← (byte) y#2 + (byte) 1
(byte*) cursor#2 ← (byte*) cursor#1 + (byte) 40
(byte) e#2 ← (byte) e#1 - (byte) 39
to:@3
@3: from @1 @2
(byte) y#4 ← phi( @1/(byte) y#2 @2/(byte) y#1 )
(byte) e#5 ← phi( @1/(byte) e#1 @2/(byte) e#2 )
(byte*) cursor#5 ← phi( @1/(byte*) cursor#1 @2/(byte*) cursor#2 )
if((byte) x#1<(byte) 40) goto @1
to:@END
@END: from @3
Multiple usages for variable. Not optimizing sub-constant (byte) y#2
Multiple usages for variable. Not optimizing sub-constant (byte*) cursor#1
Constant (byte*~) $4 (word) 1024
Succesful SSA optimization Pass2ConstantPropagation
CONTROL FLOW GRAPH
@BEGIN: from
(byte*) cursor#0 ← (word) 1024 + (byte) 0
(byte*) cursor#0 ← (byte) 0 + (word) 1024
to:@1
@1: from @3 @BEGIN
(byte) y#2 ← phi( @3/(byte) y#4 @BEGIN/(byte) 0 )

View File

@ -0,0 +1,28 @@
BBEGIN:
lda #0
sta 4352
lda #1
sta 4353
B1_from_BBEGIN:
lda #0
sta 2
B1_from_B1:
B1:
ldy 2
lda 4352,y
sta 3
ldy 2
lda 4353,y
sta 4
lda 3
clc
adc 4
sta 3
lda 3
ldy 2
sta 4354,y
inc 2
lda 2
cmp #15
bcc B1_from_B1
BEND:

View File

@ -0,0 +1,14 @@
@BEGIN: from
[0] *((word) 4352) ← (byte) 0 [ ]
[1] *((word) 4353) ← (byte) 1 [ ]
to:@1
@1: from @1 @BEGIN
[2] (byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 0 ) [ i#2 ]
[3] (byte~) $1 ← (word) 4352 *idx (byte) i#2 [ i#2 $1 ]
[4] (byte~) $3 ← (word) 4353 *idx (byte) i#2 [ i#2 $1 $3 ]
[5] (byte~) $4 ← (byte~) $1 + (byte~) $3 [ i#2 $4 ]
[6] *((word) 4354 + (byte) i#2) ← (byte~) $4 [ i#2 ]
[7] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ]
[8] if((byte) i#1<(byte) 15) goto @1 [ i#1 ]
to:@END
@END: from @1

View File

@ -0,0 +1,633 @@
byte[15] fibs = $1100;
fibs[0] = 0;
fibs[1] = 1;
byte i = 0;
do {
fibs[i+2] = fibs[i]+fibs[i+1];
i = i + 1;
} while(i<15)
PROGRAM
(byte[15]) fibs ← (word) 4352
*((byte[15]) fibs + (byte) 0) ← (byte) 0
*((byte[15]) fibs + (byte) 1) ← (byte) 1
(byte) i ← (byte) 0
@1:
(byte~) $0 ← (byte) i + (byte) 2
(byte~) $1 ← (byte[15]) fibs *idx (byte) i
(byte~) $2 ← (byte) i + (byte) 1
(byte~) $3 ← (byte[15]) fibs *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((byte[15]) fibs + (byte~) $0) ← (byte~) $4
(byte~) $5 ← (byte) i + (byte) 1
(byte) i ← (byte~) $5
(boolean~) $6 ← (byte) i < (byte) 15
if((boolean~) $6) goto @1
SYMBOLS
(byte~) $0
(byte~) $1
(byte~) $2
(byte~) $3
(byte~) $4
(byte~) $5
(boolean~) $6
(label) @1
(byte[15]) fibs
(byte) i
INITIAL CONTROL FLOW GRAPH
@BEGIN: from
(byte[15]) fibs ← (word) 4352
*((byte[15]) fibs + (byte) 0) ← (byte) 0
*((byte[15]) fibs + (byte) 1) ← (byte) 1
(byte) i ← (byte) 0
to:@1
@1: from @1 @BEGIN
(byte~) $0 ← (byte) i + (byte) 2
(byte~) $1 ← (byte[15]) fibs *idx (byte) i
(byte~) $2 ← (byte) i + (byte) 1
(byte~) $3 ← (byte[15]) fibs *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((byte[15]) fibs + (byte~) $0) ← (byte~) $4
(byte~) $5 ← (byte) i + (byte) 1
(byte) i ← (byte~) $5
(boolean~) $6 ← (byte) i < (byte) 15
if((boolean~) $6) goto @1
to:@2
@2: from @1
to:@END
@END: from @2
Removing empty block @2
CONTROL FLOW GRAPH
@BEGIN: from
(byte[15]) fibs ← (word) 4352
*((byte[15]) fibs + (byte) 0) ← (byte) 0
*((byte[15]) fibs + (byte) 1) ← (byte) 1
(byte) i ← (byte) 0
to:@1
@1: from @1 @BEGIN
(byte~) $0 ← (byte) i + (byte) 2
(byte~) $1 ← (byte[15]) fibs *idx (byte) i
(byte~) $2 ← (byte) i + (byte) 1
(byte~) $3 ← (byte[15]) fibs *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((byte[15]) fibs + (byte~) $0) ← (byte~) $4
(byte~) $5 ← (byte) i + (byte) 1
(byte) i ← (byte~) $5
(boolean~) $6 ← (byte) i < (byte) 15
if((boolean~) $6) goto @1
to:@END
@END: from @1
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte[15]) fibs ← (word) 4352
*((byte[15]) fibs + (byte) 0) ← (byte) 0
*((byte[15]) fibs + (byte) 1) ← (byte) 1
(byte) i ← (byte) 0
to:@1
@1: from @1 @BEGIN
(byte~) $0 ← (byte) i + (byte) 2
(byte~) $1 ← (byte[15]) fibs *idx (byte) i
(byte~) $2 ← (byte) i + (byte) 1
(byte~) $3 ← (byte[15]) fibs *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((byte[15]) fibs + (byte~) $0) ← (byte~) $4
(byte~) $5 ← (byte) i + (byte) 1
(byte) i ← (byte~) $5
(boolean~) $6 ← (byte) i < (byte) 15
if((boolean~) $6) goto @1
to:@END
@END: from @1
Completing Phi functions...
CONTROL FLOW GRAPH SSA
@BEGIN: from
(byte[15]) fibs#0 ← (word) 4352
*((byte[15]) fibs#0 + (byte) 0) ← (byte) 0
*((byte[15]) fibs#0 + (byte) 1) ← (byte) 1
(byte) i#0 ← (byte) 0
to:@1
@1: from @1 @BEGIN
(byte[15]) fibs#1 ← phi( @1/(byte[15]) fibs#1 @BEGIN/(byte[15]) fibs#0 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) i#0 )
(byte~) $0 ← (byte) i#2 + (byte) 2
(byte~) $1 ← (byte[15]) fibs#1 *idx (byte) i#2
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte~) $3 ← (byte[15]) fibs#1 *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((byte[15]) fibs#1 + (byte~) $0) ← (byte~) $4
(byte~) $5 ← (byte) i#2 + (byte) 1
(byte) i#1 ← (byte~) $5
(boolean~) $6 ← (byte) i#1 < (byte) 15
if((boolean~) $6) goto @1
to:@END
@END: from @1
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
@BEGIN: from
(byte[15]) fibs#0 ← (word) 4352
*((byte[15]) fibs#0 + (byte) 0) ← (byte) 0
*((byte[15]) fibs#0 + (byte) 1) ← (byte) 1
(byte) i#0 ← (byte) 0
to:@1
@1: from @1 @BEGIN
(byte[15]) fibs#1 ← phi( @1/(byte[15]) fibs#1 @BEGIN/(byte[15]) fibs#0 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) i#0 )
(byte~) $0 ← (byte) i#2 + (byte) 2
(byte~) $1 ← (byte[15]) fibs#1 *idx (byte) i#2
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte~) $3 ← (byte[15]) fibs#1 *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((byte[15]) fibs#1 + (byte~) $0) ← (byte~) $4
(byte~) $5 ← (byte) i#2 + (byte) 1
(byte) i#1 ← (byte~) $5
(boolean~) $6 ← (byte) i#1 < (byte) 15
if((boolean~) $6) goto @1
to:@END
@END: from @1
Constant (byte[15]) fibs#0 (word) 4352
Constant (byte) i#0 (byte) 0
Succesful SSA optimization Pass2ConstantPropagation
CONTROL FLOW GRAPH
@BEGIN: from
*((word) 4352 + (byte) 0) ← (byte) 0
*((word) 4352 + (byte) 1) ← (byte) 1
to:@1
@1: from @1 @BEGIN
(byte[15]) fibs#1 ← phi( @1/(byte[15]) fibs#1 @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 0 )
(byte~) $0 ← (byte) i#2 + (byte) 2
(byte~) $1 ← (byte[15]) fibs#1 *idx (byte) i#2
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte~) $3 ← (byte[15]) fibs#1 *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((byte[15]) fibs#1 + (byte~) $0) ← (byte~) $4
(byte~) $5 ← (byte) i#2 + (byte) 1
(byte) i#1 ← (byte~) $5
(boolean~) $6 ← (byte) i#1 < (byte) 15
if((boolean~) $6) goto @1
to:@END
@END: from @1
Consolidated assigned array index constant in assignment *(4352)
Consolidated assigned array index constant in assignment *(4353)
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
Succesful SSA optimization Pass2ConstantAdditionElimination
CONTROL FLOW GRAPH
@BEGIN: from
*((word) 4352) ← (byte) 0
*((word) 4353) ← (byte) 1
to:@1
@1: from @1 @BEGIN
(byte[15]) fibs#1 ← phi( @1/(byte[15]) fibs#1 @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 0 )
(byte~) $0 ← (byte) i#2 + (byte) 2
(byte~) $1 ← (byte[15]) fibs#1 *idx (byte) i#2
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte~) $3 ← (byte[15]) fibs#1 *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((byte[15]) fibs#1 + (byte~) $0) ← (byte~) $4
(byte~) $5 ← (byte) i#2 + (byte) 1
(byte) i#1 ← (byte~) $5
(boolean~) $6 ← (byte) i#1 < (byte) 15
if((boolean~) $6) goto @1
to:@END
@END: from @1
Alias (byte) i#1 = (byte~) $5
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@BEGIN: from
*((word) 4352) ← (byte) 0
*((word) 4353) ← (byte) 1
to:@1
@1: from @1 @BEGIN
(byte[15]) fibs#1 ← phi( @1/(byte[15]) fibs#1 @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 0 )
(byte~) $0 ← (byte) i#2 + (byte) 2
(byte~) $1 ← (byte[15]) fibs#1 *idx (byte) i#2
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte~) $3 ← (byte[15]) fibs#1 *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((byte[15]) fibs#1 + (byte~) $0) ← (byte~) $4
(byte) i#1 ← (byte) i#2 + (byte) 1
(boolean~) $6 ← (byte) i#1 < (byte) 15
if((boolean~) $6) goto @1
to:@END
@END: from @1
Self Phi Eliminated (byte[15]) fibs#1
Succesful SSA optimization Pass2SelfPhiElimination
CONTROL FLOW GRAPH
@BEGIN: from
*((word) 4352) ← (byte) 0
*((word) 4353) ← (byte) 1
to:@1
@1: from @1 @BEGIN
(byte[15]) fibs#1 ← phi( @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 0 )
(byte~) $0 ← (byte) i#2 + (byte) 2
(byte~) $1 ← (byte[15]) fibs#1 *idx (byte) i#2
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte~) $3 ← (byte[15]) fibs#1 *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((byte[15]) fibs#1 + (byte~) $0) ← (byte~) $4
(byte) i#1 ← (byte) i#2 + (byte) 1
(boolean~) $6 ← (byte) i#1 < (byte) 15
if((boolean~) $6) goto @1
to:@END
@END: from @1
Simple Condition (boolean~) $6 if((byte) i#1<(byte) 15) goto @1
Succesful SSA optimization Pass2ConditionalJumpSimplification
CONTROL FLOW GRAPH
@BEGIN: from
*((word) 4352) ← (byte) 0
*((word) 4353) ← (byte) 1
to:@1
@1: from @1 @BEGIN
(byte[15]) fibs#1 ← phi( @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 0 )
(byte~) $0 ← (byte) i#2 + (byte) 2
(byte~) $1 ← (byte[15]) fibs#1 *idx (byte) i#2
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte~) $3 ← (byte[15]) fibs#1 *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((byte[15]) fibs#1 + (byte~) $0) ← (byte~) $4
(byte) i#1 ← (byte) i#2 + (byte) 1
if((byte) i#1<(byte) 15) goto @1
to:@END
@END: from @1
Constant (byte[15]) fibs#1 (word) 4352
Succesful SSA optimization Pass2ConstantPropagation
CONTROL FLOW GRAPH
@BEGIN: from
*((word) 4352) ← (byte) 0
*((word) 4353) ← (byte) 1
to:@1
@1: from @1 @BEGIN
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 0 )
(byte~) $0 ← (byte) i#2 + (byte) 2
(byte~) $1 ← (word) 4352 *idx (byte) i#2
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte~) $3 ← (word) 4352 *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((word) 4352 + (byte~) $0) ← (byte~) $4
(byte) i#1 ← (byte) i#2 + (byte) 1
if((byte) i#1<(byte) 15) goto @1
to:@END
@END: from @1
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
Consolidated referenced array index constant in assignment $3
Consolidated assigned array index constant in assignment *(4354 + $0)
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Succesful SSA optimization Pass2ConstantAdditionElimination
CONTROL FLOW GRAPH
@BEGIN: from
*((word) 4352) ← (byte) 0
*((word) 4353) ← (byte) 1
to:@1
@1: from @1 @BEGIN
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 0 )
(byte~) $0 ← (byte) i#2
(byte~) $1 ← (word) 4352 *idx (byte) i#2
(byte~) $2 ← (byte) i#2
(byte~) $3 ← (word) 4353 *idx (byte~) $2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((word) 4354 + (byte~) $0) ← (byte~) $4
(byte) i#1 ← (byte) i#2 + (byte) 1
if((byte) i#1<(byte) 15) goto @1
to:@END
@END: from @1
Alias (byte) i#2 = (byte~) $0 (byte~) $2
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@BEGIN: from
*((word) 4352) ← (byte) 0
*((word) 4353) ← (byte) 1
to:@1
@1: from @1 @BEGIN
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 0 )
(byte~) $1 ← (word) 4352 *idx (byte) i#2
(byte~) $3 ← (word) 4353 *idx (byte) i#2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((word) 4354 + (byte) i#2) ← (byte~) $4
(byte) i#1 ← (byte) i#2 + (byte) 1
if((byte) i#1<(byte) 15) goto @1
to:@END
@END: from @1
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
Block Sequence Planned @BEGIN @1 @END
Added new block during phi lifting @3(between @1 and @1)
Block Sequence Planned @BEGIN @1 @END @3
CONTROL FLOW GRAPH - PHI LIFTED
@BEGIN: from
*((word) 4352) ← (byte) 0
*((word) 4353) ← (byte) 1
to:@1
@1: from @3 @BEGIN
(byte) i#2 ← phi( @3/(byte~) i#3 @BEGIN/(byte) 0 )
(byte~) $1 ← (word) 4352 *idx (byte) i#2
(byte~) $3 ← (word) 4353 *idx (byte) i#2
(byte~) $4 ← (byte~) $1 + (byte~) $3
*((word) 4354 + (byte) i#2) ← (byte~) $4
(byte) i#1 ← (byte) i#2 + (byte) 1
if((byte) i#1<(byte) 15) goto @3
to:@END
@END: from @1
@3: from @1
(byte~) i#3 ← (byte) i#1
to:@1
Propagating live ranges...
Propagating live ranges...
CONTROL FLOW GRAPH - LIVE RANGES
@BEGIN: from
[0] *((word) 4352) ← (byte) 0 [ ]
[1] *((word) 4353) ← (byte) 1 [ ]
to:@1
@1: from @3 @BEGIN
[2] (byte) i#2 ← phi( @3/(byte~) i#3 @BEGIN/(byte) 0 ) [ i#2 ]
[3] (byte~) $1 ← (word) 4352 *idx (byte) i#2 [ i#2 $1 ]
[4] (byte~) $3 ← (word) 4353 *idx (byte) i#2 [ i#2 $1 $3 ]
[5] (byte~) $4 ← (byte~) $1 + (byte~) $3 [ i#2 $4 ]
[6] *((word) 4354 + (byte) i#2) ← (byte~) $4 [ i#2 ]
[7] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ]
[8] if((byte) i#1<(byte) 15) goto @3 [ i#1 ]
to:@END
@END: from @1
@3: from @1
[9] (byte~) i#3 ← (byte) i#1 [ i#3 ]
to:@1
Created 1 initial phi equivalence classes
Coalesced [9] i#3 ← i#1
Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) @3
Block Sequence Planned @BEGIN @1 @END
Propagating live ranges...
Propagating live ranges...
CONTROL FLOW GRAPH - PHI MEM COALESCED
@BEGIN: from
[0] *((word) 4352) ← (byte) 0 [ ]
[1] *((word) 4353) ← (byte) 1 [ ]
to:@1
@1: from @1 @BEGIN
[2] (byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 0 ) [ i#2 ]
[3] (byte~) $1 ← (word) 4352 *idx (byte) i#2 [ i#2 $1 ]
[4] (byte~) $3 ← (word) 4353 *idx (byte) i#2 [ i#2 $1 $3 ]
[5] (byte~) $4 ← (byte~) $1 + (byte~) $3 [ i#2 $4 ]
[6] *((word) 4354 + (byte) i#2) ← (byte~) $4 [ i#2 ]
[7] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ]
[8] if((byte) i#1<(byte) 15) goto @1 [ i#1 ]
to:@END
@END: from @1
CALL GRAPH
DOMINATORS
@BEGIN dominated by @BEGIN
@1 dominated by @1 @BEGIN
@END dominated by @1 @BEGIN @END
Found back edge: Loop head: @1 tails: @1 blocks: null
Populated: Loop head: @1 tails: @1 blocks: @1
NATURAL LOOPS
Loop head: @1 tails: @1 blocks: @1
Found 1 loops in scope []
Loop head: @1 tails: @1 blocks: @1
NATURAL LOOPS WITH DEPTH
Loop head: @1 tails: @1 blocks: @1 depth: 1
Initial phi equivalence classes
[ i#2 i#1 ]
Copy Coalesced equivalence classes
[ i#2 i#1 ]
Added variable $1 to zero page equivalence class [ $1 ]
Added variable $3 to zero page equivalence class [ $3 ]
Added variable $4 to zero page equivalence class [ $1 $4 ]
Complete equivalence classes
[ i#2 i#1 ]
[ $1 $4 ]
[ $3 ]
Allocated zp byte:2 to zp byte:2 [ i#2 i#1 ]
Allocated zp byte:3 to zp byte:3 [ $1 $4 ]
Allocated zp byte:4 to zp byte:4 [ $3 ]
VARIABLE REGISTER WEIGHTS
(byte~) $1 11.0
(byte~) $3 22.0
(byte~) $4 22.0
(byte[15]) fibs
(byte) i
(byte) i#1 16.5
(byte) i#2 11.0
zp byte:2 [ i#2 i#1 ]
zp byte:3 [ $1 $4 ]
zp byte:4 [ $3 ]
Re-allocated ZP register from zp byte:2 to zp byte:2
Re-allocated ZP register from zp byte:3 to zp byte:3
Re-allocated ZP register from zp byte:4 to zp byte:4
INITIAL ASM
BBEGIN:
// [0] *((word) 4352) ← (byte) 0 [ ] // coptr1=coby2
lda #0
sta 4352
// [1] *((word) 4353) ← (byte) 1 [ ] // coptr1=coby2
lda #1
sta 4353
B1_from_BBEGIN:
// (byte) i#2 = (byte) 0 // zpby1=coby1
lda #0
sta 2
jmp B1
B1_from_B1:
// (byte) i#2 = (byte) i#1 // register copy zp byte:2
jmp B1
B1:
// [3] (byte~) $1 ← (word) 4352 *idx (byte) i#2 [ i#2 $1 ] // zpby1=cowo1_staridx_zpby2
ldy 2
lda 4352,y
sta 3
// [4] (byte~) $3 ← (word) 4353 *idx (byte) i#2 [ i#2 $1 $3 ] // zpby1=cowo1_staridx_zpby2
ldy 2
lda 4353,y
sta 4
// [5] (byte~) $4 ← (byte~) $1 + (byte~) $3 [ i#2 $4 ] // zpby1=zpby1_plus_zpby2
lda 3
clc
adc 4
sta 3
// [6] *((word) 4354 + (byte) i#2) ← (byte~) $4 [ i#2 ] // ptr_cowo1_zpby1=zpby2
lda 3
ldy 2
sta 4354,y
// [7] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ] // zpby1=zpby1_plus_1
inc 2
// [8] if((byte) i#1<(byte) 15) goto @1 [ i#1 ] // zpby1_lt_coby1_then_la1
lda 2
cmp #15
bcc B1_from_B1
jmp BEND
BEND:
Removing instruction jmp B1
Removing instruction jmp BEND
Succesful ASM optimization Pass5NextJumpElimination
ASSEMBLER
BBEGIN:
// [0] *((word) 4352) ← (byte) 0 [ ] // coptr1=coby2
lda #0
sta 4352
// [1] *((word) 4353) ← (byte) 1 [ ] // coptr1=coby2
lda #1
sta 4353
B1_from_BBEGIN:
// (byte) i#2 = (byte) 0 // zpby1=coby1
lda #0
sta 2
jmp B1
B1_from_B1:
// (byte) i#2 = (byte) i#1 // register copy zp byte:2
B1:
// [3] (byte~) $1 ← (word) 4352 *idx (byte) i#2 [ i#2 $1 ] // zpby1=cowo1_staridx_zpby2
ldy 2
lda 4352,y
sta 3
// [4] (byte~) $3 ← (word) 4353 *idx (byte) i#2 [ i#2 $1 $3 ] // zpby1=cowo1_staridx_zpby2
ldy 2
lda 4353,y
sta 4
// [5] (byte~) $4 ← (byte~) $1 + (byte~) $3 [ i#2 $4 ] // zpby1=zpby1_plus_zpby2
lda 3
clc
adc 4
sta 3
// [6] *((word) 4354 + (byte) i#2) ← (byte~) $4 [ i#2 ] // ptr_cowo1_zpby1=zpby2
lda 3
ldy 2
sta 4354,y
// [7] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ] // zpby1=zpby1_plus_1
inc 2
// [8] if((byte) i#1<(byte) 15) goto @1 [ i#1 ] // zpby1_lt_coby1_then_la1
lda 2
cmp #15
bcc B1_from_B1
BEND:
Removing instruction jmp B1
Succesful ASM optimization Pass5NextJumpElimination
ASSEMBLER
BBEGIN:
// [0] *((word) 4352) ← (byte) 0 [ ] // coptr1=coby2
lda #0
sta 4352
// [1] *((word) 4353) ← (byte) 1 [ ] // coptr1=coby2
lda #1
sta 4353
B1_from_BBEGIN:
// (byte) i#2 = (byte) 0 // zpby1=coby1
lda #0
sta 2
B1_from_B1:
// (byte) i#2 = (byte) i#1 // register copy zp byte:2
B1:
// [3] (byte~) $1 ← (word) 4352 *idx (byte) i#2 [ i#2 $1 ] // zpby1=cowo1_staridx_zpby2
ldy 2
lda 4352,y
sta 3
// [4] (byte~) $3 ← (word) 4353 *idx (byte) i#2 [ i#2 $1 $3 ] // zpby1=cowo1_staridx_zpby2
ldy 2
lda 4353,y
sta 4
// [5] (byte~) $4 ← (byte~) $1 + (byte~) $3 [ i#2 $4 ] // zpby1=zpby1_plus_zpby2
lda 3
clc
adc 4
sta 3
// [6] *((word) 4354 + (byte) i#2) ← (byte~) $4 [ i#2 ] // ptr_cowo1_zpby1=zpby2
lda 3
ldy 2
sta 4354,y
// [7] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ] // zpby1=zpby1_plus_1
inc 2
// [8] if((byte) i#1<(byte) 15) goto @1 [ i#1 ] // zpby1_lt_coby1_then_la1
lda 2
cmp #15
bcc B1_from_B1
BEND:
FINAL SYMBOL TABLE
(byte~) $1 zp byte:3 11.0
(byte~) $3 zp byte:4 22.0
(byte~) $4 zp byte:3 22.0
(label) @1
(label) @BEGIN
(label) @END
(byte[15]) fibs
(byte) i
(byte) i#1 zp byte:2 16.5
(byte) i#2 zp byte:2 11.0
zp byte:2 [ i#2 i#1 ]
zp byte:3 [ $1 $4 ]
zp byte:4 [ $3 ]
FINAL CODE
BBEGIN:
// [0] *((word) 4352) ← (byte) 0 [ ] // coptr1=coby2
lda #0
sta 4352
// [1] *((word) 4353) ← (byte) 1 [ ] // coptr1=coby2
lda #1
sta 4353
B1_from_BBEGIN:
// (byte) i#2 = (byte) 0 // zpby1=coby1
lda #0
sta 2
B1_from_B1:
// (byte) i#2 = (byte) i#1 // register copy zp byte:2
B1:
// [3] (byte~) $1 ← (word) 4352 *idx (byte) i#2 [ i#2 $1 ] // zpby1=cowo1_staridx_zpby2
ldy 2
lda 4352,y
sta 3
// [4] (byte~) $3 ← (word) 4353 *idx (byte) i#2 [ i#2 $1 $3 ] // zpby1=cowo1_staridx_zpby2
ldy 2
lda 4353,y
sta 4
// [5] (byte~) $4 ← (byte~) $1 + (byte~) $3 [ i#2 $4 ] // zpby1=zpby1_plus_zpby2
lda 3
clc
adc 4
sta 3
// [6] *((word) 4354 + (byte) i#2) ← (byte~) $4 [ i#2 ] // ptr_cowo1_zpby1=zpby2
lda 3
ldy 2
sta 4354,y
// [7] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ] // zpby1=zpby1_plus_1
inc 2
// [8] if((byte) i#1<(byte) 15) goto @1 [ i#1 ] // zpby1_lt_coby1_then_la1
lda 2
cmp #15
bcc B1_from_B1
BEND:

View File

@ -0,0 +1,14 @@
(byte~) $1 zp byte:3 11.0
(byte~) $3 zp byte:4 22.0
(byte~) $4 zp byte:3 22.0
(label) @1
(label) @BEGIN
(label) @END
(byte[15]) fibs
(byte) i
(byte) i#1 zp byte:2 16.5
(byte) i#2 zp byte:2 11.0
zp byte:2 [ i#2 i#1 ]
zp byte:3 [ $1 $4 ]
zp byte:4 [ $3 ]

View File

@ -1468,6 +1468,204 @@ plot::@return: from plot::@3
to:@RETURN
@END: from @BEGIN
Consolidated constant in assignment plot::$2
Succesful SSA optimization Pass2ConstantAdditionElimination
CONTROL FLOW GRAPH
@BEGIN: from
call main param-assignment
to:@END
main: from @BEGIN
(byte[256]) buffer2#15 ← phi( @BEGIN/(word) 4352 )
(byte[1000]) SCREEN#11 ← phi( @BEGIN/(word) 1024 )
(byte*) RASTER#8 ← phi( @BEGIN/(word) 53266 )
(byte[256]) buffer1#9 ← phi( @BEGIN/(word) 4096 )
call prepare param-assignment
to:main::@9
main::@9: from main
(byte[256]) buffer2#14 ← phi( main/(byte[256]) buffer2#15 )
(byte[256]) buffer1#22 ← phi( main/(byte[256]) buffer1#9 )
(byte[1000]) SCREEN#10 ← phi( main/(byte[1000]) SCREEN#11 )
(byte*) RASTER#6 ← phi( main/(byte*) RASTER#8 )
to:main::@1
main::@1: from main::@11 main::@9
(byte[256]) buffer2#11 ← phi( main::@11/(byte[256]) buffer2#13 main::@9/(byte[256]) buffer2#14 )
(byte[256]) buffer1#19 ← phi( main::@11/(byte[256]) buffer1#21 main::@9/(byte[256]) buffer1#22 )
(byte[1000]) SCREEN#7 ← phi( main::@11/(byte[1000]) SCREEN#9 main::@9/(byte[1000]) SCREEN#10 )
(byte*) RASTER#3 ← phi( main::@11/(byte*) RASTER#5 main::@9/(byte*) RASTER#6 )
to:main::@3
main::@2: from main::@6
(byte[256]) buffer2#12 ← phi( main::@6/(byte[256]) buffer2#8 )
(byte[256]) buffer1#20 ← phi( main::@6/(byte[256]) buffer1#16 )
(byte[1000]) SCREEN#8 ← phi( main::@6/(byte[1000]) SCREEN#4 )
(byte) main::c#5 ← phi( main::@6/(byte) main::c#1 )
(byte*) RASTER#4 ← phi( main::@6/(byte*) RASTER#7 )
to:main::@3
main::@3: from main::@1 main::@2 main::@3
(byte[256]) buffer2#10 ← phi( main::@1/(byte[256]) buffer2#11 main::@2/(byte[256]) buffer2#12 main::@3/(byte[256]) buffer2#10 )
(byte[256]) buffer1#18 ← phi( main::@1/(byte[256]) buffer1#19 main::@2/(byte[256]) buffer1#20 main::@3/(byte[256]) buffer1#18 )
(byte[1000]) SCREEN#6 ← phi( main::@1/(byte[1000]) SCREEN#7 main::@2/(byte[1000]) SCREEN#8 main::@3/(byte[1000]) SCREEN#6 )
(byte) main::c#4 ← phi( main::@1/(byte) 25 main::@2/(byte) main::c#5 main::@3/(byte) main::c#4 )
(byte*) RASTER#1 ← phi( main::@1/(byte*) RASTER#3 main::@2/(byte*) RASTER#4 main::@3/(byte*) RASTER#1 )
(byte~) main::$1 ← * (byte*) RASTER#1
(boolean~) main::$2 ← (byte~) main::$1 != (byte) 254
if((boolean~) main::$2) goto main::@3
to:main::@4
main::@4: from main::@3 main::@4
(byte[256]) buffer2#9 ← phi( main::@3/(byte[256]) buffer2#10 main::@4/(byte[256]) buffer2#9 )
(byte[256]) buffer1#17 ← phi( main::@3/(byte[256]) buffer1#18 main::@4/(byte[256]) buffer1#17 )
(byte[1000]) SCREEN#5 ← phi( main::@3/(byte[1000]) SCREEN#6 main::@4/(byte[1000]) SCREEN#5 )
(byte) main::c#3 ← phi( main::@3/(byte) main::c#4 main::@4/(byte) main::c#3 )
(byte*) RASTER#2 ← phi( main::@3/(byte*) RASTER#1 main::@4/(byte*) RASTER#2 )
(byte~) main::$3 ← * (byte*) RASTER#2
(boolean~) main::$4 ← (byte~) main::$3 != (byte) 255
if((boolean~) main::$4) goto main::@4
to:main::@6
main::@6: from main::@4
(byte[256]) buffer2#8 ← phi( main::@4/(byte[256]) buffer2#9 )
(byte[256]) buffer1#16 ← phi( main::@4/(byte[256]) buffer1#17 )
(byte[1000]) SCREEN#4 ← phi( main::@4/(byte[1000]) SCREEN#5 )
(byte*) RASTER#7 ← phi( main::@4/(byte*) RASTER#2 )
(byte) main::c#2 ← phi( main::@4/(byte) main::c#3 )
(byte) main::c#1 ← -- (byte) main::c#2
(boolean~) main::$5 ← (byte) main::c#1 != (byte) 0
if((boolean~) main::$5) goto main::@2
to:main::@7
main::@7: from main::@6
(byte*) RASTER#10 ← phi( main::@6/(byte*) RASTER#7 )
(byte[256]) buffer2#7 ← phi( main::@6/(byte[256]) buffer2#8 )
(byte[256]) buffer1#14 ← phi( main::@6/(byte[256]) buffer1#16 )
(byte[1000]) SCREEN#3 ← phi( main::@6/(byte[1000]) SCREEN#4 )
call flip param-assignment
to:main::@10
main::@10: from main::@7
(byte[256]) buffer2#16 ← phi( main::@7/(byte[256]) buffer2#7 )
(byte[256]) buffer1#15 ← phi( main::@7/(byte[256]) buffer1#14 )
(byte*) RASTER#9 ← phi( main::@7/(byte*) RASTER#10 )
(byte[1000]) SCREEN#2 ← phi( main::@7/(byte[1000]) SCREEN#3 )
call plot param-assignment
to:main::@11
main::@11: from main::@10
(byte[256]) buffer2#13 ← phi( main::@10/(byte[256]) buffer2#16 )
(byte[256]) buffer1#21 ← phi( main::@10/(byte[256]) buffer1#15 )
(byte[1000]) SCREEN#9 ← phi( main::@10/(byte[1000]) SCREEN#2 )
(byte*) RASTER#5 ← phi( main::@10/(byte*) RASTER#9 )
if(true) goto main::@1
to:main::@return
main::@return: from main::@11
return
to:@RETURN
prepare: from main
(byte[256]) buffer1#5 ← phi( main/(byte[256]) buffer1#9 )
to:prepare::@1
prepare::@1: from prepare prepare::@1
(byte[256]) buffer1#1 ← phi( prepare/(byte[256]) buffer1#5 prepare::@1/(byte[256]) buffer1#1 )
(byte) prepare::i#2 ← phi( prepare/(byte) 0 prepare::@1/(byte) prepare::i#1 )
*((byte[256]) buffer1#1 + (byte) prepare::i#2) ← (byte) prepare::i#2
(byte) prepare::i#1 ← ++ (byte) prepare::i#2
(boolean~) prepare::$0 ← (byte) prepare::i#1 != (byte) 0
if((boolean~) prepare::$0) goto prepare::@1
to:prepare::@return
prepare::@return: from prepare::@1
return
to:@RETURN
flip: from main::@7
(byte[256]) buffer2#5 ← phi( main::@7/(byte[256]) buffer2#7 )
(byte[256]) buffer1#10 ← phi( main::@7/(byte[256]) buffer1#14 )
to:flip::@1
flip::@1: from flip flip::@4
(byte) flip::r#4 ← phi( flip/(byte) 16 flip::@4/(byte) flip::r#1 )
(byte) flip::dstIdx#5 ← phi( flip/(byte) 15 flip::@4/(byte) flip::dstIdx#2 )
(byte[256]) buffer2#3 ← phi( flip/(byte[256]) buffer2#5 flip::@4/(byte[256]) buffer2#6 )
(byte) flip::srcIdx#3 ← phi( flip/(byte) 0 flip::@4/(byte) flip::srcIdx#4 )
(byte[256]) buffer1#6 ← phi( flip/(byte[256]) buffer1#10 flip::@4/(byte[256]) buffer1#11 )
to:flip::@2
flip::@2: from flip::@1 flip::@2
(byte) flip::r#3 ← phi( flip::@1/(byte) flip::r#4 flip::@2/(byte) flip::r#3 )
(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[256]) buffer2#1 ← phi( flip::@1/(byte[256]) buffer2#3 flip::@2/(byte[256]) buffer2#1 )
(byte) flip::srcIdx#2 ← phi( flip::@1/(byte) flip::srcIdx#3 flip::@2/(byte) flip::srcIdx#1 )
(byte[256]) buffer1#2 ← phi( flip::@1/(byte[256]) buffer1#6 flip::@2/(byte[256]) buffer1#2 )
(byte~) flip::$0 ← (byte[256]) buffer1#2 *idx (byte) flip::srcIdx#2
*((byte[256]) buffer2#1 + (byte) flip::dstIdx#3) ← (byte~) flip::$0
(byte) flip::srcIdx#1 ← ++ (byte) flip::srcIdx#2
(byte~) flip::$1 ← (byte) flip::dstIdx#3 + (byte) 16
(byte) flip::dstIdx#1 ← (byte~) flip::$1
(byte) flip::c#1 ← -- (byte) flip::c#2
(boolean~) flip::$2 ← (byte) flip::c#1 != (byte) 0
if((boolean~) flip::$2) goto flip::@2
to:flip::@4
flip::@4: from flip::@2
(byte[256]) buffer2#6 ← phi( flip::@2/(byte[256]) buffer2#1 )
(byte) flip::srcIdx#4 ← phi( flip::@2/(byte) flip::srcIdx#1 )
(byte[256]) buffer1#11 ← phi( flip::@2/(byte[256]) buffer1#2 )
(byte) flip::r#2 ← phi( flip::@2/(byte) flip::r#3 )
(byte) flip::dstIdx#4 ← phi( flip::@2/(byte) flip::dstIdx#1 )
(byte) flip::dstIdx#2 ← -- (byte) flip::dstIdx#4
(byte) flip::r#1 ← -- (byte) flip::r#2
(boolean~) flip::$3 ← (byte) flip::r#1 != (byte) 0
if((boolean~) flip::$3) goto flip::@1
to:flip::@5
flip::@5: from flip::@4
(byte[256]) buffer1#7 ← phi( flip::@4/(byte[256]) buffer1#11 )
(byte[256]) buffer2#4 ← phi( flip::@4/(byte[256]) buffer2#6 )
to:flip::@3
flip::@3: from flip::@3 flip::@5
(byte[256]) buffer1#3 ← phi( flip::@3/(byte[256]) buffer1#3 flip::@5/(byte[256]) buffer1#7 )
(byte) flip::i#2 ← phi( flip::@3/(byte) flip::i#1 flip::@5/(byte) 0 )
(byte[256]) buffer2#2 ← phi( flip::@3/(byte[256]) buffer2#2 flip::@5/(byte[256]) buffer2#4 )
(byte~) flip::$4 ← (byte[256]) buffer2#2 *idx (byte) flip::i#2
*((byte[256]) buffer1#3 + (byte) flip::i#2) ← (byte~) flip::$4
(byte) flip::i#1 ← ++ (byte) flip::i#2
(boolean~) flip::$5 ← (byte) flip::i#1 != (byte) 0
if((boolean~) flip::$5) goto flip::@3
to:flip::@return
flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte[256]) buffer1#12 ← phi( main::@10/(byte[256]) buffer1#15 )
(byte[1000]) SCREEN#1 ← phi( main::@10/(byte[1000]) SCREEN#2 )
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1
(byte*~) plot::$2 ← (byte*~) plot::$1 + (byte) 212
(byte*) plot::line#0 ← (byte*~) plot::$2
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#4 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
(byte*) plot::line#4 ← phi( plot/(byte*) plot::line#0 plot::@3/(byte*) plot::line#1 )
(byte) plot::i#3 ← phi( plot/(byte) 0 plot::@3/(byte) plot::i#4 )
(byte[256]) buffer1#8 ← phi( plot/(byte[256]) buffer1#12 plot::@3/(byte[256]) buffer1#13 )
to:plot::@2
plot::@2: from plot::@1 plot::@2
(byte) plot::y#3 ← phi( plot::@1/(byte) plot::y#4 plot::@2/(byte) plot::y#3 )
(byte) plot::x#2 ← phi( plot::@1/(byte) 0 plot::@2/(byte) plot::x#1 )
(byte*) plot::line#2 ← phi( plot::@1/(byte*) plot::line#4 plot::@2/(byte*) plot::line#2 )
(byte) plot::i#2 ← phi( plot::@1/(byte) plot::i#3 plot::@2/(byte) plot::i#1 )
(byte[256]) buffer1#4 ← phi( plot::@1/(byte[256]) buffer1#8 plot::@2/(byte[256]) buffer1#4 )
(byte~) plot::$3 ← (byte[256]) buffer1#4 *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
(boolean~) plot::$4 ← (byte) plot::x#1 < (byte) 16
if((boolean~) plot::$4) goto plot::@2
to:plot::@3
plot::@3: from plot::@2
(byte) plot::i#4 ← phi( plot::@2/(byte) plot::i#1 )
(byte[256]) buffer1#13 ← phi( plot::@2/(byte[256]) buffer1#4 )
(byte) plot::y#2 ← phi( plot::@2/(byte) plot::y#3 )
(byte*) plot::line#3 ← phi( plot::@2/(byte*) plot::line#2 )
(byte*~) plot::$5 ← (byte*) plot::line#3 + (byte) 40
(byte*) plot::line#1 ← (byte*~) plot::$5
(byte) plot::y#1 ← -- (byte) plot::y#2
(boolean~) plot::$6 ← (byte) plot::y#1 != (byte) 0
if((boolean~) plot::$6) goto plot::@1
to:plot::@return
plot::@return: from plot::@3
return
to:@RETURN
@END: from @BEGIN
Not aliassing across scopes: plot::$1 SCREEN#1
Alias (byte*) RASTER#6 = (byte*) RASTER#8
Alias (byte[1000]) SCREEN#10 = (byte[1000]) SCREEN#11
Alias (byte[256]) buffer1#22 = (byte[256]) buffer1#9 (byte[256]) buffer1#5
@ -1607,8 +1805,8 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1 + (byte) 200
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 12
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#4 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
@ -1758,8 +1956,8 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1 + (byte) 200
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 12
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#4 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
@ -1924,8 +2122,8 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1 + (byte) 200
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 12
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#4 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
@ -2073,8 +2271,8 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1 + (byte) 200
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 12
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#4 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
@ -2208,8 +2406,8 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1 + (byte) 200
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 12
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#4 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
@ -2340,8 +2538,8 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1 + (byte) 200
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 12
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#4 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
@ -2372,7 +2570,7 @@ plot::@return: from plot::@3
@END: from @BEGIN
Multiple usages for variable. Not optimizing sub-constant (byte) prepare::i#2
Multiple usages for variable. Not optimizing sub-constant (byte[1000]) SCREEN#1
Not aliassing across scopes: plot::$1 SCREEN#1
Alias (byte*) RASTER#1 = (byte*) RASTER#10
Alias (byte) main::c#2 = (byte) main::c#4
Alias (byte[1000]) SCREEN#1 = (byte[1000]) SCREEN#6
@ -2474,8 +2672,8 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1 + (byte) 200
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 12
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#2 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
@ -2599,8 +2797,8 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1 + (byte) 200
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 12
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#2 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
@ -2628,7 +2826,7 @@ plot::@return: from plot::@3
@END: from @BEGIN
Multiple usages for variable. Not optimizing sub-constant (byte) prepare::i#2
Multiple usages for variable. Not optimizing sub-constant (byte[1000]) SCREEN#1
Not aliassing across scopes: plot::$1 SCREEN#1
Alias (byte*) RASTER#1 = (byte*) RASTER#3
Alias (byte[1000]) SCREEN#1 = (byte[1000]) SCREEN#7
Alias (byte[256]) buffer1#10 = (byte[256]) buffer1#19 (byte[256]) buffer1#11 (byte[256]) buffer1#13
@ -2717,8 +2915,8 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1 + (byte) 200
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 12
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#2 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
@ -2832,8 +3030,8 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1 + (byte) 200
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 12
(byte*~) plot::$1 ← (byte[1000]) SCREEN#1
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#2 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
@ -2943,8 +3141,8 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*~) plot::$1 ← (word) 1024 + (byte) 200
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 12
(byte*~) plot::$1 ← (word) 1024
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#2 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
@ -3054,8 +3252,8 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*~) plot::$1 ← (word) 1024 + (byte) 200
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 12
(byte*~) plot::$1 ← (word) 1024
(byte*) plot::line#0 ← (byte*~) plot::$1 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#2 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
@ -3081,7 +3279,7 @@ plot::@return: from plot::@3
to:@RETURN
@END: from @BEGIN
Constant (byte*~) plot::$1 (word) 1224
Constant (byte*~) plot::$1 (word) 1024
Succesful SSA optimization Pass2ConstantPropagation
CONTROL FLOW GRAPH
@BEGIN: from
@ -3160,7 +3358,7 @@ flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@10
(byte*) plot::line#0 ← (word) 1224 + (byte) 12
(byte*) plot::line#0 ← (word) 1024 + (byte) 212
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#2 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )

View File

@ -4,13 +4,9 @@ B1_from_BBEGIN:
sta 2
B1_from_B1:
B1:
lda #2
lda 2
clc
adc 2
sta 3
lda 3
clc
adc #2
adc #4
sta 3
lda 3
ldy 2

View File

@ -2,10 +2,9 @@
to:@1
@1: from @1 @BEGIN
[0] (byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 ) [ i#2 ]
[1] (byte~) $0 ← (byte) 2 + (byte) i#2 [ i#2 $0 ]
[2] (byte~) $1 ← (byte~) $0 + (byte) 2 [ i#2 $1 ]
[3] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ]
[4] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ]
[5] if((byte) i#1<(byte) 10) goto @1 [ i#1 ]
[1] (byte~) $1 ← (byte) i#2 + (byte) 4 [ i#2 $1 ]
[2] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ]
[3] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ]
[4] if((byte) i#1<(byte) 10) goto @1 [ i#1 ]
to:@END
@END: from @1

View File

@ -134,7 +134,26 @@ CONTROL FLOW GRAPH
@END: from @1
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Consolidated constant in assignment $1
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Succesful SSA optimization Pass2ConstantAdditionElimination
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @1 @BEGIN
(byte[16]) p#1 ← phi( @1/(byte[16]) p#1 @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 )
(byte~) $0 ← (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 4
*((byte[16]) p#1 + (byte) i#2) ← (byte~) $1
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte) i#1 ← (byte~) $2
(boolean~) $3 ← (byte) i#1 < (byte) 10
if((boolean~) $3) goto @1
to:@END
@END: from @1
Alias (byte) i#2 = (byte~) $0
Alias (byte) i#1 = (byte~) $2
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@ -143,8 +162,7 @@ CONTROL FLOW GRAPH
@1: from @1 @BEGIN
(byte[16]) p#1 ← phi( @1/(byte[16]) p#1 @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
(byte~) $1 ← (byte) i#2 + (byte) 4
*((byte[16]) p#1 + (byte) i#2) ← (byte~) $1
(byte) i#1 ← (byte) i#2 + (byte) 1
(boolean~) $3 ← (byte) i#1 < (byte) 10
@ -160,8 +178,7 @@ CONTROL FLOW GRAPH
@1: from @1 @BEGIN
(byte[16]) p#1 ← phi( @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
(byte~) $1 ← (byte) i#2 + (byte) 4
*((byte[16]) p#1 + (byte) i#2) ← (byte~) $1
(byte) i#1 ← (byte) i#2 + (byte) 1
(boolean~) $3 ← (byte) i#1 < (byte) 10
@ -177,8 +194,7 @@ CONTROL FLOW GRAPH
@1: from @1 @BEGIN
(byte[16]) p#1 ← phi( @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
(byte~) $1 ← (byte) i#2 + (byte) 4
*((byte[16]) p#1 + (byte) i#2) ← (byte~) $1
(byte) i#1 ← (byte) i#2 + (byte) 1
if((byte) i#1<(byte) 10) goto @1
@ -192,8 +208,7 @@ CONTROL FLOW GRAPH
to:@1
@1: from @1 @BEGIN
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
(byte~) $1 ← (byte) i#2 + (byte) 4
*((word) 4352 + (byte) i#2) ← (byte~) $1
(byte) i#1 ← (byte) i#2 + (byte) 1
if((byte) i#1<(byte) 10) goto @1
@ -214,8 +229,7 @@ CONTROL FLOW GRAPH - PHI LIFTED
to:@1
@1: from @3 @BEGIN
(byte) i#2 ← phi( @3/(byte~) i#3 @BEGIN/(byte) 5 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
(byte~) $1 ← (byte) i#2 + (byte) 4
*((word) 4352 + (byte) i#2) ← (byte~) $1
(byte) i#1 ← (byte) i#2 + (byte) 1
if((byte) i#1<(byte) 10) goto @3
@ -225,41 +239,37 @@ CONTROL FLOW GRAPH - PHI LIFTED
(byte~) i#3 ← (byte) i#1
to:@1
Propagating live ranges...
Propagating live ranges...
CONTROL FLOW GRAPH - LIVE RANGES
@BEGIN: from
to:@1
@1: from @3 @BEGIN
[0] (byte) i#2 ← phi( @3/(byte~) i#3 @BEGIN/(byte) 5 ) [ i#2 ]
[1] (byte~) $0 ← (byte) 2 + (byte) i#2 [ i#2 $0 ]
[2] (byte~) $1 ← (byte~) $0 + (byte) 2 [ i#2 $1 ]
[3] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ]
[4] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ]
[5] if((byte) i#1<(byte) 10) goto @3 [ i#1 ]
[1] (byte~) $1 ← (byte) i#2 + (byte) 4 [ i#2 $1 ]
[2] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ]
[3] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ]
[4] if((byte) i#1<(byte) 10) goto @3 [ i#1 ]
to:@END
@END: from @1
@3: from @1
[6] (byte~) i#3 ← (byte) i#1 [ i#3 ]
[5] (byte~) i#3 ← (byte) i#1 [ i#3 ]
to:@1
Created 1 initial phi equivalence classes
Coalesced [6] i#3 ← i#1
Coalesced [5] i#3 ← i#1
Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) @3
Block Sequence Planned @BEGIN @1 @END
Propagating live ranges...
Propagating live ranges...
CONTROL FLOW GRAPH - PHI MEM COALESCED
@BEGIN: from
to:@1
@1: from @1 @BEGIN
[0] (byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 ) [ i#2 ]
[1] (byte~) $0 ← (byte) 2 + (byte) i#2 [ i#2 $0 ]
[2] (byte~) $1 ← (byte~) $0 + (byte) 2 [ i#2 $1 ]
[3] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ]
[4] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ]
[5] if((byte) i#1<(byte) 10) goto @1 [ i#1 ]
[1] (byte~) $1 ← (byte) i#2 + (byte) 4 [ i#2 $1 ]
[2] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ]
[3] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ]
[4] if((byte) i#1<(byte) 10) goto @1 [ i#1 ]
to:@END
@END: from @1
@ -284,24 +294,22 @@ Initial phi equivalence classes
[ i#2 i#1 ]
Copy Coalesced equivalence classes
[ i#2 i#1 ]
Added variable $0 to zero page equivalence class [ $0 ]
Added variable $1 to zero page equivalence class [ $0 $1 ]
Added variable $1 to zero page equivalence class [ $1 ]
Complete equivalence classes
[ i#2 i#1 ]
[ $0 $1 ]
[ $1 ]
Allocated zp byte:2 to zp byte:2 [ i#2 i#1 ]
Allocated zp byte:3 to zp byte:3 [ $0 $1 ]
Allocated zp byte:3 to zp byte:3 [ $1 ]
VARIABLE REGISTER WEIGHTS
(byte~) $0 22.0
(byte~) $1 22.0
(byte) i
(byte) i#1 16.5
(byte) i#2 11.0
(byte) i#2 14.666666666666666
(byte[16]) p
zp byte:2 [ i#2 i#1 ]
zp byte:3 [ $0 $1 ]
zp byte:3 [ $1 ]
Re-allocated ZP register from zp byte:2 to zp byte:2
Re-allocated ZP register from zp byte:3 to zp byte:3
@ -316,23 +324,18 @@ B1_from_B1:
// (byte) i#2 = (byte) i#1 // register copy zp byte:2
jmp B1
B1:
// [1] (byte~) $0 ← (byte) 2 + (byte) i#2 [ i#2 $0 ] // zpby1=coby1_plus_zpby2
lda #2
// [1] (byte~) $1 ← (byte) i#2 + (byte) 4 [ i#2 $1 ] // zpby1=zpby2_plus_coby1
lda 2
clc
adc 2
adc #4
sta 3
// [2] (byte~) $1 ← (byte~) $0 + (byte) 2 [ i#2 $1 ] // zpby1=zpby1_plus_coby1
lda 3
clc
adc #2
sta 3
// [3] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ] // ptr_cowo1_zpby1=zpby2
// [2] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ] // ptr_cowo1_zpby1=zpby2
lda 3
ldy 2
sta 4352,y
// [4] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ] // zpby1=zpby1_plus_1
// [3] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ] // zpby1=zpby1_plus_1
inc 2
// [5] if((byte) i#1<(byte) 10) goto @1 [ i#1 ] // zpby1_lt_coby1_then_la1
// [4] if((byte) i#1<(byte) 10) goto @1 [ i#1 ] // zpby1_lt_coby1_then_la1
lda 2
cmp #10
bcc B1_from_B1
@ -352,23 +355,18 @@ B1_from_BBEGIN:
B1_from_B1:
// (byte) i#2 = (byte) i#1 // register copy zp byte:2
B1:
// [1] (byte~) $0 ← (byte) 2 + (byte) i#2 [ i#2 $0 ] // zpby1=coby1_plus_zpby2
lda #2
// [1] (byte~) $1 ← (byte) i#2 + (byte) 4 [ i#2 $1 ] // zpby1=zpby2_plus_coby1
lda 2
clc
adc 2
adc #4
sta 3
// [2] (byte~) $1 ← (byte~) $0 + (byte) 2 [ i#2 $1 ] // zpby1=zpby1_plus_coby1
lda 3
clc
adc #2
sta 3
// [3] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ] // ptr_cowo1_zpby1=zpby2
// [2] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ] // ptr_cowo1_zpby1=zpby2
lda 3
ldy 2
sta 4352,y
// [4] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ] // zpby1=zpby1_plus_1
// [3] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ] // zpby1=zpby1_plus_1
inc 2
// [5] if((byte) i#1<(byte) 10) goto @1 [ i#1 ] // zpby1_lt_coby1_then_la1
// [4] if((byte) i#1<(byte) 10) goto @1 [ i#1 ] // zpby1_lt_coby1_then_la1
lda 2
cmp #10
bcc B1_from_B1
@ -385,41 +383,35 @@ B1_from_BBEGIN:
B1_from_B1:
// (byte) i#2 = (byte) i#1 // register copy zp byte:2
B1:
// [1] (byte~) $0 ← (byte) 2 + (byte) i#2 [ i#2 $0 ] // zpby1=coby1_plus_zpby2
lda #2
// [1] (byte~) $1 ← (byte) i#2 + (byte) 4 [ i#2 $1 ] // zpby1=zpby2_plus_coby1
lda 2
clc
adc 2
adc #4
sta 3
// [2] (byte~) $1 ← (byte~) $0 + (byte) 2 [ i#2 $1 ] // zpby1=zpby1_plus_coby1
lda 3
clc
adc #2
sta 3
// [3] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ] // ptr_cowo1_zpby1=zpby2
// [2] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ] // ptr_cowo1_zpby1=zpby2
lda 3
ldy 2
sta 4352,y
// [4] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ] // zpby1=zpby1_plus_1
// [3] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ] // zpby1=zpby1_plus_1
inc 2
// [5] if((byte) i#1<(byte) 10) goto @1 [ i#1 ] // zpby1_lt_coby1_then_la1
// [4] if((byte) i#1<(byte) 10) goto @1 [ i#1 ] // zpby1_lt_coby1_then_la1
lda 2
cmp #10
bcc B1_from_B1
BEND:
FINAL SYMBOL TABLE
(byte~) $0 zp byte:3 22.0
(byte~) $1 zp byte:3 22.0
(label) @1
(label) @BEGIN
(label) @END
(byte) i
(byte) i#1 zp byte:2 16.5
(byte) i#2 zp byte:2 11.0
(byte) i#2 zp byte:2 14.666666666666666
(byte[16]) p
zp byte:2 [ i#2 i#1 ]
zp byte:3 [ $0 $1 ]
zp byte:3 [ $1 ]
FINAL CODE
BBEGIN:
@ -430,23 +422,18 @@ B1_from_BBEGIN:
B1_from_B1:
// (byte) i#2 = (byte) i#1 // register copy zp byte:2
B1:
// [1] (byte~) $0 ← (byte) 2 + (byte) i#2 [ i#2 $0 ] // zpby1=coby1_plus_zpby2
lda #2
// [1] (byte~) $1 ← (byte) i#2 + (byte) 4 [ i#2 $1 ] // zpby1=zpby2_plus_coby1
lda 2
clc
adc 2
adc #4
sta 3
// [2] (byte~) $1 ← (byte~) $0 + (byte) 2 [ i#2 $1 ] // zpby1=zpby1_plus_coby1
lda 3
clc
adc #2
sta 3
// [3] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ] // ptr_cowo1_zpby1=zpby2
// [2] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ] // ptr_cowo1_zpby1=zpby2
lda 3
ldy 2
sta 4352,y
// [4] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ] // zpby1=zpby1_plus_1
// [3] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ] // zpby1=zpby1_plus_1
inc 2
// [5] if((byte) i#1<(byte) 10) goto @1 [ i#1 ] // zpby1_lt_coby1_then_la1
// [4] if((byte) i#1<(byte) 10) goto @1 [ i#1 ] // zpby1_lt_coby1_then_la1
lda 2
cmp #10
bcc B1_from_B1

View File

@ -1,12 +1,11 @@
(byte~) $0 zp byte:3 22.0
(byte~) $1 zp byte:3 22.0
(label) @1
(label) @BEGIN
(label) @END
(byte) i
(byte) i#1 zp byte:2 16.5
(byte) i#2 zp byte:2 11.0
(byte) i#2 zp byte:2 14.666666666666666
(byte[16]) p
zp byte:2 [ i#2 i#1 ]
zp byte:3 [ $0 $1 ]
zp byte:3 [ $1 ]