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

Finally got a hold of live ranges when propagating back over calls.

This commit is contained in:
jespergravgaard 2017-08-12 02:30:37 +02:00
parent 9334e435da
commit 7555d45b34
12 changed files with 792 additions and 369 deletions

View File

@ -31,8 +31,8 @@ Assembler Improvements
- Optimize by allowing resequencing of ASM (statements and phi assignments) in a final phase.
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.
- Alive vars are propagated backward through procedures (correctly). However they are then propagated back through ALL calls to the procedure incorrectly. They should only be alive at calls where they are alive after the call. In summin.kc s1#0 is incirrectly backpropagated through the first call, where it is not alive.
+ 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.
+ Alive vars are propagated backward through procedures (correctly). However they are then propagated back through ALL calls to the procedure incorrectly. They should only be alive at calls where they are alive after the call. In summin.kc s1#0 is incirrectly backpropagated through the first call, where it is not alive.
Register Allocation
- Allow user to limit number of combinations tested

View File

@ -138,14 +138,14 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
ControlFlowBlock predecessor = program.getGraph().getBlock(predecessorRef);
List<Statement> predecessorStatements = predecessor.getStatements();
// Is this block a procedure called from the predecessor?
if(currentBlock.getLabel().equals(predecessor.getCallSuccessor())) {
if (currentBlock.getLabel().equals(predecessor.getCallSuccessor())) {
// Add to last statement before call in predecessor
StatementCall callStatement = (StatementCall) predecessorStatements.get(predecessorStatements.size() - 1);
if(predecessorStatements.size()>1) {
if (predecessorStatements.size() > 1) {
Statement predecessorLastStatementBeforeCall = predecessorStatements.get(predecessorStatements.size() - 2);
liveRanges.addAlive((VariableRef) phiRValue.getrValue(), predecessorLastStatementBeforeCall);
}
} else {
} else {
// Add to last statement of predecessor
Statement predecessorLastStatement = predecessorStatements.get(predecessorStatements.size() - 1);
liveRanges.addAlive((VariableRef) phiRValue.getrValue(), predecessorLastStatement);
@ -271,7 +271,80 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
* @param previous The previous statement
* @param defined The lValues assigned in the current statement (will not be propagated)
*/
private void propagate(Statement statement, List<Statement> previous, List<? extends LValue> defined) {
private void propagate(Statement statement, List<PreviousStatement> previous, List<? extends LValue> defined) {
List<VariableRef> alive = getAliveNotDefined(statement, defined);
// Add all non-defined alive vars to all previous statement
for (VariableRef var : alive) {
for (PreviousStatement prev : previous) {
if(prev.isCaller()) {
// Special handling of propagation back to calls
// Only propagate vars also alive on the call itself
// And propagate them back to the statement prior to the call itself
StatementCall call = (StatementCall) prev.getStatement();
List<VariableRef> callAlive = liveRanges.getAlive(call);
if (callAlive.contains(var)) {
ControlFlowBlock callBlock = program.getGraph().getBlockFromStatementIdx(call.getIndex());
List<Statement> callBlockStatements = callBlock.getStatements();
Statement lastBeforeCall = callBlockStatements.get(callBlockStatements.size() - 2);
modified |= liveRanges.addAlive(var, lastBeforeCall);
program.getLog().append("Propagated " + var + " through call " + call);
}
} else {
modified |= liveRanges.addAlive(var, prev.getStatement());
}
}
}
ensureDefined(defined);
}
/**
* Propagate live ranges back from a pricedure to the statements previous to the call og the procedure.
* <p>
* Only variables also alive after the call are propagated further backward.
*
* @param procBlock The block starting the procedure
* @param phi The phi statement at the start of the current block
* @param defined The variables defined by the phi statement
*/
private void propagateCall(ControlFlowBlock procBlock, StatementPhiBlock phi, List<VariableRef> defined) {
List<VariableRef> alive = getAliveNotDefined(phi, defined);
if (alive.size() > 0) {
// Go back through each call
for (ControlFlowBlock predecessor : program.getGraph().getPredecessors(procBlock)) {
// If this block is a procedure called from the predecessor - the last statement is the one before the call
if (procBlock.getLabel().equals(predecessor.getCallSuccessor())) {
List<Statement> predecessorStatements = predecessor.getStatements();
StatementCall call = (StatementCall) predecessorStatements.get(predecessorStatements.size() - 1);
if (predecessorStatements.size() > 1) {
Statement lastBeforeCall = predecessorStatements.get(predecessorStatements.size() - 2);
List<VariableRef> callAlive = liveRanges.getAlive(call);
// Add all non-defined alive vars to all previous statement
for (VariableRef var : alive) {
// Only add the variables that are alive on the actual call (and thereby used after the call)
if (callAlive.contains(var)) {
modified |= liveRanges.addAlive(var, lastBeforeCall);
program.getLog().append("Propagated " + var + " through call " + call);
}
}
}
}
}
}
ensureDefined(defined);
}
/**
* Get the variables that are alive at a specific statemtn and not defined by the statement itself
*
* @param statement The statement
* @param defined The variables defined by the statement
* @return
*/
private List<VariableRef> getAliveNotDefined(Statement statement, List<? extends LValue> defined) {
List<VariableRef> alive = liveRanges.getAlive(statement);
if (defined != null) {
for (LValue lValue : defined) {
@ -281,37 +354,56 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
}
}
}
// Add all non-defined alive vars to all previous statement
for (VariableRef var : alive) {
for (Statement prev : previous) {
modified |= liveRanges.addAlive(var, prev);
}
}
return alive;
}
// If any lValues do not have a live range (they are never used) - create an empty live range for them
/**
* If any lValues do not have a live range (they are never used) - create an empty live range for them
*/
private void ensureDefined(List<? extends LValue> defined) {
if (defined != null) {
for (LValue lValue : defined) {
if(lValue instanceof VariableRef) {
if (lValue instanceof VariableRef) {
LiveRange lValLiveRange = liveRanges.getLiveRange((VariableRef) lValue);
if(lValLiveRange==null) {
liveRanges.addEmptyAlive((VariableRef)lValue);
program.getLog().append("Adding empty live range for unused variable "+lValue);
if (lValLiveRange == null) {
liveRanges.addEmptyAlive((VariableRef) lValue);
program.getLog().append("Adding empty live range for unused variable " + lValue);
}
}
}
}
}
private List<Statement> getPreviousStatements() {
private static class PreviousStatement {
/** The statement */
private Statement statement;
/** true if the statement is in a block that is a caller of the current block. false if the statement is a direct predecessor statement. */
private boolean caller;
public PreviousStatement(Statement statement, boolean caller) {
this.statement = statement;
this.caller = caller;
}
public Statement getStatement() {
return statement;
}
public boolean isCaller() {
return caller;
}
}
private List<PreviousStatement> getPreviousStatements() {
if (previousStatement != null) {
// Inside a block
return Arrays.asList(previousStatement);
return Arrays.asList(new PreviousStatement(previousStatement, false));
} else {
// At start of block - add last statement of all previous blocks
return getPreviousStatements(this.currentBlock);
return getPreviousStatements(this.currentBlock, false);
}
}
@ -322,22 +414,13 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
* @return The statement executed just before entering the block.
* If there are several predecessor blocks multiple statements are returned.
*/
private ArrayList<Statement> getPreviousStatements(ControlFlowBlock block) {
ArrayList<Statement> statements = new ArrayList<>();
private ArrayList<PreviousStatement> getPreviousStatements(ControlFlowBlock block, boolean isCaller) {
ArrayList<PreviousStatement> statements = new ArrayList<>();
List<ControlFlowBlock> predecessors = program.getGraph().getPredecessors(block);
for (ControlFlowBlock predecessor : predecessors) {
// If this block is a procedure called from the predecessor - the last statement is the one before the call
if(block.getLabel().equals(predecessor.getCallSuccessor())) {
List<Statement> predecessorStatements = predecessor.getStatements();
StatementCall call = (StatementCall) predecessorStatements.get(predecessorStatements.size() - 1);
if(predecessorStatements.size()>1) {
Statement lastBeforeCall = predecessorStatements.get(predecessorStatements.size() - 2);
statements.add(lastBeforeCall);
}
} else {
ArrayList<Statement> lastStatements = getLastStatements(predecessor);
statements.addAll(lastStatements);
}
boolean isSubCaller = block.getLabel().equals(predecessor.getCallSuccessor());
ArrayList<PreviousStatement> lastStatements = getLastStatements(predecessor, isCaller||isSubCaller);
statements.addAll(lastStatements);
}
return statements;
}
@ -347,18 +430,19 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
* If the block is empty the last statement of the previous block is returned.
*
* @param block The block to examine
* @param isCaller true if this block is a caller of the block we are finding previous statements for
* @return The last statement of the block (or the last statement of previous blocks if the block is empty)
*/
private ArrayList<Statement> getLastStatements(ControlFlowBlock block) {
ArrayList<Statement> statements = new ArrayList<>();
private ArrayList<PreviousStatement> getLastStatements(ControlFlowBlock block, boolean isCaller) {
ArrayList<PreviousStatement> statements = new ArrayList<>();
List<Statement> blockStatements = block.getStatements();
if (blockStatements.size() == 0) {
// Block has no statements - go further back!
statements.addAll(getPreviousStatements(block));
statements.addAll(getPreviousStatements(block, isCaller));
} else {
// Add last statement from block
Statement predecessorLastStatement = blockStatements.get(blockStatements.size() - 1);
statements.add(predecessorLastStatement);
statements.add(new PreviousStatement(predecessorLastStatement, isCaller));
}
return statements;
}
@ -381,7 +465,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
ProcedureRef procedure = call.getProcedure();
LabelRef procedureReturnBlock = procedure.getReturnBlock();
ControlFlowBlock returnBlock = program.getGraph().getBlock(procedureReturnBlock);
propagate(call, getLastStatements(returnBlock), null);
propagate(call, getLastStatements(returnBlock, false), null);
return null;
}

View File

@ -598,7 +598,9 @@ Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagated main::i#2 through call [2] call nest param-assignment
Propagating live ranges...
Propagated main::i#2 through call [2] call nest param-assignment
Propagating live ranges...
CONTROL FLOW GRAPH - LIVE RANGES
@BEGIN: from
@ -647,7 +649,9 @@ Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagated main::i#2 through call [2] call nest param-assignment
Propagating live ranges...
Propagated main::i#2 through call [2] call nest param-assignment
Propagating live ranges...
CONTROL FLOW GRAPH - PHI MEM COALESCED
@BEGIN: from

View File

@ -1543,17 +1543,59 @@ Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagated nest1::j#2 through call [13] call nest2 param-assignment
Propagating live ranges...
Propagated nest1::j#2 through call [13] call nest2 param-assignment
Propagating live ranges...
Propagated nest1::j#2 through call [13] call nest2 param-assignment
Propagated nest1::i#2 through call [13] call nest2 param-assignment
Propagating live ranges...
Propagated nest1::j#2 through call [13] call nest2 param-assignment
Propagated nest1::i#2 through call [13] call nest2 param-assignment
Propagating live ranges...
Propagated nest1::j#2 through call [13] call nest2 param-assignment
Propagated nest1::i#2 through call [13] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [13] call nest2 param-assignment
Propagated nest1::j#2 through call [13] call nest2 param-assignment
Propagated nest1::i#2 through call [13] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [13] call nest2 param-assignment
Propagated nest1::j#2 through call [13] call nest2 param-assignment
Propagated nest1::i#2 through call [13] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [3] call nest1 param-assignment
Propagated main::j#2 through call [13] call nest2 param-assignment
Propagated main::i#2 through call [13] call nest2 param-assignment
Propagated nest1::j#2 through call [13] call nest2 param-assignment
Propagated nest1::i#2 through call [13] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [3] call nest1 param-assignment
Propagated main::j#2 through call [13] call nest2 param-assignment
Propagated main::i#2 through call [13] call nest2 param-assignment
Propagated nest1::j#2 through call [13] call nest2 param-assignment
Propagated nest1::i#2 through call [13] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [3] call nest1 param-assignment
Propagated main::i#2 through call [3] call nest1 param-assignment
Propagated main::j#2 through call [13] call nest2 param-assignment
Propagated main::i#2 through call [13] call nest2 param-assignment
Propagated nest1::j#2 through call [13] call nest2 param-assignment
Propagated nest1::i#2 through call [13] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [3] call nest1 param-assignment
Propagated main::i#2 through call [3] call nest1 param-assignment
Propagated main::j#2 through call [13] call nest2 param-assignment
Propagated main::i#2 through call [13] call nest2 param-assignment
Propagated nest1::j#2 through call [13] call nest2 param-assignment
Propagated nest1::i#2 through call [13] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [3] call nest1 param-assignment
Propagated main::i#2 through call [3] call nest1 param-assignment
Propagated main::j#2 through call [13] call nest2 param-assignment
Propagated main::i#2 through call [13] call nest2 param-assignment
Propagated nest1::j#2 through call [13] call nest2 param-assignment
Propagated nest1::i#2 through call [13] call nest2 param-assignment
Propagating live ranges...
CONTROL FLOW GRAPH - LIVE RANGES
@BEGIN: from
@ -1659,17 +1701,59 @@ Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagated nest1::j#2 through call [11] call nest2 param-assignment
Propagating live ranges...
Propagated nest1::j#2 through call [11] call nest2 param-assignment
Propagating live ranges...
Propagated nest1::j#2 through call [11] call nest2 param-assignment
Propagated nest1::i#2 through call [11] call nest2 param-assignment
Propagating live ranges...
Propagated nest1::j#2 through call [11] call nest2 param-assignment
Propagated nest1::i#2 through call [11] call nest2 param-assignment
Propagating live ranges...
Propagated nest1::j#2 through call [11] call nest2 param-assignment
Propagated nest1::i#2 through call [11] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [11] call nest2 param-assignment
Propagated nest1::j#2 through call [11] call nest2 param-assignment
Propagated nest1::i#2 through call [11] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [11] call nest2 param-assignment
Propagated nest1::j#2 through call [11] call nest2 param-assignment
Propagated nest1::i#2 through call [11] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [3] call nest1 param-assignment
Propagated main::j#2 through call [11] call nest2 param-assignment
Propagated main::i#2 through call [11] call nest2 param-assignment
Propagated nest1::j#2 through call [11] call nest2 param-assignment
Propagated nest1::i#2 through call [11] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [3] call nest1 param-assignment
Propagated main::j#2 through call [11] call nest2 param-assignment
Propagated main::i#2 through call [11] call nest2 param-assignment
Propagated nest1::j#2 through call [11] call nest2 param-assignment
Propagated nest1::i#2 through call [11] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [3] call nest1 param-assignment
Propagated main::i#2 through call [3] call nest1 param-assignment
Propagated main::j#2 through call [11] call nest2 param-assignment
Propagated main::i#2 through call [11] call nest2 param-assignment
Propagated nest1::j#2 through call [11] call nest2 param-assignment
Propagated nest1::i#2 through call [11] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [3] call nest1 param-assignment
Propagated main::i#2 through call [3] call nest1 param-assignment
Propagated main::j#2 through call [11] call nest2 param-assignment
Propagated main::i#2 through call [11] call nest2 param-assignment
Propagated nest1::j#2 through call [11] call nest2 param-assignment
Propagated nest1::i#2 through call [11] call nest2 param-assignment
Propagating live ranges...
Propagated main::j#2 through call [3] call nest1 param-assignment
Propagated main::i#2 through call [3] call nest1 param-assignment
Propagated main::j#2 through call [11] call nest2 param-assignment
Propagated main::i#2 through call [11] call nest2 param-assignment
Propagated nest1::j#2 through call [11] call nest2 param-assignment
Propagated nest1::i#2 through call [11] call nest2 param-assignment
Propagating live ranges...
CONTROL FLOW GRAPH - PHI MEM COALESCED
@BEGIN: from

View File

@ -1,20 +1,30 @@
BBEGIN:
sum_from_BBEGIN:
lda #2
ldx #1
ldy #1
jsr sum
B2:
sta 2
sum_from_B2:
lda #13
ldx #9
lda #4
ldy #3
jsr sum
B3:
tax
sum_from_B3:
lda #13
ldy #9
jsr sum
B4:
sta 3
txa
clc
adc 2
clc
adc 3
BEND:
sum:
stx 255
sty 255
clc
adc 255
sum__Breturn:

View File

@ -7,14 +7,19 @@
to:@3
@3: from @2
[3] (byte) s2#0 ← (byte) sum::return#0 [ s1#0 s2#0 ]
[4] (byte) s3#0 ← (byte) s1#0 + (byte) s2#0 [ ]
[4] call sum param-assignment [ sum::return#0 s1#0 s2#0 ]
to:@4
@4: from @3
[5] (byte) s3#0 ← (byte) sum::return#0 [ s1#0 s2#0 s3#0 ]
[6] (byte~) $3 ← (byte) s1#0 + (byte) s2#0 [ $3 s3#0 ]
[7] (byte) s4#0 ← (byte~) $3 + (byte) s3#0 [ ]
to:@END
@END: from @3
sum: from @2 @BEGIN
[5] (byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 ) [ s1#0 sum::a#2 sum::b#2 ]
[5] (byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 ) [ s1#0 sum::a#2 sum::b#2 ]
[6] (byte) sum::return#0 ← (byte) sum::a#2 + (byte) sum::b#2 [ sum::return#0 s1#0 ]
@END: from @4
sum: from @2 @3 @BEGIN
[8] (byte) sum::b#3 ← phi( @2/(byte) 4 @3/(byte) 13 @BEGIN/(byte) 2 ) [ s1#0 s2#0 sum::a#3 sum::b#3 ]
[8] (byte) sum::a#3 ← phi( @2/(byte) 3 @3/(byte) 9 @BEGIN/(byte) 1 ) [ s1#0 s2#0 sum::a#3 sum::b#3 ]
[9] (byte) sum::return#0 ← (byte) sum::a#3 + (byte) sum::b#3 [ sum::return#0 s1#0 s2#0 ]
to:sum::@return
sum::@return: from sum
[7] return [ sum::return#0 s1#0 ]
[10] return [ sum::return#0 s1#0 s2#0 ]
to:@RETURN

View File

@ -1,6 +1,7 @@
byte s1=sum(1,2);
byte s2=sum(9,13);
byte s3=s1+s2;
byte s2=sum(3,4);
byte s3=sum(9,13);
byte s4=s1+s2+s3;
byte sum(byte a, byte b) {
return a+b;
}
@ -8,10 +9,13 @@ byte sum(byte a, byte b) {
PROGRAM
(byte~) $0 ← call sum (byte) 1 (byte) 2
(byte) s1 ← (byte~) $0
(byte~) $1 ← call sum (byte) 9 (byte) 13
(byte~) $1 ← call sum (byte) 3 (byte) 4
(byte) s2 ← (byte~) $1
(byte~) $2 ← (byte) s1 + (byte) s2
(byte~) $2 ← call sum (byte) 9 (byte) 13
(byte) s3 ← (byte~) $2
(byte~) $3 ← (byte) s1 + (byte) s2
(byte~) $4 ← (byte~) $3 + (byte) s3
(byte) s4 ← (byte~) $4
proc (byte()) sum((byte) sum::a , (byte) sum::b)
(byte~) sum::$0 ← (byte) sum::a + (byte) sum::b
(byte) sum::return ← (byte~) sum::$0
@ -25,9 +29,12 @@ SYMBOLS
(byte~) $0
(byte~) $1
(byte~) $2
(byte~) $3
(byte~) $4
(byte) s1
(byte) s2
(byte) s3
(byte) s4
(byte()) sum((byte) sum::a , (byte) sum::b)
(byte~) sum::$0
(label) sum::@return
@ -39,10 +46,13 @@ INITIAL CONTROL FLOW GRAPH
@BEGIN: from
(byte~) $0 ← call sum (byte) 1 (byte) 2
(byte) s1 ← (byte~) $0
(byte~) $1 ← call sum (byte) 9 (byte) 13
(byte~) $1 ← call sum (byte) 3 (byte) 4
(byte) s2 ← (byte~) $1
(byte~) $2 ← (byte) s1 + (byte) s2
(byte~) $2 ← call sum (byte) 9 (byte) 13
(byte) s3 ← (byte~) $2
(byte~) $3 ← (byte) s1 + (byte) s2
(byte~) $4 ← (byte~) $3 + (byte) s3
(byte) s4 ← (byte~) $4
to:@1
sum: from
(byte~) sum::$0 ← (byte) sum::a + (byte) sum::b
@ -64,10 +74,13 @@ CONTROL FLOW GRAPH
@BEGIN: from
(byte~) $0 ← call sum (byte) 1 (byte) 2
(byte) s1 ← (byte~) $0
(byte~) $1 ← call sum (byte) 9 (byte) 13
(byte~) $1 ← call sum (byte) 3 (byte) 4
(byte) s2 ← (byte~) $1
(byte~) $2 ← (byte) s1 + (byte) s2
(byte~) $2 ← call sum (byte) 9 (byte) 13
(byte) s3 ← (byte~) $2
(byte~) $3 ← (byte) s1 + (byte) s2
(byte~) $4 ← (byte~) $3 + (byte) s3
(byte) s4 ← (byte~) $4
to:@END
sum: from
(byte~) sum::$0 ← (byte) sum::a + (byte) sum::b
@ -90,17 +103,25 @@ CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@2: from @BEGIN
(byte~) $0 ← (byte) sum::return
(byte) s1 ← (byte~) $0
(byte) sum::a ← (byte) 9
(byte) sum::b ← (byte) 13
(byte) sum::a ← (byte) 3
(byte) sum::b ← (byte) 4
(byte) sum::return ← call sum param-assignment
to:@3
@3: from @2
(byte~) $1 ← (byte) sum::return
(byte) s2 ← (byte~) $1
(byte~) $2 ← (byte) s1 + (byte) s2
(byte) sum::a ← (byte) 9
(byte) sum::b ← (byte) 13
(byte) sum::return ← call sum param-assignment
to:@4
@4: from @3
(byte~) $2 ← (byte) sum::return
(byte) s3 ← (byte~) $2
(byte~) $3 ← (byte) s1 + (byte) s2
(byte~) $4 ← (byte~) $3 + (byte) s3
(byte) s4 ← (byte~) $4
to:@END
sum: from @2 @BEGIN
sum: from @2 @3 @BEGIN
(byte~) sum::$0 ← (byte) sum::a + (byte) sum::b
(byte) sum::return ← (byte~) sum::$0
to:sum::@return
@ -108,8 +129,9 @@ sum::@return: from sum
(byte) sum::return ← (byte) sum::return
return (byte) sum::return
to:@RETURN
@END: from @3
@END: from @4
Completing Phi functions...
Completing Phi functions...
CONTROL FLOW GRAPH SSA
@BEGIN: from
@ -118,115 +140,152 @@ CONTROL FLOW GRAPH SSA
(byte) sum::return#0 ← call sum param-assignment
to:@2
@2: from @BEGIN
(byte) sum::return#4 ← phi( @BEGIN/(byte) sum::return#0 )
(byte~) $0 ← (byte) sum::return#4
(byte) sum::return#5 ← phi( @BEGIN/(byte) sum::return#0 )
(byte~) $0 ← (byte) sum::return#5
(byte) s1#0 ← (byte~) $0
(byte) sum::a#1 ← (byte) 9
(byte) sum::b#1 ← (byte) 13
(byte) sum::a#1 ← (byte) 3
(byte) sum::b#1 ← (byte) 4
(byte) sum::return#1 ← call sum param-assignment
to:@3
@3: from @2
(byte) s1#1 ← phi( @2/(byte) s1#0 )
(byte) sum::return#5 ← phi( @2/(byte) sum::return#1 )
(byte~) $1 ← (byte) sum::return#5
(byte) s1#2 ← phi( @2/(byte) s1#0 )
(byte) sum::return#6 ← phi( @2/(byte) sum::return#1 )
(byte~) $1 ← (byte) sum::return#6
(byte) s2#0 ← (byte~) $1
(byte~) $2 ← (byte) s1#1 + (byte) s2#0
(byte) sum::a#2 ← (byte) 9
(byte) sum::b#2 ← (byte) 13
(byte) sum::return#2 ← call sum param-assignment
to:@4
@4: from @3
(byte) s2#1 ← phi( @3/(byte) s2#0 )
(byte) s1#1 ← phi( @3/(byte) s1#2 )
(byte) sum::return#7 ← phi( @3/(byte) sum::return#2 )
(byte~) $2 ← (byte) sum::return#7
(byte) s3#0 ← (byte~) $2
(byte~) $3 ← (byte) s1#1 + (byte) s2#1
(byte~) $4 ← (byte~) $3 + (byte) s3#0
(byte) s4#0 ← (byte~) $4
to:@END
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) sum::b#1 @BEGIN/(byte) sum::b#0 )
(byte) sum::a#2 ← phi( @2/(byte) sum::a#1 @BEGIN/(byte) sum::a#0 )
(byte~) sum::$0 ← (byte) sum::a#2 + (byte) sum::b#2
(byte) sum::return#2 ← (byte~) sum::$0
sum: from @2 @3 @BEGIN
(byte) sum::b#3 ← phi( @2/(byte) sum::b#1 @3/(byte) sum::b#2 @BEGIN/(byte) sum::b#0 )
(byte) sum::a#3 ← phi( @2/(byte) sum::a#1 @3/(byte) sum::a#2 @BEGIN/(byte) sum::a#0 )
(byte~) sum::$0 ← (byte) sum::a#3 + (byte) sum::b#3
(byte) sum::return#3 ← (byte~) sum::$0
to:sum::@return
sum::@return: from sum
(byte) sum::return#6 ← phi( sum/(byte) sum::return#2 )
(byte) sum::return#3 ← (byte) sum::return#6
return (byte) sum::return#3
(byte) sum::return#8 ← phi( sum/(byte) sum::return#3 )
(byte) sum::return#4 ← (byte) sum::return#8
return (byte) sum::return#4
to:@RETURN
@END: from @3
@END: from @4
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
@BEGIN: from
(byte) sum::a#0 ← (byte) 1
(byte) sum::b#0 ← (byte) 2
call sum param-assignment
(byte) sum::return#0 ← (byte) sum::return#3
(byte) sum::return#0 ← (byte) sum::return#4
to:@2
@2: from @BEGIN
(byte) sum::return#4 ← phi( @BEGIN/(byte) sum::return#0 )
(byte~) $0 ← (byte) sum::return#4
(byte) sum::return#5 ← phi( @BEGIN/(byte) sum::return#0 )
(byte~) $0 ← (byte) sum::return#5
(byte) s1#0 ← (byte~) $0
(byte) sum::a#1 ← (byte) 9
(byte) sum::b#1 ← (byte) 13
(byte) sum::a#1 ← (byte) 3
(byte) sum::b#1 ← (byte) 4
call sum param-assignment
(byte) sum::return#1 ← (byte) sum::return#3
(byte) sum::return#1 ← (byte) sum::return#4
to:@3
@3: from @2
(byte) s1#1 ← phi( @2/(byte) s1#0 )
(byte) sum::return#5 ← phi( @2/(byte) sum::return#1 )
(byte~) $1 ← (byte) sum::return#5
(byte) s1#2 ← phi( @2/(byte) s1#0 )
(byte) sum::return#6 ← phi( @2/(byte) sum::return#1 )
(byte~) $1 ← (byte) sum::return#6
(byte) s2#0 ← (byte~) $1
(byte~) $2 ← (byte) s1#1 + (byte) s2#0
(byte) sum::a#2 ← (byte) 9
(byte) sum::b#2 ← (byte) 13
call sum param-assignment
(byte) sum::return#2 ← (byte) sum::return#4
to:@4
@4: from @3
(byte) s2#1 ← phi( @3/(byte) s2#0 )
(byte) s1#1 ← phi( @3/(byte) s1#2 )
(byte) sum::return#7 ← phi( @3/(byte) sum::return#2 )
(byte~) $2 ← (byte) sum::return#7
(byte) s3#0 ← (byte~) $2
(byte~) $3 ← (byte) s1#1 + (byte) s2#1
(byte~) $4 ← (byte~) $3 + (byte) s3#0
(byte) s4#0 ← (byte~) $4
to:@END
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) sum::b#1 @BEGIN/(byte) sum::b#0 )
(byte) sum::a#2 ← phi( @2/(byte) sum::a#1 @BEGIN/(byte) sum::a#0 )
(byte~) sum::$0 ← (byte) sum::a#2 + (byte) sum::b#2
(byte) sum::return#2 ← (byte~) sum::$0
sum: from @2 @3 @BEGIN
(byte) sum::b#3 ← phi( @2/(byte) sum::b#1 @3/(byte) sum::b#2 @BEGIN/(byte) sum::b#0 )
(byte) sum::a#3 ← phi( @2/(byte) sum::a#1 @3/(byte) sum::a#2 @BEGIN/(byte) sum::a#0 )
(byte~) sum::$0 ← (byte) sum::a#3 + (byte) sum::b#3
(byte) sum::return#3 ← (byte~) sum::$0
to:sum::@return
sum::@return: from sum
(byte) sum::return#6 ← phi( sum/(byte) sum::return#2 )
(byte) sum::return#3 ← (byte) sum::return#6
(byte) sum::return#8 ← phi( sum/(byte) sum::return#3 )
(byte) sum::return#4 ← (byte) sum::return#8
return
to:@RETURN
@END: from @3
@END: from @4
Constant (byte) sum::a#0 (byte) 1
Constant (byte) sum::b#0 (byte) 2
Constant (byte) sum::a#1 (byte) 9
Constant (byte) sum::b#1 (byte) 13
Constant (byte) sum::a#1 (byte) 3
Constant (byte) sum::b#1 (byte) 4
Constant (byte) sum::a#2 (byte) 9
Constant (byte) sum::b#2 (byte) 13
Succesful SSA optimization Pass2ConstantPropagation
CONTROL FLOW GRAPH
@BEGIN: from
call sum param-assignment
(byte) sum::return#0 ← (byte) sum::return#3
(byte) sum::return#0 ← (byte) sum::return#4
to:@2
@2: from @BEGIN
(byte) sum::return#4 ← phi( @BEGIN/(byte) sum::return#0 )
(byte~) $0 ← (byte) sum::return#4
(byte) sum::return#5 ← phi( @BEGIN/(byte) sum::return#0 )
(byte~) $0 ← (byte) sum::return#5
(byte) s1#0 ← (byte~) $0
call sum param-assignment
(byte) sum::return#1 ← (byte) sum::return#3
(byte) sum::return#1 ← (byte) sum::return#4
to:@3
@3: from @2
(byte) s1#1 ← phi( @2/(byte) s1#0 )
(byte) sum::return#5 ← phi( @2/(byte) sum::return#1 )
(byte~) $1 ← (byte) sum::return#5
(byte) s1#2 ← phi( @2/(byte) s1#0 )
(byte) sum::return#6 ← phi( @2/(byte) sum::return#1 )
(byte~) $1 ← (byte) sum::return#6
(byte) s2#0 ← (byte~) $1
(byte~) $2 ← (byte) s1#1 + (byte) s2#0
call sum param-assignment
(byte) sum::return#2 ← (byte) sum::return#4
to:@4
@4: from @3
(byte) s2#1 ← phi( @3/(byte) s2#0 )
(byte) s1#1 ← phi( @3/(byte) s1#2 )
(byte) sum::return#7 ← phi( @3/(byte) sum::return#2 )
(byte~) $2 ← (byte) sum::return#7
(byte) s3#0 ← (byte~) $2
(byte~) $3 ← (byte) s1#1 + (byte) s2#1
(byte~) $4 ← (byte~) $3 + (byte) s3#0
(byte) s4#0 ← (byte~) $4
to:@END
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 )
(byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 )
(byte~) sum::$0 ← (byte) sum::a#2 + (byte) sum::b#2
(byte) sum::return#2 ← (byte~) sum::$0
sum: from @2 @3 @BEGIN
(byte) sum::b#3 ← phi( @2/(byte) 4 @3/(byte) 13 @BEGIN/(byte) 2 )
(byte) sum::a#3 ← phi( @2/(byte) 3 @3/(byte) 9 @BEGIN/(byte) 1 )
(byte~) sum::$0 ← (byte) sum::a#3 + (byte) sum::b#3
(byte) sum::return#3 ← (byte~) sum::$0
to:sum::@return
sum::@return: from sum
(byte) sum::return#6 ← phi( sum/(byte) sum::return#2 )
(byte) sum::return#3 ← (byte) sum::return#6
(byte) sum::return#8 ← phi( sum/(byte) sum::return#3 )
(byte) sum::return#4 ← (byte) sum::return#8
return
to:@RETURN
@END: from @3
@END: from @4
Not aliassing across scopes: $0 sum::return#4
Not aliassing across scopes: $1 sum::return#5
Alias (byte) sum::return#0 = (byte) sum::return#3 (byte) sum::return#4 (byte) sum::return#1 (byte) sum::return#5 (byte) sum::return#2 (byte~) sum::$0 (byte) sum::return#6
Alias (byte) s1#0 = (byte~) $0 (byte) s1#1
Alias (byte) s2#0 = (byte~) $1
Not aliassing across scopes: $0 sum::return#5
Not aliassing across scopes: $1 sum::return#6
Not aliassing across scopes: $2 sum::return#7
Alias (byte) sum::return#0 = (byte) sum::return#4 (byte) sum::return#5 (byte) sum::return#1 (byte) sum::return#6 (byte) sum::return#2 (byte) sum::return#7 (byte) sum::return#3 (byte~) sum::$0 (byte) sum::return#8
Alias (byte) s1#0 = (byte~) $0 (byte) s1#2 (byte) s1#1
Alias (byte) s2#0 = (byte~) $1 (byte) s2#1
Alias (byte) s3#0 = (byte~) $2
Alias (byte) s4#0 = (byte~) $4
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@BEGIN: from
@ -238,22 +297,28 @@ CONTROL FLOW GRAPH
to:@3
@3: from @2
(byte) s2#0 ← (byte) sum::return#0
(byte) s3#0 ← (byte) s1#0 + (byte) s2#0
call sum param-assignment
to:@4
@4: from @3
(byte) s3#0 ← (byte) sum::return#0
(byte~) $3 ← (byte) s1#0 + (byte) s2#0
(byte) s4#0 ← (byte~) $3 + (byte) s3#0
to:@END
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 )
(byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 )
(byte) sum::return#0 ← (byte) sum::a#2 + (byte) sum::b#2
sum: from @2 @3 @BEGIN
(byte) sum::b#3 ← phi( @2/(byte) 4 @3/(byte) 13 @BEGIN/(byte) 2 )
(byte) sum::a#3 ← phi( @2/(byte) 3 @3/(byte) 9 @BEGIN/(byte) 1 )
(byte) sum::return#0 ← (byte) sum::a#3 + (byte) sum::b#3
to:sum::@return
sum::@return: from sum
return
to:@RETURN
@END: from @3
@END: from @4
Not aliassing across scopes: s1#0 sum::return#0
Not aliassing across scopes: s2#0 sum::return#0
Block Sequence Planned @BEGIN @2 @3 @END sum sum::@return
Block Sequence Planned @BEGIN @2 @3 @END sum sum::@return
Not aliassing across scopes: s3#0 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
@BEGIN: from
call sum param-assignment
@ -264,23 +329,37 @@ CONTROL FLOW GRAPH - PHI LIFTED
to:@3
@3: from @2
(byte) s2#0 ← (byte) sum::return#0
(byte) s3#0 ← (byte) s1#0 + (byte) s2#0
call sum param-assignment
to:@4
@4: from @3
(byte) s3#0 ← (byte) sum::return#0
(byte~) $3 ← (byte) s1#0 + (byte) s2#0
(byte) s4#0 ← (byte~) $3 + (byte) s3#0
to:@END
@END: from @3
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 )
(byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 )
(byte) sum::return#0 ← (byte) sum::a#2 + (byte) sum::b#2
@END: from @4
sum: from @2 @3 @BEGIN
(byte) sum::b#3 ← phi( @2/(byte) 4 @3/(byte) 13 @BEGIN/(byte) 2 )
(byte) sum::a#3 ← phi( @2/(byte) 3 @3/(byte) 9 @BEGIN/(byte) 1 )
(byte) sum::return#0 ← (byte) sum::a#3 + (byte) sum::b#3
to:sum::@return
sum::@return: from sum
return
to:@RETURN
Adding empty live range for unused variable s3#0
Adding empty live range for unused variable s4#0
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagated s1#0 through call [4] call sum param-assignment
Propagated s2#0 through call [4] call sum param-assignment
Propagating live ranges...
Propagated s1#0 through call [2] call sum param-assignment
Propagated s1#0 through call [4] call sum param-assignment
Propagated s2#0 through call [4] call sum param-assignment
Propagating live ranges...
Propagated s1#0 through call [2] call sum param-assignment
Propagated s1#0 through call [4] call sum param-assignment
Propagated s2#0 through call [4] call sum param-assignment
Propagating live ranges...
CONTROL FLOW GRAPH - LIVE RANGES
@BEGIN: from
@ -292,26 +371,40 @@ CONTROL FLOW GRAPH - LIVE RANGES
to:@3
@3: from @2
[3] (byte) s2#0 ← (byte) sum::return#0 [ s1#0 s2#0 ]
[4] (byte) s3#0 ← (byte) s1#0 + (byte) s2#0 [ ]
[4] call sum param-assignment [ sum::return#0 s1#0 s2#0 ]
to:@4
@4: from @3
[5] (byte) s3#0 ← (byte) sum::return#0 [ s1#0 s2#0 s3#0 ]
[6] (byte~) $3 ← (byte) s1#0 + (byte) s2#0 [ $3 s3#0 ]
[7] (byte) s4#0 ← (byte~) $3 + (byte) s3#0 [ ]
to:@END
@END: from @3
sum: from @2 @BEGIN
[5] (byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 ) [ s1#0 sum::a#2 sum::b#2 ]
[5] (byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 ) [ s1#0 sum::a#2 sum::b#2 ]
[6] (byte) sum::return#0 ← (byte) sum::a#2 + (byte) sum::b#2 [ sum::return#0 s1#0 ]
@END: from @4
sum: from @2 @3 @BEGIN
[8] (byte) sum::b#3 ← phi( @2/(byte) 4 @3/(byte) 13 @BEGIN/(byte) 2 ) [ s1#0 s2#0 sum::a#3 sum::b#3 ]
[8] (byte) sum::a#3 ← phi( @2/(byte) 3 @3/(byte) 9 @BEGIN/(byte) 1 ) [ s1#0 s2#0 sum::a#3 sum::b#3 ]
[9] (byte) sum::return#0 ← (byte) sum::a#3 + (byte) sum::b#3 [ sum::return#0 s1#0 s2#0 ]
to:sum::@return
sum::@return: from sum
[7] return [ sum::return#0 s1#0 ]
[10] return [ sum::return#0 s1#0 s2#0 ]
to:@RETURN
Created 2 initial phi equivalence classes
Coalesced down to 2 phi equivalence classes
Block Sequence Planned @BEGIN @2 @3 @END sum sum::@return
Adding empty live range for unused variable s3#0
Block Sequence Planned @BEGIN @2 @3 @4 @END sum sum::@return
Adding empty live range for unused variable s4#0
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagated s1#0 through call [4] call sum param-assignment
Propagated s2#0 through call [4] call sum param-assignment
Propagating live ranges...
Propagated s1#0 through call [2] call sum param-assignment
Propagated s1#0 through call [4] call sum param-assignment
Propagated s2#0 through call [4] call sum param-assignment
Propagating live ranges...
Propagated s1#0 through call [2] call sum param-assignment
Propagated s1#0 through call [4] call sum param-assignment
Propagated s2#0 through call [4] call sum param-assignment
Propagating live ranges...
CONTROL FLOW GRAPH - PHI MEM COALESCED
@BEGIN: from
@ -323,26 +416,32 @@ CONTROL FLOW GRAPH - PHI MEM COALESCED
to:@3
@3: from @2
[3] (byte) s2#0 ← (byte) sum::return#0 [ s1#0 s2#0 ]
[4] (byte) s3#0 ← (byte) s1#0 + (byte) s2#0 [ ]
[4] call sum param-assignment [ sum::return#0 s1#0 s2#0 ]
to:@4
@4: from @3
[5] (byte) s3#0 ← (byte) sum::return#0 [ s1#0 s2#0 s3#0 ]
[6] (byte~) $3 ← (byte) s1#0 + (byte) s2#0 [ $3 s3#0 ]
[7] (byte) s4#0 ← (byte~) $3 + (byte) s3#0 [ ]
to:@END
@END: from @3
sum: from @2 @BEGIN
[5] (byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 ) [ s1#0 sum::a#2 sum::b#2 ]
[5] (byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 ) [ s1#0 sum::a#2 sum::b#2 ]
[6] (byte) sum::return#0 ← (byte) sum::a#2 + (byte) sum::b#2 [ sum::return#0 s1#0 ]
@END: from @4
sum: from @2 @3 @BEGIN
[8] (byte) sum::b#3 ← phi( @2/(byte) 4 @3/(byte) 13 @BEGIN/(byte) 2 ) [ s1#0 s2#0 sum::a#3 sum::b#3 ]
[8] (byte) sum::a#3 ← phi( @2/(byte) 3 @3/(byte) 9 @BEGIN/(byte) 1 ) [ s1#0 s2#0 sum::a#3 sum::b#3 ]
[9] (byte) sum::return#0 ← (byte) sum::a#3 + (byte) sum::b#3 [ sum::return#0 s1#0 s2#0 ]
to:sum::@return
sum::@return: from sum
[7] return [ sum::return#0 s1#0 ]
[10] return [ sum::return#0 s1#0 s2#0 ]
to:@RETURN
CALL GRAPH
Calls in [] to 0:sum 2:sum
Calls in [] to 0:sum 2:sum 4:sum
DOMINATORS
@BEGIN dominated by @BEGIN
@2 dominated by @BEGIN @2
@3 dominated by @BEGIN @2 @3
@END dominated by @BEGIN @2 @3 @END
@4 dominated by @BEGIN @2 @3 @4
@END dominated by @BEGIN @2 @3 @4 @END
sum dominated by @BEGIN sum
sum::@return dominated by @BEGIN sum::@return sum
@ -354,50 +453,59 @@ NATURAL LOOPS WITH DEPTH
VARIABLE REGISTER WEIGHTS
(byte~) $3 4.0
(byte) s1
(byte) s1#0 0.6666666666666666
(byte) s1#0 0.5
(byte) s2
(byte) s2#0 4.0
(byte) s2#0 0.6666666666666666
(byte) s3
(byte) s3#0 Infinity
(byte) s3#0 2.0
(byte) s4
(byte) s4#0 Infinity
(byte()) sum((byte) sum::a , (byte) sum::b)
(byte) sum::a
(byte) sum::a#2 2.0
(byte) sum::a#3 2.0
(byte) sum::b
(byte) sum::b#2 2.0
(byte) sum::b#3 2.0
(byte) sum::return
(byte) sum::return#0 1.5
(byte) sum::return#0 1.6
Initial phi equivalence classes
[ sum::a#2 ]
[ sum::b#2 ]
[ sum::a#3 ]
[ sum::b#3 ]
Added variable s1#0 to zero page equivalence class [ s1#0 ]
Added variable s2#0 to zero page equivalence class [ s2#0 ]
Added variable s3#0 to zero page equivalence class [ s3#0 ]
Added variable $3 to zero page equivalence class [ $3 ]
Added variable s4#0 to zero page equivalence class [ s4#0 ]
Added variable sum::return#0 to zero page equivalence class [ sum::return#0 ]
Complete equivalence classes
[ sum::a#2 ]
[ sum::b#2 ]
[ sum::a#3 ]
[ sum::b#3 ]
[ s1#0 ]
[ s2#0 ]
[ s3#0 ]
[ $3 ]
[ s4#0 ]
[ sum::return#0 ]
Allocated zp byte:2 to zp byte:2 [ sum::a#2 ]
Allocated zp byte:3 to zp byte:3 [ sum::b#2 ]
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 [ sum::return#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 ]
INITIAL ASM
//SEG0 @BEGIN
BBEGIN:
//SEG1 [0] call sum param-assignment [ sum::return#0 ]
//SEG2 [5] phi from @BEGIN to sum
//SEG2 [8] phi from @BEGIN to sum
sum_from_BBEGIN:
//SEG3 [5] phi (byte) sum::b#2 = (byte) 2 -- zpby1=coby1
//SEG3 [8] phi (byte) sum::b#3 = (byte) 2 -- zpby1=coby1
lda #2
sta 3
//SEG4 [5] phi (byte) sum::a#2 = (byte) 1 -- zpby1=coby1
//SEG4 [8] phi (byte) sum::a#3 = (byte) 1 -- zpby1=coby1
lda #1
sta 2
jsr sum
@ -405,62 +513,87 @@ sum_from_BBEGIN:
//SEG5 @2
B2:
//SEG6 [1] (byte) s1#0 ← (byte) sum::return#0 [ s1#0 ] -- zpby1=zpby2
lda 7
lda 9
sta 4
//SEG7 [2] call sum param-assignment [ sum::return#0 s1#0 ]
//SEG8 [5] phi from @2 to sum
//SEG8 [8] phi from @2 to sum
sum_from_B2:
//SEG9 [5] phi (byte) sum::b#2 = (byte) 13 -- zpby1=coby1
lda #13
//SEG9 [8] phi (byte) sum::b#3 = (byte) 4 -- zpby1=coby1
lda #4
sta 3
//SEG10 [5] phi (byte) sum::a#2 = (byte) 9 -- zpby1=coby1
lda #9
//SEG10 [8] phi (byte) sum::a#3 = (byte) 3 -- zpby1=coby1
lda #3
sta 2
jsr sum
jmp B3
//SEG11 @3
B3:
//SEG12 [3] (byte) s2#0 ← (byte) sum::return#0 [ s1#0 s2#0 ] -- zpby1=zpby2
lda 7
lda 9
sta 5
//SEG13 [4] (byte) s3#0 ← (byte) s1#0 + (byte) s2#0 [ ] -- zpby1=zpby2_plus_zpby3
//SEG13 [4] call sum param-assignment [ sum::return#0 s1#0 s2#0 ]
//SEG14 [8] phi from @3 to sum
sum_from_B3:
//SEG15 [8] phi (byte) sum::b#3 = (byte) 13 -- zpby1=coby1
lda #13
sta 3
//SEG16 [8] phi (byte) sum::a#3 = (byte) 9 -- zpby1=coby1
lda #9
sta 2
jsr sum
jmp B4
//SEG17 @4
B4:
//SEG18 [5] (byte) s3#0 ← (byte) sum::return#0 [ s1#0 s2#0 s3#0 ] -- zpby1=zpby2
lda 9
sta 6
//SEG19 [6] (byte~) $3 ← (byte) s1#0 + (byte) s2#0 [ $3 s3#0 ] -- zpby1=zpby2_plus_zpby3
lda 4
clc
adc 5
sta 6
sta 7
//SEG20 [7] (byte) s4#0 ← (byte~) $3 + (byte) s3#0 [ ] -- zpby1=zpby2_plus_zpby3
lda 7
clc
adc 6
sta 8
jmp BEND
//SEG14 @END
//SEG21 @END
BEND:
//SEG15 sum
//SEG22 sum
sum:
//SEG16 [6] (byte) sum::return#0 ← (byte) sum::a#2 + (byte) sum::b#2 [ sum::return#0 s1#0 ] -- zpby1=zpby2_plus_zpby3
//SEG23 [9] (byte) sum::return#0 ← (byte) sum::a#3 + (byte) sum::b#3 [ sum::return#0 s1#0 s2#0 ] -- zpby1=zpby2_plus_zpby3
lda 2
clc
adc 3
sta 7
sta 9
jmp sum__Breturn
//SEG17 sum::@return
//SEG24 sum::@return
sum__Breturn:
//SEG18 [7] return [ sum::return#0 s1#0 ]
//SEG25 [10] return [ sum::return#0 s1#0 s2#0 ]
rts
REGISTER UPLIFT POTENTIAL REGISTERS
Potential registers zp byte:2 [ sum::a#2 ] : zp byte:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:3 [ sum::b#2 ] : zp byte:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:2 [ sum::a#3 ] : zp byte:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:3 [ sum::b#3 ] : zp byte:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:4 [ s1#0 ] : zp byte:4 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:5 [ s2#0 ] : zp byte:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:6 [ s3#0 ] : zp byte:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:7 [ sum::return#0 ] : zp byte:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:7 [ $3 ] : zp byte:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:8 [ s4#0 ] : zp byte:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:9 [ sum::return#0 ] : zp byte:9 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [] ∞: zp byte:6 [ s3#0 ] 4: zp byte:5 [ s2#0 ] 0.67: zp byte:4 [ s1#0 ]
Uplift Scope [sum] 2: zp byte:2 [ sum::a#2 ] 2: zp byte:3 [ sum::b#2 ] 1.5: zp byte:7 [ sum::return#0 ]
Uplift Scope [] ∞: zp byte:8 [ s4#0 ] 4: zp byte:7 [ $3 ] 2: zp byte:6 [ s3#0 ] 0.67: zp byte:5 [ s2#0 ] 0.5: zp byte:4 [ s1#0 ]
Uplift Scope [sum] 2: zp byte:2 [ sum::a#3 ] 2: zp byte:3 [ sum::b#3 ] 1.6: zp byte:9 [ sum::return#0 ]
Uplifting [] best 75 combination reg byte a [ s3#0 ] reg byte a [ s2#0 ] zp byte:4 [ s1#0 ]
Uplifting [sum] best 54 combination reg byte x [ sum::a#2 ] reg byte a [ sum::b#2 ] reg byte a [ sum::return#0 ]
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
Removing instruction jmp B2
Removing instruction jmp B3
Removing instruction jmp B4
Removing instruction jmp BEND
Removing instruction jmp sum__Breturn
Succesful ASM optimization Pass5NextJumpElimination
@ -468,112 +601,150 @@ ASSEMBLER
//SEG0 @BEGIN
BBEGIN:
//SEG1 [0] call sum param-assignment [ sum::return#0 ]
//SEG2 [5] phi from @BEGIN to sum
//SEG2 [8] phi from @BEGIN to sum
sum_from_BBEGIN:
//SEG3 [5] phi (byte) sum::b#2 = (byte) 2 -- aby=coby1
//SEG3 [8] phi (byte) sum::b#3 = (byte) 2 -- aby=coby1
lda #2
//SEG4 [5] phi (byte) sum::a#2 = (byte) 1 -- xby=coby1
ldx #1
//SEG4 [8] phi (byte) sum::a#3 = (byte) 1 -- yby=coby1
ldy #1
jsr sum
//SEG5 @2
B2:
//SEG6 [1] (byte) s1#0 ← (byte) sum::return#0 [ s1#0 ] -- zpby1=aby
sta 2
//SEG7 [2] call sum param-assignment [ sum::return#0 s1#0 ]
//SEG8 [5] phi from @2 to sum
//SEG8 [8] phi from @2 to sum
sum_from_B2:
//SEG9 [5] phi (byte) sum::b#2 = (byte) 13 -- aby=coby1
lda #13
//SEG10 [5] phi (byte) sum::a#2 = (byte) 9 -- xby=coby1
ldx #9
//SEG9 [8] phi (byte) sum::b#3 = (byte) 4 -- aby=coby1
lda #4
//SEG10 [8] phi (byte) sum::a#3 = (byte) 3 -- yby=coby1
ldy #3
jsr sum
//SEG11 @3
B3:
//SEG12 [3] (byte) s2#0 ← (byte) sum::return#0 [ s1#0 s2#0 ]
// (byte) s2#0 = (byte) sum::return#0 // register copy reg byte a
//SEG13 [4] (byte) s3#0 ← (byte) s1#0 + (byte) s2#0 [ ] -- aby=zpby1_plus_aby
//SEG12 [3] (byte) s2#0 ← (byte) sum::return#0 [ s1#0 s2#0 ] -- xby=aby
tax
//SEG13 [4] call sum param-assignment [ sum::return#0 s1#0 s2#0 ]
//SEG14 [8] phi from @3 to sum
sum_from_B3:
//SEG15 [8] phi (byte) sum::b#3 = (byte) 13 -- aby=coby1
lda #13
//SEG16 [8] phi (byte) sum::a#3 = (byte) 9 -- yby=coby1
ldy #9
jsr sum
//SEG17 @4
B4:
//SEG18 [5] (byte) s3#0 ← (byte) sum::return#0 [ s1#0 s2#0 s3#0 ] -- zpby1=aby
sta 3
//SEG19 [6] (byte~) $3 ← (byte) s1#0 + (byte) s2#0 [ $3 s3#0 ] -- aby=zpby1_plus_xby
txa
clc
adc 2
//SEG14 @END
//SEG20 [7] (byte) s4#0 ← (byte~) $3 + (byte) s3#0 [ ] -- aby=aby_plus_zpby1
clc
adc 3
//SEG21 @END
BEND:
//SEG15 sum
//SEG22 sum
sum:
//SEG16 [6] (byte) sum::return#0 ← (byte) sum::a#2 + (byte) sum::b#2 [ sum::return#0 s1#0 ] -- aby=xby_plus_aby
stx 255
//SEG23 [9] (byte) sum::return#0 ← (byte) sum::a#3 + (byte) sum::b#3 [ sum::return#0 s1#0 s2#0 ] -- aby=yby_plus_aby
sty 255
clc
adc 255
//SEG17 sum::@return
//SEG24 sum::@return
sum__Breturn:
//SEG18 [7] return [ sum::return#0 s1#0 ]
//SEG25 [10] return [ sum::return#0 s1#0 s2#0 ]
rts
FINAL SYMBOL TABLE
(byte~) $3 reg byte a 4.0
(label) @2
(label) @3
(label) @4
(label) @BEGIN
(label) @END
(byte) s1
(byte) s1#0 zp byte:2 0.6666666666666666
(byte) s1#0 zp byte:2 0.5
(byte) s2
(byte) s2#0 reg byte a 4.0
(byte) s2#0 reg byte x 0.6666666666666666
(byte) s3
(byte) s3#0 reg byte a Infinity
(byte) s3#0 zp byte:3 2.0
(byte) s4
(byte) s4#0 reg byte a Infinity
(byte()) sum((byte) sum::a , (byte) sum::b)
(label) sum::@return
(byte) sum::a
(byte) sum::a#2 reg byte x 2.0
(byte) sum::a#3 reg byte y 2.0
(byte) sum::b
(byte) sum::b#2 reg byte a 2.0
(byte) sum::b#3 reg byte a 2.0
(byte) sum::return
(byte) sum::return#0 reg byte a 1.5
(byte) sum::return#0 reg byte a 1.6
reg byte x [ sum::a#2 ]
reg byte a [ sum::b#2 ]
reg byte y [ sum::a#3 ]
reg byte a [ sum::b#3 ]
zp byte:2 [ s1#0 ]
reg byte a [ s2#0 ]
reg byte a [ s3#0 ]
reg byte x [ s2#0 ]
zp byte:3 [ s3#0 ]
reg byte a [ $3 ]
reg byte a [ s4#0 ]
reg byte a [ sum::return#0 ]
FINAL CODE
//SEG0 @BEGIN
BBEGIN:
//SEG1 [0] call sum param-assignment [ sum::return#0 ]
//SEG2 [5] phi from @BEGIN to sum
//SEG2 [8] phi from @BEGIN to sum
sum_from_BBEGIN:
//SEG3 [5] phi (byte) sum::b#2 = (byte) 2 -- aby=coby1
//SEG3 [8] phi (byte) sum::b#3 = (byte) 2 -- aby=coby1
lda #2
//SEG4 [5] phi (byte) sum::a#2 = (byte) 1 -- xby=coby1
ldx #1
//SEG4 [8] phi (byte) sum::a#3 = (byte) 1 -- yby=coby1
ldy #1
jsr sum
//SEG5 @2
B2:
//SEG6 [1] (byte) s1#0 ← (byte) sum::return#0 [ s1#0 ] -- zpby1=aby
sta 2
//SEG7 [2] call sum param-assignment [ sum::return#0 s1#0 ]
//SEG8 [5] phi from @2 to sum
//SEG8 [8] phi from @2 to sum
sum_from_B2:
//SEG9 [5] phi (byte) sum::b#2 = (byte) 13 -- aby=coby1
lda #13
//SEG10 [5] phi (byte) sum::a#2 = (byte) 9 -- xby=coby1
ldx #9
//SEG9 [8] phi (byte) sum::b#3 = (byte) 4 -- aby=coby1
lda #4
//SEG10 [8] phi (byte) sum::a#3 = (byte) 3 -- yby=coby1
ldy #3
jsr sum
//SEG11 @3
B3:
//SEG12 [3] (byte) s2#0 ← (byte) sum::return#0 [ s1#0 s2#0 ]
// (byte) s2#0 = (byte) sum::return#0 // register copy reg byte a
//SEG13 [4] (byte) s3#0 ← (byte) s1#0 + (byte) s2#0 [ ] -- aby=zpby1_plus_aby
//SEG12 [3] (byte) s2#0 ← (byte) sum::return#0 [ s1#0 s2#0 ] -- xby=aby
tax
//SEG13 [4] call sum param-assignment [ sum::return#0 s1#0 s2#0 ]
//SEG14 [8] phi from @3 to sum
sum_from_B3:
//SEG15 [8] phi (byte) sum::b#3 = (byte) 13 -- aby=coby1
lda #13
//SEG16 [8] phi (byte) sum::a#3 = (byte) 9 -- yby=coby1
ldy #9
jsr sum
//SEG17 @4
B4:
//SEG18 [5] (byte) s3#0 ← (byte) sum::return#0 [ s1#0 s2#0 s3#0 ] -- zpby1=aby
sta 3
//SEG19 [6] (byte~) $3 ← (byte) s1#0 + (byte) s2#0 [ $3 s3#0 ] -- aby=zpby1_plus_xby
txa
clc
adc 2
//SEG14 @END
//SEG20 [7] (byte) s4#0 ← (byte~) $3 + (byte) s3#0 [ ] -- aby=aby_plus_zpby1
clc
adc 3
//SEG21 @END
BEND:
//SEG15 sum
//SEG22 sum
sum:
//SEG16 [6] (byte) sum::return#0 ← (byte) sum::a#2 + (byte) sum::b#2 [ sum::return#0 s1#0 ] -- aby=xby_plus_aby
stx 255
//SEG23 [9] (byte) sum::return#0 ← (byte) sum::a#3 + (byte) sum::b#3 [ sum::return#0 s1#0 s2#0 ] -- aby=yby_plus_aby
sty 255
clc
adc 255
//SEG17 sum::@return
//SEG24 sum::@return
sum__Breturn:
//SEG18 [7] return [ sum::return#0 s1#0 ]
//SEG25 [10] return [ sum::return#0 s1#0 s2#0 ]
rts

View File

@ -1,25 +1,31 @@
(byte~) $3 reg byte a 4.0
(label) @2
(label) @3
(label) @4
(label) @BEGIN
(label) @END
(byte) s1
(byte) s1#0 zp byte:2 0.6666666666666666
(byte) s1#0 zp byte:2 0.5
(byte) s2
(byte) s2#0 reg byte a 4.0
(byte) s2#0 reg byte x 0.6666666666666666
(byte) s3
(byte) s3#0 reg byte a Infinity
(byte) s3#0 zp byte:3 2.0
(byte) s4
(byte) s4#0 reg byte a Infinity
(byte()) sum((byte) sum::a , (byte) sum::b)
(label) sum::@return
(byte) sum::a
(byte) sum::a#2 reg byte x 2.0
(byte) sum::a#3 reg byte y 2.0
(byte) sum::b
(byte) sum::b#2 reg byte a 2.0
(byte) sum::b#3 reg byte a 2.0
(byte) sum::return
(byte) sum::return#0 reg byte a 1.5
(byte) sum::return#0 reg byte a 1.6
reg byte x [ sum::a#2 ]
reg byte a [ sum::b#2 ]
reg byte y [ sum::a#3 ]
reg byte a [ sum::b#3 ]
zp byte:2 [ s1#0 ]
reg byte a [ s2#0 ]
reg byte a [ s3#0 ]
reg byte x [ s2#0 ]
zp byte:3 [ s3#0 ]
reg byte a [ $3 ]
reg byte a [ s4#0 ]
reg byte a [ sum::return#0 ]

View File

@ -101,25 +101,25 @@ animate::@1: from animate
render: from main::@1
to:render::@1
render::@1: from render render::@3
[51] (byte*) render::colline#2 ← phi( render/(word) 55296 render::@3/(byte*) render::colline#1 ) [ render::y#2 render::colline#2 numpoints#1 ]
[51] (byte) render::y#2 ← phi( render/(byte) 0 render::@3/(byte) render::y#1 ) [ render::y#2 render::colline#2 numpoints#1 ]
[51] (byte*) render::colline#2 ← phi( render/(word) 55296 render::@3/(byte*) render::colline#1 ) [ render::y#2 render::colline#2 ]
[51] (byte) render::y#2 ← phi( render/(byte) 0 render::@3/(byte) render::y#1 ) [ render::y#2 render::colline#2 ]
to:render::@2
render::@2: from render::@1 render::@5
[52] (byte) render::x#2 ← phi( render::@1/(byte) 0 render::@5/(byte) render::x#1 ) [ render::x#2 render::y#2 render::colline#2 numpoints#1 ]
[53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 numpoints#1 ]
[54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 findcol::y#0 numpoints#1 ]
[55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
[52] (byte) render::x#2 ← phi( render::@1/(byte) 0 render::@5/(byte) render::x#1 ) [ render::x#2 render::y#2 render::colline#2 ]
[53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 ]
[54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 ]
[55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
to:render::@5
render::@5: from render::@2
[56] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 numpoints#1 ]
[57] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 numpoints#1 ]
[58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 render::colline#2 numpoints#1 ]
[59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 numpoints#1 ]
[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 ]
to:render::@3
render::@3: from render::@5
[60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 numpoints#1 ]
[61] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 numpoints#1 ]
[62] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 numpoints#1 ]
[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 ]
to:render::@return
render::@return: from render::@3
[63] return [ ]
@ -159,8 +159,8 @@ findcol::@13: from findcol::@11 findcol::@12
[78] if((byte) findcol::i#1<(byte) numpoints#1) goto findcol::@1 [ render::x#2 render::y#2 render::colline#2 findcol::i#1 findcol::mindiff#11 findcol::mincol#2 findcol::x#0 findcol::y#0 numpoints#1 ]
to:findcol::@return
findcol::@return: from findcol::@13 findcol::@2
[79] (byte) findcol::return#0 ← phi( findcol::@13/(byte) findcol::mincol#2 findcol::@2/(byte) 0 ) [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
[80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
[79] (byte) findcol::return#0 ← phi( findcol::@13/(byte) findcol::mincol#2 findcol::@2/(byte) 0 ) [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
[80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
to:@RETURN
findcol::@12: from findcol::@11
[81] (byte) findcol::mincol#1 ← (word) 4608 *idx (byte) findcol::i#12 [ render::x#2 render::y#2 render::colline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#6 findcol::mincol#1 numpoints#1 ]

View File

@ -5853,25 +5853,61 @@ Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::y#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::y#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::y#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::y#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::y#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::y#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::y#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::y#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::y#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::y#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagated render::x#2 through call [60] call findcol param-assignment
Propagated render::y#2 through call [60] call findcol param-assignment
Propagated render::colline#2 through call [60] call findcol param-assignment
Propagating live ranges...
CONTROL FLOW GRAPH - LIVE RANGES
@BEGIN: from
@ -5982,35 +6018,35 @@ animate::@1: from animate
render: from main::@1
to:render::@1
render::@1: from render render::@6
[56] (byte*) render::colline#2 ← phi( render/(word) 55296 render::@6/(byte*~) render::colline#6 ) [ numpoints#1 render::y#2 render::colline#2 ]
[56] (byte) render::y#2 ← phi( render/(byte) 0 render::@6/(byte~) render::y#6 ) [ numpoints#1 render::y#2 render::colline#2 ]
[56] (byte*) render::colline#2 ← phi( render/(word) 55296 render::@6/(byte*~) render::colline#6 ) [ render::y#2 render::colline#2 ]
[56] (byte) render::y#2 ← phi( render/(byte) 0 render::@6/(byte~) render::y#6 ) [ render::y#2 render::colline#2 ]
to:render::@2
render::@2: from render::@1 render::@7
[57] (byte) render::x#2 ← phi( render::@1/(byte) 0 render::@7/(byte~) render::x#4 ) [ numpoints#1 render::x#2 render::y#2 render::colline#2 ]
[58] (byte) findcol::x#0 ← (byte) render::x#2 [ numpoints#1 render::x#2 render::y#2 render::colline#2 findcol::x#0 ]
[59] (byte) findcol::y#0 ← (byte) render::y#2 [ numpoints#1 render::x#2 render::y#2 render::colline#2 findcol::x#0 findcol::y#0 ]
[60] call findcol param-assignment [ numpoints#1 render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
[57] (byte) render::x#2 ← phi( render::@1/(byte) 0 render::@7/(byte~) render::x#4 ) [ render::x#2 render::y#2 render::colline#2 ]
[58] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 ]
[59] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 ]
[60] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
to:render::@5
render::@5: from render::@2
[61] (byte) render::col#0 ← (byte) findcol::return#0 [ numpoints#1 render::x#2 render::y#2 render::colline#2 render::col#0 ]
[62] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ numpoints#1 render::x#2 render::y#2 render::colline#2 ]
[63] (byte) render::x#1 ← ++ (byte) render::x#2 [ numpoints#1 render::y#2 render::colline#2 render::x#1 ]
[64] if((byte) render::x#1<(byte) 40) goto render::@7 [ numpoints#1 render::y#2 render::colline#2 render::x#1 ]
[61] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 ]
[62] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 ]
[63] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::y#2 render::colline#2 render::x#1 ]
[64] if((byte) render::x#1<(byte) 40) goto render::@7 [ render::y#2 render::colline#2 render::x#1 ]
to:render::@3
render::@3: from render::@5
[65] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ numpoints#1 render::y#2 render::colline#1 ]
[66] (byte) render::y#1 ← ++ (byte) render::y#2 [ numpoints#1 render::y#1 render::colline#1 ]
[67] if((byte) render::y#1<(byte) 25) goto render::@6 [ numpoints#1 render::y#1 render::colline#1 ]
[65] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::y#2 render::colline#1 ]
[66] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 ]
[67] if((byte) render::y#1<(byte) 25) goto render::@6 [ render::y#1 render::colline#1 ]
to:render::@return
render::@return: from render::@3
[68] return [ ]
to:@RETURN
render::@6: from render::@3
[69] (byte~) render::y#6 ← (byte) render::y#1 [ numpoints#1 render::y#6 render::colline#1 ]
[70] (byte*~) render::colline#6 ← (byte*) render::colline#1 [ numpoints#1 render::y#6 render::colline#6 ]
[69] (byte~) render::y#6 ← (byte) render::y#1 [ render::y#6 render::colline#1 ]
[70] (byte*~) render::colline#6 ← (byte*) render::colline#1 [ render::y#6 render::colline#6 ]
to:render::@1
render::@7: from render::@5
[71] (byte~) render::x#4 ← (byte) render::x#1 [ numpoints#1 render::x#4 render::y#2 render::colline#2 ]
[71] (byte~) render::x#4 ← (byte) render::x#1 [ render::x#4 render::y#2 render::colline#2 ]
to:render::@2
findcol: from render::@2
to:findcol::@1
@ -6053,11 +6089,11 @@ findcol::@13: from findcol::@12 findcol::@30
[90] if((byte) findcol::i#1<(byte) numpoints#1) goto findcol::@29 [ numpoints#1 render::x#2 render::y#2 render::colline#2 findcol::x#0 findcol::y#0 findcol::i#1 findcol::mincol#2 findcol::mindiff#11 ]
to:findcol::@31
findcol::@31: from findcol::@13
[91] (byte~) findcol::mincol#16 ← (byte) findcol::mincol#2 [ numpoints#1 render::x#2 render::y#2 render::colline#2 findcol::mincol#16 ]
[91] (byte~) findcol::mincol#16 ← (byte) findcol::mincol#2 [ render::x#2 render::y#2 render::colline#2 findcol::mincol#16 ]
to:findcol::@return
findcol::@return: from findcol::@2 findcol::@31
[92] (byte) findcol::return#0 ← phi( findcol::@31/(byte~) findcol::mincol#16 findcol::@2/(byte) 0 ) [ numpoints#1 render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
[93] return [ numpoints#1 render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
[92] (byte) findcol::return#0 ← phi( findcol::@31/(byte~) findcol::mincol#16 findcol::@2/(byte) 0 ) [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
[93] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
to:@RETURN
findcol::@29: from findcol::@13
[94] (byte~) findcol::i#13 ← (byte) findcol::i#1 [ numpoints#1 render::x#2 render::y#2 render::colline#2 findcol::i#13 findcol::x#0 findcol::y#0 findcol::mincol#2 findcol::mindiff#11 ]
@ -6145,19 +6181,41 @@ Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagated render::x#2 through call [55] call findcol param-assignment
Propagated render::colline#2 through call [55] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [55] call findcol param-assignment
Propagated render::colline#2 through call [55] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [55] call findcol param-assignment
Propagated render::colline#2 through call [55] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [55] call findcol param-assignment
Propagated render::colline#2 through call [55] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [55] call findcol param-assignment
Propagated render::y#2 through call [55] call findcol param-assignment
Propagated render::colline#2 through call [55] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [55] call findcol param-assignment
Propagated render::y#2 through call [55] call findcol param-assignment
Propagated render::colline#2 through call [55] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [55] call findcol param-assignment
Propagated render::y#2 through call [55] call findcol param-assignment
Propagated render::colline#2 through call [55] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [55] call findcol param-assignment
Propagated render::y#2 through call [55] call findcol param-assignment
Propagated render::colline#2 through call [55] call findcol param-assignment
Propagating live ranges...
Propagated render::x#2 through call [55] call findcol param-assignment
Propagated render::y#2 through call [55] call findcol param-assignment
Propagated render::colline#2 through call [55] call findcol param-assignment
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagated render::x#2 through call [55] call findcol param-assignment
Propagated render::y#2 through call [55] call findcol param-assignment
Propagated render::colline#2 through call [55] call findcol param-assignment
Propagating live ranges...
CONTROL FLOW GRAPH - PHI MEM COALESCED
@BEGIN: from
@ -6263,25 +6321,25 @@ animate::@1: from animate
render: from main::@1
to:render::@1
render::@1: from render render::@3
[51] (byte*) render::colline#2 ← phi( render/(word) 55296 render::@3/(byte*) render::colline#1 ) [ render::y#2 render::colline#2 numpoints#1 ]
[51] (byte) render::y#2 ← phi( render/(byte) 0 render::@3/(byte) render::y#1 ) [ render::y#2 render::colline#2 numpoints#1 ]
[51] (byte*) render::colline#2 ← phi( render/(word) 55296 render::@3/(byte*) render::colline#1 ) [ render::y#2 render::colline#2 ]
[51] (byte) render::y#2 ← phi( render/(byte) 0 render::@3/(byte) render::y#1 ) [ render::y#2 render::colline#2 ]
to:render::@2
render::@2: from render::@1 render::@5
[52] (byte) render::x#2 ← phi( render::@1/(byte) 0 render::@5/(byte) render::x#1 ) [ render::x#2 render::y#2 render::colline#2 numpoints#1 ]
[53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 numpoints#1 ]
[54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 findcol::y#0 numpoints#1 ]
[55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
[52] (byte) render::x#2 ← phi( render::@1/(byte) 0 render::@5/(byte) render::x#1 ) [ render::x#2 render::y#2 render::colline#2 ]
[53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 ]
[54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 ]
[55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
to:render::@5
render::@5: from render::@2
[56] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 numpoints#1 ]
[57] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 numpoints#1 ]
[58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 render::colline#2 numpoints#1 ]
[59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 numpoints#1 ]
[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 ]
to:render::@3
render::@3: from render::@5
[60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 numpoints#1 ]
[61] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 numpoints#1 ]
[62] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 numpoints#1 ]
[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 ]
to:render::@return
render::@return: from render::@3
[63] return [ ]
@ -6321,8 +6379,8 @@ findcol::@13: from findcol::@11 findcol::@12
[78] if((byte) findcol::i#1<(byte) numpoints#1) goto findcol::@1 [ render::x#2 render::y#2 render::colline#2 findcol::i#1 findcol::mindiff#11 findcol::mincol#2 findcol::x#0 findcol::y#0 numpoints#1 ]
to:findcol::@return
findcol::@return: from findcol::@13 findcol::@2
[79] (byte) findcol::return#0 ← phi( findcol::@13/(byte) findcol::mincol#2 findcol::@2/(byte) 0 ) [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
[80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
[79] (byte) findcol::return#0 ← phi( findcol::@13/(byte) findcol::mincol#2 findcol::@2/(byte) 0 ) [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
[80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
to:@RETURN
findcol::@12: from findcol::@11
[81] (byte) findcol::mincol#1 ← (word) 4608 *idx (byte) findcol::i#12 [ render::x#2 render::y#2 render::colline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#6 findcol::mincol#1 numpoints#1 ]
@ -6515,11 +6573,11 @@ VARIABLE REGISTER WEIGHTS
(byte) findcol::return
(byte) findcol::return#0 3667.333333333333
(byte) findcol::x
(byte) findcol::x#0 1782.8260869565217
(byte) findcol::x#0 1952.6190476190475
(byte) findcol::xp
(byte) findcol::xp#0 10001.0
(byte) findcol::y
(byte) findcol::y#0 1863.8636363636363
(byte) findcol::y#0 1952.6190476190475
(byte) findcol::yp
(byte) findcol::yp#0 6250.625
(void()) initscreen()
@ -6528,7 +6586,7 @@ VARIABLE REGISTER WEIGHTS
(byte*) initscreen::screen#2 16.5
(void()) main()
(byte) numpoints
(byte) numpoints#1 286.0857142857144
(byte) numpoints#1 476.8095238095237
(byte) numpoints#19 4.5
(void()) render()
(byte) render::col
@ -7004,34 +7062,34 @@ render__B2_from_B5:
jmp render__B2
//SEG118 render::@2
render__B2:
//SEG119 [53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 numpoints#1 ] -- zpby1=zpby2
//SEG119 [53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 ] -- zpby1=zpby2
lda 5
sta 37
//SEG120 [54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 findcol::y#0 numpoints#1 ] -- zpby1=zpby2
//SEG120 [54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 ] -- zpby1=zpby2
lda 2
sta 38
//SEG121 [55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
//SEG121 [55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
jsr findcol
jmp render__B5
//SEG122 render::@5
render__B5:
//SEG123 [56] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 numpoints#1 ] -- zpby1=zpby2
//SEG123 [56] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 ] -- zpby1=zpby2
lda 10
sta 39
//SEG124 [57] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 numpoints#1 ] -- zpptrby1_staridx_zpby1=zpby2
//SEG124 [57] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 ] -- zpptrby1_staridx_zpby1=zpby2
lda 39
ldy 5
sta (3),y
//SEG125 [58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 render::colline#2 numpoints#1 ] -- zpby1=_inc_zpby1
//SEG125 [58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 render::colline#2 ] -- zpby1=_inc_zpby1
inc 5
//SEG126 [59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 numpoints#1 ] -- zpby1_lt_coby1_then_la1
//SEG126 [59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 ] -- zpby1_lt_coby1_then_la1
lda 5
cmp #40
bcc render__B2_from_B5
jmp render__B3
//SEG127 render::@3
render__B3:
//SEG128 [60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 numpoints#1 ] -- zpptrby1=zpptrby1_plus_coby1
//SEG128 [60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 ] -- zpptrby1=zpptrby1_plus_coby1
lda 3
clc
adc #40
@ -7039,9 +7097,9 @@ render__B3:
bcc !+
inc 3+1
!:
//SEG129 [61] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 numpoints#1 ] -- zpby1=_inc_zpby1
//SEG129 [61] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 ] -- zpby1=_inc_zpby1
inc 2
//SEG130 [62] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 numpoints#1 ] -- zpby1_lt_coby1_then_la1
//SEG130 [62] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 ] -- zpby1_lt_coby1_then_la1
lda 2
cmp #25
bcc render__B1_from_B3
@ -7157,7 +7215,7 @@ findcol__Breturn_from_B2:
jmp findcol__Breturn
//SEG171 findcol::@return
findcol__Breturn:
//SEG172 [80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
//SEG172 [80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
rts
//SEG173 findcol::@12
findcol__B12:
@ -7275,9 +7333,8 @@ Statement [47] *((word) 4354) ← (byte) 0 [ ] always clobbers reg byte a
Statement [48] *((word) 4097) ← (byte) 40 [ ] always clobbers reg byte a
Statement [49] *((word) 4352) ← (byte) 0 [ ] always clobbers reg byte a
Statement [50] *((word) 4096) ← (byte) 0 [ ] always clobbers reg byte a
Statement [60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 numpoints#1 ] always clobbers reg byte a
Statement [60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 ] always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp byte:2 [ render::y#2 render::y#1 ]
Removing always clobbered register reg byte a as potential for zp byte:14 [ numpoints#19 numpoints#1 ]
Statement [69] (byte) findcol::diff#1 ← (byte) findcol::x#0 - (byte) findcol::xp#0 [ render::x#2 render::y#2 render::colline#2 findcol::i#12 findcol::x#0 findcol::diff#1 findcol::y#0 findcol::yp#0 findcol::mindiff#10 findcol::mincol#11 numpoints#1 ] always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp byte:5 [ render::x#2 render::x#1 ]
Removing always clobbered register reg byte a as potential for zp byte:6 [ findcol::i#12 findcol::i#1 ]
@ -7286,6 +7343,7 @@ Removing always clobbered register reg byte a as potential for zp byte:38 [ find
Removing always clobbered register reg byte a as potential for zp byte:41 [ findcol::yp#0 ]
Removing always clobbered register reg byte a as potential for zp byte:7 [ findcol::mindiff#10 findcol::mindiff#11 findcol::diff#13 ]
Removing always clobbered register reg byte a as potential for zp byte:10 [ findcol::return#0 findcol::mincol#11 findcol::mincol#2 findcol::mincol#1 ]
Removing always clobbered register reg byte a as potential for zp byte:14 [ numpoints#19 numpoints#1 ]
Statement [72] (byte~) findcol::$10 ← (byte) findcol::y#0 - (byte) findcol::yp#0 [ render::x#2 render::y#2 render::colline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#4 findcol::$10 findcol::mindiff#10 findcol::mincol#11 numpoints#1 ] always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp byte:8 [ findcol::diff#4 findcol::diff#0 findcol::diff#1 ]
Statement [83] (byte~) findcol::$8 ← (byte) findcol::yp#0 - (byte) findcol::y#0 [ render::x#2 render::y#2 render::colline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#4 findcol::mindiff#10 findcol::mincol#11 numpoints#1 findcol::$8 ] always clobbers reg byte a
@ -7299,7 +7357,7 @@ Statement [47] *((word) 4354) ← (byte) 0 [ ] always clobbers reg byte a
Statement [48] *((word) 4097) ← (byte) 40 [ ] always clobbers reg byte a
Statement [49] *((word) 4352) ← (byte) 0 [ ] always clobbers reg byte a
Statement [50] *((word) 4096) ← (byte) 0 [ ] always clobbers reg byte a
Statement [60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 numpoints#1 ] always clobbers reg byte a
Statement [60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 ] always clobbers reg byte a
Statement [69] (byte) findcol::diff#1 ← (byte) findcol::x#0 - (byte) findcol::xp#0 [ render::x#2 render::y#2 render::colline#2 findcol::i#12 findcol::x#0 findcol::diff#1 findcol::y#0 findcol::yp#0 findcol::mindiff#10 findcol::mincol#11 numpoints#1 ] always clobbers reg byte a
Statement [72] (byte~) findcol::$10 ← (byte) findcol::y#0 - (byte) findcol::yp#0 [ render::x#2 render::y#2 render::colline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#4 findcol::$10 findcol::mindiff#10 findcol::mincol#11 numpoints#1 ] always clobbers reg byte a
Statement [83] (byte~) findcol::$8 ← (byte) findcol::yp#0 - (byte) findcol::y#0 [ render::x#2 render::y#2 render::colline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#4 findcol::mindiff#10 findcol::mincol#11 numpoints#1 findcol::$8 ] always clobbers reg byte a
@ -7353,16 +7411,16 @@ Potential registers zp byte:42 [ findcol::$10 ] : zp byte:42 , reg byte a , reg
Potential registers zp byte:43 [ findcol::$8 ] : zp byte:43 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [findcol] 53,338.67: zp byte:9 [ findcol::diff#6 findcol::diff#3 findcol::diff#2 ] 50,005: zp byte:8 [ findcol::diff#4 findcol::diff#0 findcol::diff#1 ] 31,878.19: zp byte:7 [ findcol::mindiff#10 findcol::mindiff#11 findcol::diff#13 ] 28,253.12: zp byte:10 [ findcol::return#0 findcol::mincol#11 findcol::mincol#2 findcol::mincol#1 ] 20,002: zp byte:42 [ findcol::$10 ] 20,002: zp byte:43 [ findcol::$8 ] 17,633.34: zp byte:6 [ findcol::i#12 findcol::i#1 ] 10,001: zp byte:40 [ findcol::xp#0 ] 6,250.62: zp byte:41 [ findcol::yp#0 ] 1,863.86: zp byte:38 [ findcol::y#0 ] 1,782.83: zp byte:37 [ findcol::x#0 ]
Uplift Scope [findcol] 53,338.67: zp byte:9 [ findcol::diff#6 findcol::diff#3 findcol::diff#2 ] 50,005: zp byte:8 [ findcol::diff#4 findcol::diff#0 findcol::diff#1 ] 31,878.19: zp byte:7 [ findcol::mindiff#10 findcol::mindiff#11 findcol::diff#13 ] 28,253.12: zp byte:10 [ findcol::return#0 findcol::mincol#11 findcol::mincol#2 findcol::mincol#1 ] 20,002: zp byte:42 [ findcol::$10 ] 20,002: zp byte:43 [ findcol::$8 ] 17,633.34: zp byte:6 [ findcol::i#12 findcol::i#1 ] 10,001: zp byte:40 [ findcol::xp#0 ] 6,250.62: zp byte:41 [ findcol::yp#0 ] 1,952.62: zp byte:37 [ findcol::x#0 ] 1,952.62: zp byte:38 [ findcol::y#0 ]
Uplift Scope [render] 2,002: zp byte:39 [ render::col#0 ] 1,639.57: zp byte:5 [ render::x#2 render::x#1 ] 187.95: zp byte:2 [ render::y#2 render::y#1 ] 104.93: zp ptr byte:3 [ render::colline#2 render::colline#1 ]
Uplift Scope [] 290.59: zp byte:14 [ numpoints#19 numpoints#1 ]
Uplift Scope [] 481.31: zp byte:14 [ numpoints#19 numpoints#1 ]
Uplift Scope [animate] 4: zp byte:17 [ animate::$0 ] 4: zp byte:18 [ animate::$1 ] 4: zp byte:19 [ animate::$2 ] 4: zp byte:20 [ animate::$4 ] 4: zp byte:21 [ animate::$5 ] 4: zp byte:22 [ animate::$6 ] 4: zp byte:23 [ animate::$8 ] 4: zp byte:24 [ animate::$9 ] 4: zp byte:25 [ animate::$10 ] 4: zp byte:26 [ animate::$12 ] 4: zp byte:27 [ animate::$13 ] 4: zp byte:28 [ animate::$14 ] 4: zp byte:29 [ animate::$16 ] 4: zp byte:30 [ animate::$17 ] 4: zp byte:31 [ animate::$18 ] 4: zp byte:32 [ animate::$20 ] 4: zp byte:33 [ animate::$21 ] 4: zp byte:34 [ animate::$22 ] 4: zp byte:35 [ animate::$24 ] 4: zp byte:36 [ animate::$25 ]
Uplift Scope [initscreen] 33: zp ptr byte:11 [ initscreen::screen#2 initscreen::screen#1 ]
Uplift Scope [addpoint] 2: zp byte:13 [ addpoint::x#6 ] 1: zp byte:15 [ addpoint::y#6 ] 0.67: zp byte:16 [ addpoint::c#6 ]
Uplift Scope [main]
Uplift attempts [findcol] 10000/559872 (limiting to 10000)
Uplifting [findcol] best 1694527 combination reg byte a [ findcol::diff#6 findcol::diff#3 findcol::diff#2 ] zp byte:8 [ findcol::diff#4 findcol::diff#0 findcol::diff#1 ] zp byte:7 [ findcol::mindiff#10 findcol::mindiff#11 findcol::diff#13 ] reg byte y [ findcol::return#0 findcol::mincol#11 findcol::mincol#2 findcol::mincol#1 ] reg byte a [ findcol::$10 ] reg byte a [ findcol::$8 ] reg byte x [ findcol::i#12 findcol::i#1 ] zp byte:40 [ findcol::xp#0 ] zp byte:41 [ findcol::yp#0 ] zp byte:38 [ findcol::y#0 ] zp byte:37 [ findcol::x#0 ]
Uplifting [findcol] best 1694527 combination reg byte a [ findcol::diff#6 findcol::diff#3 findcol::diff#2 ] zp byte:8 [ findcol::diff#4 findcol::diff#0 findcol::diff#1 ] zp byte:7 [ findcol::mindiff#10 findcol::mindiff#11 findcol::diff#13 ] reg byte y [ findcol::return#0 findcol::mincol#11 findcol::mincol#2 findcol::mincol#1 ] reg byte a [ findcol::$10 ] reg byte a [ findcol::$8 ] reg byte x [ findcol::i#12 findcol::i#1 ] zp byte:40 [ findcol::xp#0 ] zp byte:41 [ findcol::yp#0 ] zp byte:37 [ findcol::x#0 ] zp byte:38 [ findcol::y#0 ]
Limited combination testing to 10000 combinations of 559872 possible.
Uplifting [render] best 1690527 combination reg byte a [ render::col#0 ] zp byte:5 [ render::x#2 render::x#1 ] zp byte:2 [ render::y#2 render::y#1 ] zp ptr byte:3 [ render::colline#2 render::colline#1 ]
Uplifting [] best 1690527 combination zp byte:14 [ numpoints#19 numpoints#1 ]
@ -7698,30 +7756,30 @@ render__B2_from_B5:
//SEG117 [52] phi (byte) render::x#2 = (byte) render::x#1 -- register_copy
//SEG118 render::@2
render__B2:
//SEG119 [53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 numpoints#1 ] -- zpby1=zpby2
//SEG119 [53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 ] -- zpby1=zpby2
lda 5
sta 9
//SEG120 [54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 findcol::y#0 numpoints#1 ] -- zpby1=zpby2
//SEG120 [54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 ] -- zpby1=zpby2
lda 2
sta 10
//SEG121 [55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
//SEG121 [55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
jsr findcol
//SEG122 render::@5
render__B5:
//SEG123 [56] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 numpoints#1 ] -- aby=yby
//SEG123 [56] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 ] -- aby=yby
tya
//SEG124 [57] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 numpoints#1 ] -- zpptrby1_staridx_zpby1=aby
//SEG124 [57] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 ] -- zpptrby1_staridx_zpby1=aby
ldy 5
sta (3),y
//SEG125 [58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 render::colline#2 numpoints#1 ] -- zpby1=_inc_zpby1
//SEG125 [58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 render::colline#2 ] -- zpby1=_inc_zpby1
inc 5
//SEG126 [59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 numpoints#1 ] -- zpby1_lt_coby1_then_la1
//SEG126 [59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 ] -- zpby1_lt_coby1_then_la1
lda 5
cmp #40
bcc render__B2_from_B5
//SEG127 render::@3
render__B3:
//SEG128 [60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 numpoints#1 ] -- zpptrby1=zpptrby1_plus_coby1
//SEG128 [60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 ] -- zpptrby1=zpptrby1_plus_coby1
lda 3
clc
adc #40
@ -7729,9 +7787,9 @@ render__B3:
bcc !+
inc 3+1
!:
//SEG129 [61] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 numpoints#1 ] -- zpby1=_inc_zpby1
//SEG129 [61] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 ] -- zpby1=_inc_zpby1
inc 2
//SEG130 [62] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 numpoints#1 ] -- zpby1_lt_coby1_then_la1
//SEG130 [62] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 ] -- zpby1_lt_coby1_then_la1
lda 2
cmp #25
bcc render__B1_from_B3
@ -7828,7 +7886,7 @@ findcol__Breturn_from_B2:
ldy #0
//SEG171 findcol::@return
findcol__Breturn:
//SEG172 [80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
//SEG172 [80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
rts
//SEG173 findcol::@12
findcol__B12:
@ -8199,30 +8257,30 @@ render__B2_from_B5:
//SEG117 [52] phi (byte) render::x#2 = (byte) render::x#1 -- register_copy
//SEG118 render::@2
render__B2:
//SEG119 [53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 numpoints#1 ] -- zpby1=zpby2
//SEG119 [53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 ] -- zpby1=zpby2
lda 5
sta 9
//SEG120 [54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 findcol::y#0 numpoints#1 ] -- zpby1=zpby2
//SEG120 [54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 ] -- zpby1=zpby2
lda 2
sta 10
//SEG121 [55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
//SEG121 [55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
jsr findcol
//SEG122 render::@5
render__B5:
//SEG123 [56] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 numpoints#1 ] -- aby=yby
//SEG123 [56] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 ] -- aby=yby
tya
//SEG124 [57] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 numpoints#1 ] -- zpptrby1_staridx_zpby1=aby
//SEG124 [57] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 ] -- zpptrby1_staridx_zpby1=aby
ldy 5
sta (3),y
//SEG125 [58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 render::colline#2 numpoints#1 ] -- zpby1=_inc_zpby1
//SEG125 [58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 render::colline#2 ] -- zpby1=_inc_zpby1
inc 5
//SEG126 [59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 numpoints#1 ] -- zpby1_lt_coby1_then_la1
//SEG126 [59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 ] -- zpby1_lt_coby1_then_la1
lda 5
cmp #40
bcc render__B2_from_B5
//SEG127 render::@3
render__B3:
//SEG128 [60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 numpoints#1 ] -- zpptrby1=zpptrby1_plus_coby1
//SEG128 [60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 ] -- zpptrby1=zpptrby1_plus_coby1
lda 3
clc
adc #40
@ -8230,9 +8288,9 @@ render__B3:
bcc !+
inc 3+1
!:
//SEG129 [61] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 numpoints#1 ] -- zpby1=_inc_zpby1
//SEG129 [61] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 ] -- zpby1=_inc_zpby1
inc 2
//SEG130 [62] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 numpoints#1 ] -- zpby1_lt_coby1_then_la1
//SEG130 [62] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 ] -- zpby1_lt_coby1_then_la1
lda 2
cmp #25
bcc render__B1_from_B3
@ -8328,7 +8386,7 @@ findcol__Breturn_from_B2:
ldy #0
//SEG171 findcol::@return
findcol__Breturn:
//SEG172 [80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
//SEG172 [80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
rts
//SEG173 findcol::@12
findcol__B12:
@ -8513,11 +8571,11 @@ FINAL SYMBOL TABLE
(byte) findcol::return
(byte) findcol::return#0 reg byte y 3667.333333333333
(byte) findcol::x
(byte) findcol::x#0 zp byte:9 1782.8260869565217
(byte) findcol::x#0 zp byte:9 1952.6190476190475
(byte) findcol::xp
(byte) findcol::xp#0 zp byte:7 10001.0
(byte) findcol::y
(byte) findcol::y#0 zp byte:10 1863.8636363636363
(byte) findcol::y#0 zp byte:10 1952.6190476190475
(byte) findcol::yp
(byte) findcol::yp#0 zp byte:11 6250.625
(void()) initscreen()
@ -8538,7 +8596,7 @@ FINAL SYMBOL TABLE
(label) main::@8
(label) main::@return
(byte) numpoints
(byte) numpoints#1 zp byte:8 286.0857142857144
(byte) numpoints#1 zp byte:8 476.8095238095237
(byte) numpoints#19 zp byte:8 4.5
(void()) render()
(label) render::@1
@ -8861,30 +8919,30 @@ render__B2_from_B5:
//SEG117 [52] phi (byte) render::x#2 = (byte) render::x#1 -- register_copy
//SEG118 render::@2
render__B2:
//SEG119 [53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 numpoints#1 ] -- zpby1=zpby2
//SEG119 [53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 render::colline#2 ] -- zpby1=zpby2
lda 5
sta 9
//SEG120 [54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 findcol::y#0 numpoints#1 ] -- zpby1=zpby2
//SEG120 [54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 ] -- zpby1=zpby2
lda 2
sta 10
//SEG121 [55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
//SEG121 [55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
jsr findcol
//SEG122 render::@5
render__B5:
//SEG123 [56] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 numpoints#1 ] -- aby=yby
//SEG123 [56] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 ] -- aby=yby
tya
//SEG124 [57] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 numpoints#1 ] -- zpptrby1_staridx_zpby1=aby
//SEG124 [57] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 ] -- zpptrby1_staridx_zpby1=aby
ldy 5
sta (3),y
//SEG125 [58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 render::colline#2 numpoints#1 ] -- zpby1=_inc_zpby1
//SEG125 [58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 render::colline#2 ] -- zpby1=_inc_zpby1
inc 5
//SEG126 [59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 numpoints#1 ] -- zpby1_lt_coby1_then_la1
//SEG126 [59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 ] -- zpby1_lt_coby1_then_la1
lda 5
cmp #40
bcc render__B2_from_B5
//SEG127 render::@3
render__B3:
//SEG128 [60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 numpoints#1 ] -- zpptrby1=zpptrby1_plus_coby1
//SEG128 [60] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::y#2 ] -- zpptrby1=zpptrby1_plus_coby1
lda 3
clc
adc #40
@ -8892,9 +8950,9 @@ render__B3:
bcc !+
inc 3+1
!:
//SEG129 [61] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 numpoints#1 ] -- zpby1=_inc_zpby1
//SEG129 [61] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 ] -- zpby1=_inc_zpby1
inc 2
//SEG130 [62] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 numpoints#1 ] -- zpby1_lt_coby1_then_la1
//SEG130 [62] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 ] -- zpby1_lt_coby1_then_la1
lda 2
cmp #25
bcc render__B1_from_B3
@ -8990,7 +9048,7 @@ findcol__Breturn_from_B2:
ldy #0
//SEG171 findcol::@return
findcol__Breturn:
//SEG172 [80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 numpoints#1 ]
//SEG172 [80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
rts
//SEG173 findcol::@12
findcol__B12:

View File

@ -82,11 +82,11 @@
(byte) findcol::return
(byte) findcol::return#0 reg byte y 3667.333333333333
(byte) findcol::x
(byte) findcol::x#0 zp byte:9 1782.8260869565217
(byte) findcol::x#0 zp byte:9 1952.6190476190475
(byte) findcol::xp
(byte) findcol::xp#0 zp byte:7 10001.0
(byte) findcol::y
(byte) findcol::y#0 zp byte:10 1863.8636363636363
(byte) findcol::y#0 zp byte:10 1952.6190476190475
(byte) findcol::yp
(byte) findcol::yp#0 zp byte:11 6250.625
(void()) initscreen()
@ -107,7 +107,7 @@
(label) main::@8
(label) main::@return
(byte) numpoints
(byte) numpoints#1 zp byte:8 286.0857142857144
(byte) numpoints#1 zp byte:8 476.8095238095237
(byte) numpoints#19 zp byte:8 4.5
(void()) render()
(label) render::@1

View File

@ -1,6 +1,7 @@
byte s1=sum(1,2);
byte s2=sum(9,13);
byte s3=s1+s2;
byte s2=sum(3,4);
byte s3=sum(9,13);
byte s4=s1+s2+s3;
byte sum(byte a, byte b) {
return a+b;
}