1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-20 23:30:43 +00:00

Implemented ability of procedures to modify globals

This commit is contained in:
jespergravgaard 2017-08-12 00:15:59 +02:00
parent 867d78fd31
commit fc859e8a03
42 changed files with 2217 additions and 944 deletions

View File

@ -217,9 +217,13 @@ public class Compiler {
log.append(program.getGraph().toString(program));
}
(new Pass1ModifiedVarsAnalysis(program)).findModifiedVars();
log.append("PROCEDURE MODIFY VARIABLE ANALYSIS");
log.append(program.getProcedureModifiedVars().toString(program));
Pass1ProcedureCallParameters pass1ProcedureCallParameters =
new Pass1ProcedureCallParameters(program);
program.setGraph(pass1ProcedureCallParameters.generate());
pass1ProcedureCallParameters.generate();
log.append("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL");
log.append(program.getGraph().toString(program));

View File

@ -31,20 +31,20 @@ 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 doew not work. Outer vars must be transfered in/out like parameters/return values to get it working.
- 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
- Limit number of combinations tested
- Equivalences not tested through combinaitons should be tested individually afterwards.
- Allow user to limit number of combinations tested
- Safe-Copy based SSA deconstruction
- Reuse phi-transitions that are identical
- Optimize phi transitions by ensuring that identical phi-transitions with regards to register allocation are collected into a single transition.
- Optimize by finding optimal sequence for multiple phi assignments in entry-segments.
- Avoid clobbering alive vars
- Maybe support several fragements for the same operation with different cost and clobbering profiles.
- Maybe support several fragments for the same operation with different cost and clobbering profiles.
- Add memory registers (if we need to free some ZP)
+ Limit number of combinations tested
+ Equivalences not tested through combinaitons should be tested individually afterwards.
+ Matrix Phi operation (instead of separate statements)
+ Phi Lifting
+ PhiLifting & PhiMemCoalesce (http://compilers.cs.ucla.edu/fernando/projects/soc/reports/short_tech.pdf)

View File

@ -191,7 +191,10 @@ public class CallGraph {
@Override
public String toString() {
StringBuilder out = new StringBuilder();
out.append(callStatementIdx).append(":").append(procedure);
if(callStatementIdx!=null) {
out.append(callStatementIdx).append(":");
}
out.append(procedure);
return out.toString();
}

View File

@ -52,6 +52,10 @@ public class ControlFlowBlock {
this.statements.add(statement);
}
public void addStatementBeforeLast(Statement statement) {
this.statements.add(statements.size()-1, statement);
}
public void setDefaultSuccessor(LabelRef defaultSuccessor) {
this.defaultSuccessor = defaultSuccessor;
}
@ -178,4 +182,5 @@ public class ControlFlowBlock {
}
return successors;
}
}

View File

@ -208,4 +208,19 @@ public class ControlFlowGraph {
return null;
}
/**
* Get all blocks stat are part of the execution of a specific scope. (mostly a procedure)
* @param scopeLabel The label of the scope to find blocks for
* @return All blocks that are part of the execution of the scope
*/
public List<ControlFlowBlock> getScopeBlocks(LabelRef scopeLabel) {
ArrayList<ControlFlowBlock> scopeBlocks = new ArrayList<>();
for (ControlFlowBlock block : getAllBlocks()) {
if(block.getLabel().getFullName().equals(scopeLabel.getFullName()) || block.getLabel().getScopeNames().equals(scopeLabel.getFullName())) {
scopeBlocks.add(block);
}
}
return scopeBlocks;
}
}

View File

@ -108,6 +108,10 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
return copyBlock;
}
public ControlFlowBlock getOrigBlock() {
return origBlock;
}
@Override
public Statement visitStatement(Statement statement) {
return (Statement) super.visitStatement(statement);

View File

@ -0,0 +1,30 @@
package dk.camelot64.kickc.icl;
import java.util.*;
/**
* Contains all variables modified inside procedures. Contain the unversioned VariableRefs.
*/
public class ProcedureModifiedVars {
private Map<ProcedureRef, Set<VariableRef>> modified;
public ProcedureModifiedVars(Map<ProcedureRef, Set<VariableRef>> modified) {
this.modified = modified;
}
public Set<VariableRef> getModifiedVars(ProcedureRef procedure) {
return modified.get(procedure);
}
public String toString(Program program) {
StringBuilder out = new StringBuilder();
for (ProcedureRef procedureRef : modified.keySet()) {
for (VariableRef variableRef : getModifiedVars(procedureRef)) {
out.append(procedureRef.getFullName()).append(" modifies "+variableRef.getFullName()).append("\n");
}
}
return out.toString();
}
}

View File

@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.asm.AsmProgram;
import dk.camelot64.kickc.passes.Pass1ModifiedVarsAnalysis;
/** A KickC Intermediate Compiler Language (ICL) Program */
public class Program {
@ -18,6 +19,8 @@ public class Program {
/** The log containing information about the compilation process. */
private CompileLog log;
/** Variables modified inside procedures. */
private ProcedureModifiedVars procedureModifiedVars;
/** Information about calls. */
private CallGraph callGraph;
/** Information about dominators of all blocks*/
@ -69,6 +72,15 @@ public class Program {
this.graph = graph;
}
public void setProcedureModifiedVars(ProcedureModifiedVars procedureModifiedVars) {
this.procedureModifiedVars = procedureModifiedVars;
}
public ProcedureModifiedVars getProcedureModifiedVars() {
return procedureModifiedVars;
}
public AsmProgram getAsm() {
return asm;
}

View File

@ -191,6 +191,16 @@ public abstract class Scope implements Symbol {
return scopes;
}
public Collection<Procedure> getAllProcedures(boolean includeSubScopes) {
Collection<Procedure> procedures = new ArrayList<>();
for (Scope scope : getAllScopes(includeSubScopes)) {
if(scope instanceof Procedure) {
procedures.add((Procedure) scope);
}
}
return procedures;
}
public Label addLabel(String name) {
Label symbol = new Label(name, this, false);

View File

@ -93,4 +93,13 @@ public class SymbolRef implements Value {
public String toString() {
return getFullName();
}
public String getFullNameUnversioned() {
if(isVersion()) {
return fullName.substring(0, fullName.indexOf("#"));
} else {
return fullName;
}
}
}

View File

@ -0,0 +1,57 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.icl.*;
import java.util.*;
/** Find all variables from an outer scope modified in an inner scope (ie. a procedure) */
public class Pass1ModifiedVarsAnalysis {
private Program program;
public Pass1ModifiedVarsAnalysis(Program program) {
this.program = program;
}
public void findModifiedVars() {
Map<ProcedureRef, Set<VariableRef>> modified = new LinkedHashMap<>();
Collection<Procedure> allProcedures = program.getScope().getAllProcedures(true);
for (Procedure procedure : allProcedures) {
Set<VariableRef> modifiedVars = getModifiedVars(procedure);
modified.put(procedure.getRef(), modifiedVars);
}
program.setProcedureModifiedVars(new ProcedureModifiedVars(modified));
}
/** Get all outside variables modified by a procedure (or any sub-procedure called by the procedure).
*
* @param procedure The procedure to examine
* @return All variables declared outside the procedure modified inside the procedure.
*/
public Set<VariableRef> getModifiedVars(Procedure procedure) {
Set<VariableRef> modified = new LinkedHashSet<>();
LabelRef procScope = procedure.getScopeLabelRef();
List<ControlFlowBlock> procBlocks = program.getGraph().getScopeBlocks(procScope);
for (ControlFlowBlock block : procBlocks) {
for (Statement statement : block.getStatements()) {
if(statement instanceof StatementLValue) {
LValue lValue = ((StatementLValue) statement).getlValue();
if(lValue instanceof VariableRef) {
VariableRef var = (VariableRef) lValue;
if(!var.getScopeNames().equals(procScope.getFullName())) {
modified.add(var);
}
}
if(statement instanceof StatementCall) {
ProcedureRef called = ((StatementCall) statement).getProcedure();
Procedure calledProc = program.getScope().getProcedure(called);
modified.addAll(getModifiedVars(calledProc));
}
}
}
}
return modified;
}
}

View File

@ -2,22 +2,27 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.icl.*;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/** Pass that modifies a control flow graph to call procedures by passing parameters through registers */
public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
private ProgramScope scope;
private ControlFlowGraph graph;
private Program program;
public Pass1ProcedureCallParameters(Program program) {
this.scope = program.getScope();
this.graph = program.getGraph();
this.program = program;
}
public ControlFlowGraph generate() {
ControlFlowGraph generated = visitGraph(graph);
return generated;
public void generate() {
ControlFlowGraph generated = visitGraph(program.getGraph());
program.setGraph(generated);
}
private ProgramScope getScope() {
return program.getScope();
}
@Override
@ -25,7 +30,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
// Procedure strategy implemented is currently variable-based transfer of parameters/return values
// Generate parameter passing assignments
ProcedureRef procedureRef = origCall.getProcedure();
Procedure procedure = scope.getProcedure(procedureRef);
Procedure procedure = getScope().getProcedure(procedureRef);
List<Variable> parameterDecls = procedure.getParameters();
List<RValue> parameterValues = origCall.getParameters();
for (int i = 0; i < parameterDecls.size(); i++) {
@ -44,7 +49,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
copyCall.setProcedure(procedureRef);
addStatementToCurrentBlock(copyCall);
getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
Symbol currentBlockSymbol = scope.getSymbol(getCurrentBlock().getLabel());
Symbol currentBlockSymbol = getScope().getSymbol(getCurrentBlock().getLabel());
Scope currentBlockScope;
if(currentBlockSymbol instanceof Procedure) {
currentBlockScope = (Scope) currentBlockSymbol;
@ -59,13 +64,31 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
LValue lValue = origCall.getlValue();
if(lValue instanceof VariableRef) {
VariableRef lValueRef = (VariableRef) lValue;
Variable lValueVar = scope.getVariable(lValueRef);
Variable lValueVar = getScope().getVariable(lValueRef);
lValueVar.getScope().remove(lValueVar);
}
}
// Add self-assignments for all variables modified in the procedure
Set<VariableRef> modifiedVars = program.getProcedureModifiedVars().getModifiedVars(procedure.getRef());
for (VariableRef modifiedVar : modifiedVars) {
addStatementToCurrentBlock(new StatementAssignment(modifiedVar, modifiedVar));
}
return null;
}
@Override
public StatementReturn visitReturn(StatementReturn origReturn) {
ControlFlowBlock currentBlock = getCurrentBlock();
String currentProcName = currentBlock.getLabel().getScopeNames();
Procedure procedure = program.getScope().getProcedure(currentProcName);
// Add self-assignments for all variables modified in the procedure
Set<VariableRef> modifiedVars = program.getProcedureModifiedVars().getModifiedVars(procedure.getRef());
for (VariableRef modifiedVar : modifiedVars) {
addStatementToCurrentBlock(new StatementAssignment(modifiedVar, modifiedVar));
}
return super.visitReturn(origReturn);
}
}

View File

@ -2,19 +2,24 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.icl.*;
/** Pass that modifies a control flow graph to call procedures by passing return value through registers */
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* Pass that modifies a control flow graph to call procedures by passing return value through registers
*/
public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor {
private ProgramScope scope;
private ControlFlowGraph graph;
private Program program;
public Pass1ProcedureCallsReturnValue(Program program) {
this.scope = program.getScope();
this.graph = program.getGraph();
this.program = program;
}
public ControlFlowGraph generate() {
ControlFlowGraph generated = visitGraph(graph);
ControlFlowGraph generated = visitGraph(program.getGraph());
return generated;
}
@ -23,7 +28,7 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
// Procedure strategy implemented is currently variable-based transfer of parameters/return values
// Generate return value assignment
ProcedureRef procedureRef = origCall.getProcedure();
Procedure procedure = scope.getProcedure(procedureRef);
Procedure procedure = program.getScope().getProcedure(procedureRef);
String procedureName = origCall.getProcedureName();
StatementCall copyCall = new StatementCall(null, procedureName, null);
copyCall.setParametersByAssignment(true);
@ -33,7 +38,7 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
if (!SymbolTypeBasic.VOID.equals(procedure.getReturnType())) {
// Find return variable final version
Label returnBlockLabel = procedure.getLabel("@return");
ControlFlowBlock returnBlock = graph.getBlock(returnBlockLabel.getRef());
ControlFlowBlock returnBlock = program.getGraph().getBlock(returnBlockLabel.getRef());
VariableRef returnVarFinal = null;
for (Statement statement : returnBlock.getStatements()) {
if (statement instanceof StatementReturn) {
@ -50,9 +55,50 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
StatementAssignment returnAssignment = new StatementAssignment(origCall.getlValue(), returnVarFinal);
addStatementToCurrentBlock(returnAssignment);
}
// Patch versions of rValues in assignments for vars modified in the call
LabelRef successor = getOrigBlock().getDefaultSuccessor();
ControlFlowBlock successorBlock = program.getGraph().getBlock(successor);
Set<VariableRef> modifiedVars = program.getProcedureModifiedVars().getModifiedVars(procedure.getRef());
for (Statement statement : successorBlock.getStatements()) {
if (statement instanceof StatementPhiBlock) {
StatementPhiBlock phiBlock = (StatementPhiBlock) statement;
for (StatementPhiBlock.PhiVariable phiVariable : phiBlock.getPhiVariables()) {
VariableRef phiVar = phiVariable.getVariable();
VariableRef unversionedVar = new VariableRef(phiVar.getFullNameUnversioned());
if (modifiedVars.contains(unversionedVar)) {
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
if (phiRValue.getPredecessor().equals(getOrigBlock().getLabel())) {
VariableRef procReturnVersion = findReturnVersion(procedure, unversionedVar);
phiRValue.setrValue(procReturnVersion);
}
}
}
}
}
}
return null;
}
private VariableRef findReturnVersion(Procedure procedure, VariableRef assignedVar) {
String unversionedName = assignedVar.getFullNameUnversioned();
LabelRef returnBlock = new LabelRef(procedure.getScopeLabelRef().getFullName() + "::@return");
ControlFlowBlock block = program.getGraph().getBlock(returnBlock);
for (Statement statement : block.getStatements()) {
if (statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;
if (assignment.getlValue() instanceof VariableRef) {
VariableRef lValue = (VariableRef) assignment.getlValue();
if (lValue.getFullNameUnversioned().equals(unversionedName)) {
return lValue;
}
}
}
}
throw new RuntimeException("Variable " + assignedVar + "modified by procedure " + procedure + " not found in @return block " + block.getLabel());
}
@Override
public StatementReturn visitReturn(StatementReturn origReturn) {
addStatementToCurrentBlock(new StatementReturn(null));

View File

@ -1,6 +1,5 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.icl.*;
/** Finds the call graph for the control flow graph - identifies all calls in all scopes and creates a graph from these. */
@ -13,7 +12,6 @@ public class Pass3CallGraphAnalysis extends Pass2Base {
public void findCallGraph() {
CallGraph callGraph = new CallGraph();
for (ControlFlowBlock block : getGraph().getAllBlocks()) {
LabelRef scopeRef = getScopeRef(block, getProgram());
for (Statement statement : block.getStatements()) {

View File

@ -22,16 +22,16 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
LiveRangeVariables liveRanges = initializeLiveRanges();
getProgram().setLiveRangeVariables(liveRanges);
//log.append("CONTROL FLOW GRAPH - LIVE RANGES");
//log.append(program.getGraph().toString(program.getScope()));
//getLog().append("CONTROL FLOW GRAPH - LIVE RANGES");
//getLog().append(getProgram().getGraph().toString(getProgram()));
boolean propagating;
do {
propagating = propagateLiveRanges(liveRanges);
getProgram().setLiveRangeVariables(liveRanges);
getLog().append("Propagating live ranges...");
//log.append("CONTROL FLOW GRAPH - LIVE RANGES");
//log.append(program.getGraph().toString(program.getScope()));
//getLog().append("CONTROL FLOW GRAPH - LIVE RANGES");
//getLog().append(getProgram().getGraph().toString(getProgram()));
} while (propagating);
getProgram().setLiveRangeVariables(liveRanges);
@ -137,11 +137,20 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
LabelRef predecessorRef = phiRValue.getPredecessor();
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())) {
// Add to last statement before call in predecessor
StatementCall callStatement = (StatementCall) predecessorStatements.get(predecessorStatements.size() - 1);
Statement predecessorLastStatementBeforeCall = predecessorStatements.get(predecessorStatements.size() - 2);
liveRanges.addAlive((VariableRef) phiRValue.getrValue(), predecessorLastStatementBeforeCall);
} else {
// Add to last statement of predecessor
Statement predecessorLastStatement = predecessorStatements.get(predecessorStatements.size() - 1);
liveRanges.addAlive((VariableRef) phiRValue.getrValue(), predecessorLastStatement);
}
}
}
}
return null;
}
@ -315,11 +324,19 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
ArrayList<Statement> 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);
}
}
return statements;
}
@ -356,8 +373,9 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
@Override
public Void visitCall(StatementCall call) {
propagate(call, getPreviousStatements(), null);
// Also propagate back through all statements of the procedure
// Do not propagate directly to previous statement
//propagate(call, getPreviousStatements(), null);
// Instead propagate back through all statements of the procedure
ProcedureRef procedure = call.getProcedure();
LabelRef procedureReturnBlock = procedure.getReturnBlock();
ControlFlowBlock returnBlock = program.getGraph().getBlock(procedureReturnBlock);

View File

@ -1,6 +1,5 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.icl.*;
import java.util.Collection;
@ -85,6 +84,9 @@ public class Pass3PhiLifting {
newBlockStatements.add(newAssignment);
phiRValue.setrValue(newVar.getRef());
phiRValue.setPredecessor(newBlock.getLabel());
} else if(block.getLabel().equals(predecessorBlock.getCallSuccessor())) {
predecessorBlock.addStatementBeforeLast(newAssignment);
phiRValue.setrValue(newVar.getRef());
} else {
predecessorBlock.addStatement(newAssignment);
phiRValue.setrValue(newVar.getRef());

View File

@ -94,7 +94,7 @@ public class Pass3RegisterUpliftCombinations extends Pass2Base {
}
private int getAsmScore(Program program) {
public static int getAsmScore(Program program) {
int score = 0;
AsmProgram asm = program.getAsm();
ControlFlowGraph graph = program.getGraph();
@ -103,8 +103,11 @@ public class Pass3RegisterUpliftCombinations extends Pass2Base {
double asmSegmentCycles = asmSegment.getCycles();
if (asmSegmentCycles > 0) {
Integer statementIdx = asmSegment.getStatementIdx();
int maxLoopDepth=1;
if(statementIdx!=null) {
ControlFlowBlock block = graph.getBlockFromStatementIdx(statementIdx);
int maxLoopDepth = loopSet.getMaxLoopDepth(block.getLabel());
maxLoopDepth = loopSet.getMaxLoopDepth(block.getLabel());
}
score += asmSegmentCycles * Math.pow(10, maxLoopDepth);
}
}

View File

@ -61,7 +61,7 @@ public class Pass3RegisterUpliftRemains extends Pass2Base {
}
// If no clobber - Find value of the resulting allocation
boolean hasClobberProblem = new Pass3AssertNoCpuClobber(getProgram()).hasClobberProblem(false);
int combinationScore = getAsmScore(getProgram());
int combinationScore = Pass3RegisterUpliftCombinations.getAsmScore(getProgram());
//StringBuilder msg = new StringBuilder();
//msg.append("Uplift remains attempt [" + equivalenceClass + "] ");
//if (hasClobberProblem) {
@ -97,21 +97,4 @@ public class Pass3RegisterUpliftRemains extends Pass2Base {
}
private int getAsmScore(Program program) {
int score = 0;
AsmProgram asm = program.getAsm();
ControlFlowGraph graph = program.getGraph();
NaturalLoopSet loopSet = program.getLoopSet();
for (AsmSegment asmSegment : asm.getSegments()) {
double asmSegmentCycles = asmSegment.getCycles();
if (asmSegmentCycles > 0) {
Integer statementIdx = asmSegment.getStatementIdx();
ControlFlowBlock block = graph.getBlockFromStatementIdx(statementIdx);
int maxLoopDepth = loopSet.getMaxLoopDepth(block.getLabel());
score += asmSegmentCycles * Math.pow(10, maxLoopDepth);
}
}
return score;
}
}

View File

@ -76,6 +76,10 @@ public class TestCompilationOutput extends TestCase {
compileAndCompare("useglobal");
}
public void testModGlobal() throws IOException, URISyntaxException {
compileAndCompare("modglobal");
}
public void testUseUninitialized() throws IOException, URISyntaxException {
String filename = "useuninitialized";
compileAndCompare(filename);

View File

@ -0,0 +1,20 @@
byte cnt = 0;
byte cnt2 = 0;
byte[256] SCREEN=$0400;
main();
void main() {
SCREEN[0]=inccnt();
cnt++;
SCREEN[1]=inccnt();
}
byte inccnt() {
++cnt;
++cnt2;
return cnt;
}

View File

@ -199,6 +199,8 @@ CONTROL FLOW GRAPH
to:@END
@END: from @3
PROCEDURE MODIFY VARIABLE ANALYSIS
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte) STAR ← (byte) 81

View File

@ -81,6 +81,8 @@ CONTROL FLOW GRAPH
to:@END
@END: from @1
PROCEDURE MODIFY VARIABLE ANALYSIS
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte[15]) fibs ← (word) 4352

View File

@ -484,6 +484,8 @@ plot::@return: from plot::@3
to:@RETURN
@END: from @BEGIN
PROCEDURE MODIFY VARIABLE ANALYSIS
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte[1000]) SCREEN ← (word) 1024

View File

@ -81,6 +81,8 @@ CONTROL FLOW GRAPH
to:@END
@END: from @3
PROCEDURE MODIFY VARIABLE ANALYSIS
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte) i ← (byte) 10

View File

@ -131,6 +131,8 @@ nest::@return: from nest::@1
to:@RETURN
@END: from @BEGIN
PROCEDURE MODIFY VARIABLE ANALYSIS
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte*) SCREEN ← (word) 1024
@ -646,6 +648,7 @@ Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
CONTROL FLOW GRAPH - PHI MEM COALESCED
@BEGIN: from
[0] call main param-assignment [ ]

View File

@ -269,6 +269,8 @@ nest2::@return: from nest2::@3
to:@RETURN
@END: from @BEGIN
PROCEDURE MODIFY VARIABLE ANALYSIS
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte*) SCREEN ← (word) 1024
@ -1550,6 +1552,9 @@ Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
CONTROL FLOW GRAPH - LIVE RANGES
@BEGIN: from
[0] call main param-assignment [ ]
@ -1662,6 +1667,10 @@ Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
CONTROL FLOW GRAPH - PHI MEM COALESCED
@BEGIN: from
[0] call main param-assignment [ ]

View File

@ -139,6 +139,8 @@ main::@return: from main::@1
to:@RETURN
@END: from @BEGIN
PROCEDURE MODIFY VARIABLE ANALYSIS
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
call main param-assignment

View File

@ -61,6 +61,8 @@ CONTROL FLOW GRAPH
to:@END
@END: from @1
PROCEDURE MODIFY VARIABLE ANALYSIS
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte[16]) p ← (word) 4352

View File

@ -0,0 +1,23 @@
BBEGIN:
jsr main
BEND:
main:
inccnt_from_main:
ldy #0
ldx #0
jsr inccnt
main__B1:
sta 1024
inx
inccnt_from_B1:
jsr inccnt
main__B2:
sta 1025
main__Breturn:
rts
inccnt:
inx
iny
txa
inccnt__Breturn:
rts

View File

@ -0,0 +1,30 @@
@BEGIN: from
[0] call main param-assignment [ ]
to:@END
@END: from @BEGIN
main: from @BEGIN
[1] call inccnt param-assignment [ inccnt::return#0 cnt#1 cnt2#1 ]
to:main::@1
main::@1: from main
[2] (byte~) main::$0 ← (byte) inccnt::return#0 [ main::$0 cnt#1 cnt2#1 ]
[3] *((word) 1024) ← (byte~) main::$0 [ cnt#1 cnt2#1 ]
[4] (byte) cnt#3 ← ++ (byte) cnt#1 [ cnt#3 cnt2#1 ]
[5] call inccnt param-assignment [ inccnt::return#0 ]
to:main::@2
main::@2: from main::@1
[6] (byte~) main::$1 ← (byte) inccnt::return#0 [ main::$1 ]
[7] *((word) 1025) ← (byte~) main::$1 [ ]
to:main::@return
main::@return: from main::@2
[8] return [ ]
to:@RETURN
inccnt: from main main::@1
[9] (byte) cnt2#11 ← phi( main/(byte) 0 main::@1/(byte) cnt2#1 ) [ cnt#12 cnt2#11 ]
[9] (byte) cnt#12 ← phi( main/(byte) 0 main::@1/(byte) cnt#3 ) [ cnt#12 cnt2#11 ]
[10] (byte) cnt#1 ← ++ (byte) cnt#12 [ cnt#1 cnt2#11 ]
[11] (byte) cnt2#1 ← ++ (byte) cnt2#11 [ cnt#1 cnt2#1 ]
[12] (byte) inccnt::return#0 ← (byte) cnt#1 [ inccnt::return#0 cnt#1 cnt2#1 ]
to:inccnt::@return
inccnt::@return: from inccnt
[13] return [ inccnt::return#0 cnt#1 cnt2#1 ]
to:@RETURN

View File

@ -0,0 +1,955 @@
byte cnt = 0;
byte cnt2 = 0;
byte[256] SCREEN=$0400;
main();
void main() {
SCREEN[0]=inccnt();
cnt++;
SCREEN[1]=inccnt();
}
byte inccnt() {
++cnt;
++cnt2;
return cnt;
}
Adding pre/post-modifier (byte) cnt ← ++ (byte) cnt
Adding pre/post-modifier (byte) cnt ← ++ (byte) cnt
Adding pre/post-modifier (byte) cnt2 ← ++ (byte) cnt2
PROGRAM
(byte) cnt ← (byte) 0
(byte) cnt2 ← (byte) 0
(byte[256]) SCREEN ← (word) 1024
(void~) $0 ← call main
proc (void()) main()
(byte~) main::$0 ← call inccnt
*((byte[256]) SCREEN + (byte) 0) ← (byte~) main::$0
(byte) cnt ← ++ (byte) cnt
(byte~) main::$1 ← call inccnt
*((byte[256]) SCREEN + (byte) 1) ← (byte~) main::$1
main::@return:
return
endproc // main()
proc (byte()) inccnt()
(byte) cnt ← ++ (byte) cnt
(byte) cnt2 ← ++ (byte) cnt2
(byte) inccnt::return ← (byte) cnt
goto inccnt::@return
inccnt::@return:
(byte) inccnt::return ← (byte) inccnt::return
return (byte) inccnt::return
endproc // inccnt()
SYMBOLS
(void~) $0
(byte[256]) SCREEN
(byte) cnt
(byte) cnt2
(byte()) inccnt()
(label) inccnt::@return
(byte) inccnt::return
(void()) main()
(byte~) main::$0
(byte~) main::$1
(label) main::@return
INITIAL CONTROL FLOW GRAPH
@BEGIN: from
(byte) cnt ← (byte) 0
(byte) cnt2 ← (byte) 0
(byte[256]) SCREEN ← (word) 1024
(void~) $0 ← call main
to:@1
main: from
(byte~) main::$0 ← call inccnt
*((byte[256]) SCREEN + (byte) 0) ← (byte~) main::$0
(byte) cnt ← ++ (byte) cnt
(byte~) main::$1 ← call inccnt
*((byte[256]) SCREEN + (byte) 1) ← (byte~) main::$1
to:main::@return
main::@return: from main
return
to:@RETURN
@1: from @BEGIN
to:@2
inccnt: from
(byte) cnt ← ++ (byte) cnt
(byte) cnt2 ← ++ (byte) cnt2
(byte) inccnt::return ← (byte) cnt
to:inccnt::@return
inccnt::@return: from inccnt inccnt::@1
(byte) inccnt::return ← (byte) inccnt::return
return (byte) inccnt::return
to:@RETURN
inccnt::@1: from
to:inccnt::@return
@2: from @1
to:@END
@END: from @2
Removing empty block @1
Removing empty block inccnt::@1
Removing empty block @2
CONTROL FLOW GRAPH
@BEGIN: from
(byte) cnt ← (byte) 0
(byte) cnt2 ← (byte) 0
(byte[256]) SCREEN ← (word) 1024
(void~) $0 ← call main
to:@END
main: from
(byte~) main::$0 ← call inccnt
*((byte[256]) SCREEN + (byte) 0) ← (byte~) main::$0
(byte) cnt ← ++ (byte) cnt
(byte~) main::$1 ← call inccnt
*((byte[256]) SCREEN + (byte) 1) ← (byte~) main::$1
to:main::@return
main::@return: from main
return
to:@RETURN
inccnt: from
(byte) cnt ← ++ (byte) cnt
(byte) cnt2 ← ++ (byte) cnt2
(byte) inccnt::return ← (byte) cnt
to:inccnt::@return
inccnt::@return: from inccnt
(byte) inccnt::return ← (byte) inccnt::return
return (byte) inccnt::return
to:@RETURN
@END: from @BEGIN
PROCEDURE MODIFY VARIABLE ANALYSIS
main modifies cnt
main modifies cnt2
inccnt modifies cnt
inccnt modifies cnt2
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte) cnt ← (byte) 0
(byte) cnt2 ← (byte) 0
(byte[256]) SCREEN ← (word) 1024
call main param-assignment
to:@3
@3: from @BEGIN
(byte) cnt ← (byte) cnt
(byte) cnt2 ← (byte) cnt2
to:@END
main: from @BEGIN
(byte) inccnt::return ← call inccnt param-assignment
to:main::@1
main::@1: from main
(byte~) main::$0 ← (byte) inccnt::return
(byte) cnt ← (byte) cnt
(byte) cnt2 ← (byte) cnt2
*((byte[256]) SCREEN + (byte) 0) ← (byte~) main::$0
(byte) cnt ← ++ (byte) cnt
(byte) inccnt::return ← call inccnt param-assignment
to:main::@2
main::@2: from main::@1
(byte~) main::$1 ← (byte) inccnt::return
(byte) cnt ← (byte) cnt
(byte) cnt2 ← (byte) cnt2
*((byte[256]) SCREEN + (byte) 1) ← (byte~) main::$1
to:main::@return
main::@return: from main::@2
(byte) cnt ← (byte) cnt
(byte) cnt2 ← (byte) cnt2
return
to:@RETURN
inccnt: from main main::@1
(byte) cnt ← ++ (byte) cnt
(byte) cnt2 ← ++ (byte) cnt2
(byte) inccnt::return ← (byte) cnt
to:inccnt::@return
inccnt::@return: from inccnt
(byte) inccnt::return ← (byte) inccnt::return
(byte) cnt ← (byte) cnt
(byte) cnt2 ← (byte) cnt2
return (byte) inccnt::return
to:@RETURN
@END: from @3
Completing Phi functions...
Completing Phi functions...
CONTROL FLOW GRAPH SSA
@BEGIN: from
(byte) cnt#0 ← (byte) 0
(byte) cnt2#0 ← (byte) 0
(byte[256]) SCREEN#0 ← (word) 1024
call main param-assignment
to:@3
@3: from @BEGIN
(byte) cnt2#7 ← phi( @BEGIN/(byte) cnt2#0 )
(byte) cnt#8 ← phi( @BEGIN/(byte) cnt#0 )
(byte) cnt#1 ← (byte) cnt#8
(byte) cnt2#1 ← (byte) cnt2#7
to:@END
main: from @BEGIN
(byte[256]) SCREEN#3 ← phi( @BEGIN/(byte[256]) SCREEN#0 )
(byte) cnt2#13 ← phi( @BEGIN/(byte) cnt2#0 )
(byte) cnt#14 ← phi( @BEGIN/(byte) cnt#0 )
(byte) inccnt::return#0 ← call inccnt param-assignment
to:main::@1
main::@1: from main
(byte[256]) SCREEN#1 ← phi( main/(byte[256]) SCREEN#3 )
(byte) cnt2#8 ← phi( main/(byte) cnt2#13 )
(byte) cnt#9 ← phi( main/(byte) cnt#14 )
(byte) inccnt::return#4 ← phi( main/(byte) inccnt::return#0 )
(byte~) main::$0 ← (byte) inccnt::return#4
(byte) cnt#2 ← (byte) cnt#9
(byte) cnt2#2 ← (byte) cnt2#8
*((byte[256]) SCREEN#1 + (byte) 0) ← (byte~) main::$0
(byte) cnt#3 ← ++ (byte) cnt#2
(byte) inccnt::return#1 ← call inccnt param-assignment
to:main::@2
main::@2: from main::@1
(byte[256]) SCREEN#2 ← phi( main::@1/(byte[256]) SCREEN#1 )
(byte) cnt2#9 ← phi( main::@1/(byte) cnt2#2 )
(byte) cnt#10 ← phi( main::@1/(byte) cnt#3 )
(byte) inccnt::return#5 ← phi( main::@1/(byte) inccnt::return#1 )
(byte~) main::$1 ← (byte) inccnt::return#5
(byte) cnt#4 ← (byte) cnt#10
(byte) cnt2#3 ← (byte) cnt2#9
*((byte[256]) SCREEN#2 + (byte) 1) ← (byte~) main::$1
to:main::@return
main::@return: from main::@2
(byte) cnt2#10 ← phi( main::@2/(byte) cnt2#3 )
(byte) cnt#11 ← phi( main::@2/(byte) cnt#4 )
(byte) cnt#5 ← (byte) cnt#11
(byte) cnt2#4 ← (byte) cnt2#10
return
to:@RETURN
inccnt: from main main::@1
(byte) cnt2#11 ← phi( main/(byte) cnt2#13 main::@1/(byte) cnt2#2 )
(byte) cnt#12 ← phi( main/(byte) cnt#14 main::@1/(byte) cnt#3 )
(byte) cnt#6 ← ++ (byte) cnt#12
(byte) cnt2#5 ← ++ (byte) cnt2#11
(byte) inccnt::return#2 ← (byte) cnt#6
to:inccnt::@return
inccnt::@return: from inccnt
(byte) cnt2#12 ← phi( inccnt/(byte) cnt2#5 )
(byte) cnt#13 ← phi( inccnt/(byte) cnt#6 )
(byte) inccnt::return#6 ← phi( inccnt/(byte) inccnt::return#2 )
(byte) inccnt::return#3 ← (byte) inccnt::return#6
(byte) cnt#7 ← (byte) cnt#13
(byte) cnt2#6 ← (byte) cnt2#12
return (byte) inccnt::return#3
to:@RETURN
@END: from @3
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
@BEGIN: from
(byte) cnt#0 ← (byte) 0
(byte) cnt2#0 ← (byte) 0
(byte[256]) SCREEN#0 ← (word) 1024
call main param-assignment
to:@3
@3: from @BEGIN
(byte) cnt2#7 ← phi( @BEGIN/(byte) cnt2#4 )
(byte) cnt#8 ← phi( @BEGIN/(byte) cnt#5 )
(byte) cnt#1 ← (byte) cnt#8
(byte) cnt2#1 ← (byte) cnt2#7
to:@END
main: from @BEGIN
(byte[256]) SCREEN#3 ← phi( @BEGIN/(byte[256]) SCREEN#0 )
(byte) cnt2#13 ← phi( @BEGIN/(byte) cnt2#0 )
(byte) cnt#14 ← phi( @BEGIN/(byte) cnt#0 )
call inccnt param-assignment
(byte) inccnt::return#0 ← (byte) inccnt::return#3
to:main::@1
main::@1: from main
(byte[256]) SCREEN#1 ← phi( main/(byte[256]) SCREEN#3 )
(byte) cnt2#8 ← phi( main/(byte) cnt2#6 )
(byte) cnt#9 ← phi( main/(byte) cnt#7 )
(byte) inccnt::return#4 ← phi( main/(byte) inccnt::return#0 )
(byte~) main::$0 ← (byte) inccnt::return#4
(byte) cnt#2 ← (byte) cnt#9
(byte) cnt2#2 ← (byte) cnt2#8
*((byte[256]) SCREEN#1 + (byte) 0) ← (byte~) main::$0
(byte) cnt#3 ← ++ (byte) cnt#2
call inccnt param-assignment
(byte) inccnt::return#1 ← (byte) inccnt::return#3
to:main::@2
main::@2: from main::@1
(byte[256]) SCREEN#2 ← phi( main::@1/(byte[256]) SCREEN#1 )
(byte) cnt2#9 ← phi( main::@1/(byte) cnt2#6 )
(byte) cnt#10 ← phi( main::@1/(byte) cnt#7 )
(byte) inccnt::return#5 ← phi( main::@1/(byte) inccnt::return#1 )
(byte~) main::$1 ← (byte) inccnt::return#5
(byte) cnt#4 ← (byte) cnt#10
(byte) cnt2#3 ← (byte) cnt2#9
*((byte[256]) SCREEN#2 + (byte) 1) ← (byte~) main::$1
to:main::@return
main::@return: from main::@2
(byte) cnt2#10 ← phi( main::@2/(byte) cnt2#3 )
(byte) cnt#11 ← phi( main::@2/(byte) cnt#4 )
(byte) cnt#5 ← (byte) cnt#11
(byte) cnt2#4 ← (byte) cnt2#10
return
to:@RETURN
inccnt: from main main::@1
(byte) cnt2#11 ← phi( main/(byte) cnt2#13 main::@1/(byte) cnt2#2 )
(byte) cnt#12 ← phi( main/(byte) cnt#14 main::@1/(byte) cnt#3 )
(byte) cnt#6 ← ++ (byte) cnt#12
(byte) cnt2#5 ← ++ (byte) cnt2#11
(byte) inccnt::return#2 ← (byte) cnt#6
to:inccnt::@return
inccnt::@return: from inccnt
(byte) cnt2#12 ← phi( inccnt/(byte) cnt2#5 )
(byte) cnt#13 ← phi( inccnt/(byte) cnt#6 )
(byte) inccnt::return#6 ← phi( inccnt/(byte) inccnt::return#2 )
(byte) inccnt::return#3 ← (byte) inccnt::return#6
(byte) cnt#7 ← (byte) cnt#13
(byte) cnt2#6 ← (byte) cnt2#12
return
to:@RETURN
@END: from @3
Constant (byte) cnt#0 (byte) 0
Constant (byte) cnt2#0 (byte) 0
Constant (byte[256]) SCREEN#0 (word) 1024
Succesful SSA optimization Pass2ConstantPropagation
CONTROL FLOW GRAPH
@BEGIN: from
call main param-assignment
to:@3
@3: from @BEGIN
(byte) cnt2#7 ← phi( @BEGIN/(byte) cnt2#4 )
(byte) cnt#8 ← phi( @BEGIN/(byte) cnt#5 )
(byte) cnt#1 ← (byte) cnt#8
(byte) cnt2#1 ← (byte) cnt2#7
to:@END
main: from @BEGIN
(byte[256]) SCREEN#3 ← phi( @BEGIN/(word) 1024 )
(byte) cnt2#13 ← phi( @BEGIN/(byte) 0 )
(byte) cnt#14 ← phi( @BEGIN/(byte) 0 )
call inccnt param-assignment
(byte) inccnt::return#0 ← (byte) inccnt::return#3
to:main::@1
main::@1: from main
(byte[256]) SCREEN#1 ← phi( main/(byte[256]) SCREEN#3 )
(byte) cnt2#8 ← phi( main/(byte) cnt2#6 )
(byte) cnt#9 ← phi( main/(byte) cnt#7 )
(byte) inccnt::return#4 ← phi( main/(byte) inccnt::return#0 )
(byte~) main::$0 ← (byte) inccnt::return#4
(byte) cnt#2 ← (byte) cnt#9
(byte) cnt2#2 ← (byte) cnt2#8
*((byte[256]) SCREEN#1 + (byte) 0) ← (byte~) main::$0
(byte) cnt#3 ← ++ (byte) cnt#2
call inccnt param-assignment
(byte) inccnt::return#1 ← (byte) inccnt::return#3
to:main::@2
main::@2: from main::@1
(byte[256]) SCREEN#2 ← phi( main::@1/(byte[256]) SCREEN#1 )
(byte) cnt2#9 ← phi( main::@1/(byte) cnt2#6 )
(byte) cnt#10 ← phi( main::@1/(byte) cnt#7 )
(byte) inccnt::return#5 ← phi( main::@1/(byte) inccnt::return#1 )
(byte~) main::$1 ← (byte) inccnt::return#5
(byte) cnt#4 ← (byte) cnt#10
(byte) cnt2#3 ← (byte) cnt2#9
*((byte[256]) SCREEN#2 + (byte) 1) ← (byte~) main::$1
to:main::@return
main::@return: from main::@2
(byte) cnt2#10 ← phi( main::@2/(byte) cnt2#3 )
(byte) cnt#11 ← phi( main::@2/(byte) cnt#4 )
(byte) cnt#5 ← (byte) cnt#11
(byte) cnt2#4 ← (byte) cnt2#10
return
to:@RETURN
inccnt: from main main::@1
(byte) cnt2#11 ← phi( main/(byte) cnt2#13 main::@1/(byte) cnt2#2 )
(byte) cnt#12 ← phi( main/(byte) cnt#14 main::@1/(byte) cnt#3 )
(byte) cnt#6 ← ++ (byte) cnt#12
(byte) cnt2#5 ← ++ (byte) cnt2#11
(byte) inccnt::return#2 ← (byte) cnt#6
to:inccnt::@return
inccnt::@return: from inccnt
(byte) cnt2#12 ← phi( inccnt/(byte) cnt2#5 )
(byte) cnt#13 ← phi( inccnt/(byte) cnt#6 )
(byte) inccnt::return#6 ← phi( inccnt/(byte) inccnt::return#2 )
(byte) inccnt::return#3 ← (byte) inccnt::return#6
(byte) cnt#7 ← (byte) cnt#13
(byte) cnt2#6 ← (byte) cnt2#12
return
to:@RETURN
@END: from @3
Not aliassing across scopes: main::$0 inccnt::return#4
Not aliassing across scopes: main::$1 inccnt::return#5
Not aliassing across scopes: inccnt::return#2 cnt#6
Alias (byte) cnt#1 = (byte) cnt#8 (byte) cnt#5 (byte) cnt#9 (byte) cnt#7 (byte) cnt#2 (byte) cnt#10 (byte) cnt#4 (byte) cnt#11 (byte) cnt#13 (byte) cnt#6
Alias (byte) cnt2#1 = (byte) cnt2#7 (byte) cnt2#4 (byte) cnt2#8 (byte) cnt2#6 (byte) cnt2#2 (byte) cnt2#9 (byte) cnt2#3 (byte) cnt2#10 (byte) cnt2#12 (byte) cnt2#5
Alias (byte) inccnt::return#0 = (byte) inccnt::return#3 (byte) inccnt::return#4 (byte) inccnt::return#1 (byte) inccnt::return#5 (byte) inccnt::return#6 (byte) inccnt::return#2
Alias (byte[256]) SCREEN#1 = (byte[256]) SCREEN#3 (byte[256]) SCREEN#2
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@BEGIN: from
call main param-assignment
to:@3
@3: from @BEGIN
to:@END
main: from @BEGIN
(byte[256]) SCREEN#1 ← phi( @BEGIN/(word) 1024 )
(byte) cnt2#13 ← phi( @BEGIN/(byte) 0 )
(byte) cnt#14 ← phi( @BEGIN/(byte) 0 )
call inccnt param-assignment
to:main::@1
main::@1: from main
(byte~) main::$0 ← (byte) inccnt::return#0
*((byte[256]) SCREEN#1 + (byte) 0) ← (byte~) main::$0
(byte) cnt#3 ← ++ (byte) cnt#1
call inccnt param-assignment
to:main::@2
main::@2: from main::@1
(byte~) main::$1 ← (byte) inccnt::return#0
*((byte[256]) SCREEN#1 + (byte) 1) ← (byte~) main::$1
to:main::@return
main::@return: from main::@2
return
to:@RETURN
inccnt: from main main::@1
(byte) cnt2#11 ← phi( main/(byte) cnt2#13 main::@1/(byte) cnt2#1 )
(byte) cnt#12 ← phi( main/(byte) cnt#14 main::@1/(byte) cnt#3 )
(byte) cnt#1 ← ++ (byte) cnt#12
(byte) cnt2#1 ← ++ (byte) cnt2#11
(byte) inccnt::return#0 ← (byte) cnt#1
to:inccnt::@return
inccnt::@return: from inccnt
return
to:@RETURN
@END: from @3
Redundant Phi (byte) cnt#14 (byte) 0
Redundant Phi (byte) cnt2#13 (byte) 0
Redundant Phi (byte[256]) SCREEN#1 (word) 1024
Succesful SSA optimization Pass2RedundantPhiElimination
CONTROL FLOW GRAPH
@BEGIN: from
call main param-assignment
to:@3
@3: from @BEGIN
to:@END
main: from @BEGIN
call inccnt param-assignment
to:main::@1
main::@1: from main
(byte~) main::$0 ← (byte) inccnt::return#0
*((word) 1024 + (byte) 0) ← (byte~) main::$0
(byte) cnt#3 ← ++ (byte) cnt#1
call inccnt param-assignment
to:main::@2
main::@2: from main::@1
(byte~) main::$1 ← (byte) inccnt::return#0
*((word) 1024 + (byte) 1) ← (byte~) main::$1
to:main::@return
main::@return: from main::@2
return
to:@RETURN
inccnt: from main main::@1
(byte) cnt2#11 ← phi( main/(byte) 0 main::@1/(byte) cnt2#1 )
(byte) cnt#12 ← phi( main/(byte) 0 main::@1/(byte) cnt#3 )
(byte) cnt#1 ← ++ (byte) cnt#12
(byte) cnt2#1 ← ++ (byte) cnt2#11
(byte) inccnt::return#0 ← (byte) cnt#1
to:inccnt::@return
inccnt::@return: from inccnt
return
to:@RETURN
@END: from @3
Culled Empty Block (label) @3
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@BEGIN: from
call main param-assignment
to:@END
main: from @BEGIN
call inccnt param-assignment
to:main::@1
main::@1: from main
(byte~) main::$0 ← (byte) inccnt::return#0
*((word) 1024 + (byte) 0) ← (byte~) main::$0
(byte) cnt#3 ← ++ (byte) cnt#1
call inccnt param-assignment
to:main::@2
main::@2: from main::@1
(byte~) main::$1 ← (byte) inccnt::return#0
*((word) 1024 + (byte) 1) ← (byte~) main::$1
to:main::@return
main::@return: from main::@2
return
to:@RETURN
inccnt: from main main::@1
(byte) cnt2#11 ← phi( main/(byte) 0 main::@1/(byte) cnt2#1 )
(byte) cnt#12 ← phi( main/(byte) 0 main::@1/(byte) cnt#3 )
(byte) cnt#1 ← ++ (byte) cnt#12
(byte) cnt2#1 ← ++ (byte) cnt2#11
(byte) inccnt::return#0 ← (byte) cnt#1
to:inccnt::@return
inccnt::@return: from inccnt
return
to:@RETURN
@END: from @BEGIN
Consolidated assigned array index constant in assignment *(1024)
Consolidated assigned array index constant in assignment *(1025)
Succesful SSA optimization Pass2ConstantAdditionElimination
CONTROL FLOW GRAPH
@BEGIN: from
call main param-assignment
to:@END
main: from @BEGIN
call inccnt param-assignment
to:main::@1
main::@1: from main
(byte~) main::$0 ← (byte) inccnt::return#0
*((word) 1024) ← (byte~) main::$0
(byte) cnt#3 ← ++ (byte) cnt#1
call inccnt param-assignment
to:main::@2
main::@2: from main::@1
(byte~) main::$1 ← (byte) inccnt::return#0
*((word) 1025) ← (byte~) main::$1
to:main::@return
main::@return: from main::@2
return
to:@RETURN
inccnt: from main main::@1
(byte) cnt2#11 ← phi( main/(byte) 0 main::@1/(byte) cnt2#1 )
(byte) cnt#12 ← phi( main/(byte) 0 main::@1/(byte) cnt#3 )
(byte) cnt#1 ← ++ (byte) cnt#12
(byte) cnt2#1 ← ++ (byte) cnt2#11
(byte) inccnt::return#0 ← (byte) cnt#1
to:inccnt::@return
inccnt::@return: from inccnt
return
to:@RETURN
@END: from @BEGIN
Not aliassing across scopes: main::$0 inccnt::return#0
Not aliassing across scopes: main::$1 inccnt::return#0
Not aliassing across scopes: inccnt::return#0 cnt#1
Not aliassing across scopes: main::$0 inccnt::return#0
Not aliassing across scopes: main::$1 inccnt::return#0
Not aliassing across scopes: inccnt::return#0 cnt#1
Block Sequence Planned @BEGIN @END main main::@1 main::@2 main::@return inccnt inccnt::@return
Block Sequence Planned @BEGIN @END main main::@1 main::@2 main::@return inccnt inccnt::@return
CONTROL FLOW GRAPH - PHI LIFTED
@BEGIN: from
call main param-assignment
to:@END
@END: from @BEGIN
main: from @BEGIN
call inccnt param-assignment
to:main::@1
main::@1: from main
(byte~) main::$0 ← (byte) inccnt::return#0
*((word) 1024) ← (byte~) main::$0
(byte) cnt#3 ← ++ (byte) cnt#1
(byte~) cnt#15 ← (byte) cnt#3
(byte~) cnt2#14 ← (byte) cnt2#1
call inccnt param-assignment
to:main::@2
main::@2: from main::@1
(byte~) main::$1 ← (byte) inccnt::return#0
*((word) 1025) ← (byte~) main::$1
to:main::@return
main::@return: from main::@2
return
to:@RETURN
inccnt: from main main::@1
(byte) cnt2#11 ← phi( main/(byte) 0 main::@1/(byte~) cnt2#14 )
(byte) cnt#12 ← phi( main/(byte) 0 main::@1/(byte~) cnt#15 )
(byte) cnt#1 ← ++ (byte) cnt#12
(byte) cnt2#1 ← ++ (byte) cnt2#11
(byte) inccnt::return#0 ← (byte) cnt#1
to:inccnt::@return
inccnt::@return: from inccnt
return
to:@RETURN
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
CONTROL FLOW GRAPH - LIVE RANGES
@BEGIN: from
[0] call main param-assignment [ ]
to:@END
@END: from @BEGIN
main: from @BEGIN
[1] call inccnt param-assignment [ inccnt::return#0 cnt#1 cnt2#1 ]
to:main::@1
main::@1: from main
[2] (byte~) main::$0 ← (byte) inccnt::return#0 [ main::$0 cnt#1 cnt2#1 ]
[3] *((word) 1024) ← (byte~) main::$0 [ cnt#1 cnt2#1 ]
[4] (byte) cnt#3 ← ++ (byte) cnt#1 [ cnt#3 cnt2#1 ]
[5] (byte~) cnt#15 ← (byte) cnt#3 [ cnt2#1 cnt#15 ]
[6] (byte~) cnt2#14 ← (byte) cnt2#1 [ cnt#15 cnt2#14 ]
[7] call inccnt param-assignment [ inccnt::return#0 ]
to:main::@2
main::@2: from main::@1
[8] (byte~) main::$1 ← (byte) inccnt::return#0 [ main::$1 ]
[9] *((word) 1025) ← (byte~) main::$1 [ ]
to:main::@return
main::@return: from main::@2
[10] return [ ]
to:@RETURN
inccnt: from main main::@1
[11] (byte) cnt2#11 ← phi( main/(byte) 0 main::@1/(byte~) cnt2#14 ) [ cnt#12 cnt2#11 ]
[11] (byte) cnt#12 ← phi( main/(byte) 0 main::@1/(byte~) cnt#15 ) [ cnt#12 cnt2#11 ]
[12] (byte) cnt#1 ← ++ (byte) cnt#12 [ cnt#1 cnt2#11 ]
[13] (byte) cnt2#1 ← ++ (byte) cnt2#11 [ cnt#1 cnt2#1 ]
[14] (byte) inccnt::return#0 ← (byte) cnt#1 [ inccnt::return#0 cnt#1 cnt2#1 ]
to:inccnt::@return
inccnt::@return: from inccnt
[15] return [ inccnt::return#0 cnt#1 cnt2#1 ]
to:@RETURN
Created 2 initial phi equivalence classes
Coalesced [5] cnt#15 ← cnt#3
Coalesced [6] cnt2#14 ← cnt2#1
Coalesced down to 2 phi equivalence classes
Block Sequence Planned @BEGIN @END main main::@1 main::@2 main::@return inccnt inccnt::@return
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
CONTROL FLOW GRAPH - PHI MEM COALESCED
@BEGIN: from
[0] call main param-assignment [ ]
to:@END
@END: from @BEGIN
main: from @BEGIN
[1] call inccnt param-assignment [ inccnt::return#0 cnt#1 cnt2#1 ]
to:main::@1
main::@1: from main
[2] (byte~) main::$0 ← (byte) inccnt::return#0 [ main::$0 cnt#1 cnt2#1 ]
[3] *((word) 1024) ← (byte~) main::$0 [ cnt#1 cnt2#1 ]
[4] (byte) cnt#3 ← ++ (byte) cnt#1 [ cnt#3 cnt2#1 ]
[5] call inccnt param-assignment [ inccnt::return#0 ]
to:main::@2
main::@2: from main::@1
[6] (byte~) main::$1 ← (byte) inccnt::return#0 [ main::$1 ]
[7] *((word) 1025) ← (byte~) main::$1 [ ]
to:main::@return
main::@return: from main::@2
[8] return [ ]
to:@RETURN
inccnt: from main main::@1
[9] (byte) cnt2#11 ← phi( main/(byte) 0 main::@1/(byte) cnt2#1 ) [ cnt#12 cnt2#11 ]
[9] (byte) cnt#12 ← phi( main/(byte) 0 main::@1/(byte) cnt#3 ) [ cnt#12 cnt2#11 ]
[10] (byte) cnt#1 ← ++ (byte) cnt#12 [ cnt#1 cnt2#11 ]
[11] (byte) cnt2#1 ← ++ (byte) cnt2#11 [ cnt#1 cnt2#1 ]
[12] (byte) inccnt::return#0 ← (byte) cnt#1 [ inccnt::return#0 cnt#1 cnt2#1 ]
to:inccnt::@return
inccnt::@return: from inccnt
[13] return [ inccnt::return#0 cnt#1 cnt2#1 ]
to:@RETURN
CALL GRAPH
Calls in [] to 0:main
Calls in [main] to 1:inccnt 5:inccnt
DOMINATORS
@BEGIN dominated by @BEGIN
@END dominated by @BEGIN @END
main dominated by @BEGIN main
main::@1 dominated by @BEGIN main::@1 main
main::@2 dominated by @BEGIN main::@2 main::@1 main
main::@return dominated by @BEGIN main::@return main::@2 main::@1 main
inccnt dominated by @BEGIN inccnt main
inccnt::@return dominated by inccnt::@return @BEGIN inccnt main
NATURAL LOOPS
Found 0 loops in scope []
Found 0 loops in scope [main]
Found 0 loops in scope [inccnt]
NATURAL LOOPS WITH DEPTH
VARIABLE REGISTER WEIGHTS
(byte[256]) SCREEN
(byte) cnt
(byte) cnt#1 0.8571428571428571
(byte) cnt#12 4.0
(byte) cnt#3 4.0
(byte) cnt2
(byte) cnt2#1 0.5714285714285714
(byte) cnt2#11 2.0
(byte()) inccnt()
(byte) inccnt::return
(byte) inccnt::return#0 1.5
(void()) main()
(byte~) main::$0 4.0
(byte~) main::$1 4.0
Initial phi equivalence classes
[ cnt#12 cnt#3 ]
[ cnt2#11 cnt2#1 ]
Added variable main::$0 to zero page equivalence class [ main::$0 ]
Added variable main::$1 to zero page equivalence class [ main::$1 ]
Added variable cnt#1 to zero page equivalence class [ cnt#1 ]
Added variable inccnt::return#0 to zero page equivalence class [ inccnt::return#0 ]
Complete equivalence classes
[ cnt#12 cnt#3 ]
[ cnt2#11 cnt2#1 ]
[ main::$0 ]
[ main::$1 ]
[ cnt#1 ]
[ inccnt::return#0 ]
Allocated zp byte:2 to zp byte:2 [ cnt#12 cnt#3 ]
Allocated zp byte:3 to zp byte:3 [ cnt2#11 cnt2#1 ]
Allocated zp byte:4 to zp byte:4 [ main::$0 ]
Allocated zp byte:5 to zp byte:5 [ main::$1 ]
Allocated zp byte:6 to zp byte:6 [ cnt#1 ]
Allocated zp byte:7 to zp byte:7 [ inccnt::return#0 ]
INITIAL ASM
//SEG0 @BEGIN
BBEGIN:
//SEG1 [0] call main param-assignment [ ]
jsr main
jmp BEND
//SEG2 @END
BEND:
//SEG3 main
main:
//SEG4 [1] call inccnt param-assignment [ inccnt::return#0 cnt#1 cnt2#1 ]
//SEG5 [9] phi from main to inccnt
inccnt_from_main:
//SEG6 [9] phi (byte) cnt2#11 = (byte) 0 -- zpby1=coby1
lda #0
sta 3
//SEG7 [9] phi (byte) cnt#12 = (byte) 0 -- zpby1=coby1
lda #0
sta 2
jsr inccnt
jmp main__B1
//SEG8 main::@1
main__B1:
//SEG9 [2] (byte~) main::$0 ← (byte) inccnt::return#0 [ main::$0 cnt#1 cnt2#1 ] -- zpby1=zpby2
lda 7
sta 4
//SEG10 [3] *((word) 1024) ← (byte~) main::$0 [ cnt#1 cnt2#1 ] -- _star_cowo1=zpby1
lda 4
sta 1024
//SEG11 [4] (byte) cnt#3 ← ++ (byte) cnt#1 [ cnt#3 cnt2#1 ] -- zpby1=_inc_zpby2
lda 6
sta 2
inc 2
//SEG12 [5] call inccnt param-assignment [ inccnt::return#0 ]
//SEG13 [9] phi from main::@1 to inccnt
inccnt_from_B1:
//SEG14 [9] phi (byte) cnt2#11 = (byte) cnt2#1 -- register_copy
//SEG15 [9] phi (byte) cnt#12 = (byte) cnt#3 -- register_copy
jsr inccnt
jmp main__B2
//SEG16 main::@2
main__B2:
//SEG17 [6] (byte~) main::$1 ← (byte) inccnt::return#0 [ main::$1 ] -- zpby1=zpby2
lda 7
sta 5
//SEG18 [7] *((word) 1025) ← (byte~) main::$1 [ ] -- _star_cowo1=zpby1
lda 5
sta 1025
jmp main__Breturn
//SEG19 main::@return
main__Breturn:
//SEG20 [8] return [ ]
rts
//SEG21 inccnt
inccnt:
//SEG22 [10] (byte) cnt#1 ← ++ (byte) cnt#12 [ cnt#1 cnt2#11 ] -- zpby1=_inc_zpby2
lda 2
sta 6
inc 6
//SEG23 [11] (byte) cnt2#1 ← ++ (byte) cnt2#11 [ cnt#1 cnt2#1 ] -- zpby1=_inc_zpby1
inc 3
//SEG24 [12] (byte) inccnt::return#0 ← (byte) cnt#1 [ inccnt::return#0 cnt#1 cnt2#1 ] -- zpby1=zpby2
lda 6
sta 7
jmp inccnt__Breturn
//SEG25 inccnt::@return
inccnt__Breturn:
//SEG26 [13] return [ inccnt::return#0 cnt#1 cnt2#1 ]
rts
REGISTER UPLIFT POTENTIAL REGISTERS
Potential registers zp byte:2 [ cnt#12 cnt#3 ] : zp byte:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:3 [ cnt2#11 cnt2#1 ] : zp byte:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:4 [ main::$0 ] : zp byte:4 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:5 [ main::$1 ] : zp byte:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:6 [ cnt#1 ] : zp byte:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp byte:7 [ inccnt::return#0 ] : zp byte:7 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [] 8: zp byte:2 [ cnt#12 cnt#3 ] 2.57: zp byte:3 [ cnt2#11 cnt2#1 ] 0.86: zp byte:6 [ cnt#1 ]
Uplift Scope [main] 4: zp byte:4 [ main::$0 ] 4: zp byte:5 [ main::$1 ]
Uplift Scope [inccnt] 1.5: zp byte:7 [ inccnt::return#0 ]
Uplifting [] best 84 combination reg byte x [ cnt#12 cnt#3 ] reg byte y [ cnt2#11 cnt2#1 ] reg byte x [ cnt#1 ]
Uplifting [main] best 72 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [inccnt] best 65 combination reg byte a [ inccnt::return#0 ]
MISSING FRAGMENTS
zpby1=_inc_xby
zpby1=_inc_yby
aby=_inc_xby
aby=_inc_yby
yby=_inc_xby
xby=_inc_yby
Removing instruction jmp BEND
Removing instruction jmp main__B1
Removing instruction jmp main__B2
Removing instruction jmp main__Breturn
Removing instruction jmp inccnt__Breturn
Succesful ASM optimization Pass5NextJumpElimination
ASSEMBLER
//SEG0 @BEGIN
BBEGIN:
//SEG1 [0] call main param-assignment [ ]
jsr main
//SEG2 @END
BEND:
//SEG3 main
main:
//SEG4 [1] call inccnt param-assignment [ inccnt::return#0 cnt#1 cnt2#1 ]
//SEG5 [9] phi from main to inccnt
inccnt_from_main:
//SEG6 [9] phi (byte) cnt2#11 = (byte) 0 -- yby=coby1
ldy #0
//SEG7 [9] phi (byte) cnt#12 = (byte) 0 -- xby=coby1
ldx #0
jsr inccnt
//SEG8 main::@1
main__B1:
//SEG9 [2] (byte~) main::$0 ← (byte) inccnt::return#0 [ main::$0 cnt#1 cnt2#1 ]
// (byte~) main::$0 = (byte) inccnt::return#0 // register copy reg byte a
//SEG10 [3] *((word) 1024) ← (byte~) main::$0 [ cnt#1 cnt2#1 ] -- _star_cowo1=aby
sta 1024
//SEG11 [4] (byte) cnt#3 ← ++ (byte) cnt#1 [ cnt#3 cnt2#1 ] -- xby=_inc_xby
inx
//SEG12 [5] call inccnt param-assignment [ inccnt::return#0 ]
//SEG13 [9] phi from main::@1 to inccnt
inccnt_from_B1:
//SEG14 [9] phi (byte) cnt2#11 = (byte) cnt2#1 -- register_copy
//SEG15 [9] phi (byte) cnt#12 = (byte) cnt#3 -- register_copy
jsr inccnt
//SEG16 main::@2
main__B2:
//SEG17 [6] (byte~) main::$1 ← (byte) inccnt::return#0 [ main::$1 ]
// (byte~) main::$1 = (byte) inccnt::return#0 // register copy reg byte a
//SEG18 [7] *((word) 1025) ← (byte~) main::$1 [ ] -- _star_cowo1=aby
sta 1025
//SEG19 main::@return
main__Breturn:
//SEG20 [8] return [ ]
rts
//SEG21 inccnt
inccnt:
//SEG22 [10] (byte) cnt#1 ← ++ (byte) cnt#12 [ cnt#1 cnt2#11 ] -- xby=_inc_xby
inx
//SEG23 [11] (byte) cnt2#1 ← ++ (byte) cnt2#11 [ cnt#1 cnt2#1 ] -- yby=_inc_yby
iny
//SEG24 [12] (byte) inccnt::return#0 ← (byte) cnt#1 [ inccnt::return#0 cnt#1 cnt2#1 ] -- aby=xby
txa
//SEG25 inccnt::@return
inccnt__Breturn:
//SEG26 [13] return [ inccnt::return#0 cnt#1 cnt2#1 ]
rts
FINAL SYMBOL TABLE
(label) @BEGIN
(label) @END
(byte[256]) SCREEN
(byte) cnt
(byte) cnt#1 reg byte x 0.8571428571428571
(byte) cnt#12 reg byte x 4.0
(byte) cnt#3 reg byte x 4.0
(byte) cnt2
(byte) cnt2#1 reg byte y 0.5714285714285714
(byte) cnt2#11 reg byte y 2.0
(byte()) inccnt()
(label) inccnt::@return
(byte) inccnt::return
(byte) inccnt::return#0 reg byte a 1.5
(void()) main()
(byte~) main::$0 reg byte a 4.0
(byte~) main::$1 reg byte a 4.0
(label) main::@1
(label) main::@2
(label) main::@return
reg byte x [ cnt#12 cnt#3 ]
reg byte y [ cnt2#11 cnt2#1 ]
reg byte a [ main::$0 ]
reg byte a [ main::$1 ]
reg byte x [ cnt#1 ]
reg byte a [ inccnt::return#0 ]
FINAL CODE
//SEG0 @BEGIN
BBEGIN:
//SEG1 [0] call main param-assignment [ ]
jsr main
//SEG2 @END
BEND:
//SEG3 main
main:
//SEG4 [1] call inccnt param-assignment [ inccnt::return#0 cnt#1 cnt2#1 ]
//SEG5 [9] phi from main to inccnt
inccnt_from_main:
//SEG6 [9] phi (byte) cnt2#11 = (byte) 0 -- yby=coby1
ldy #0
//SEG7 [9] phi (byte) cnt#12 = (byte) 0 -- xby=coby1
ldx #0
jsr inccnt
//SEG8 main::@1
main__B1:
//SEG9 [2] (byte~) main::$0 ← (byte) inccnt::return#0 [ main::$0 cnt#1 cnt2#1 ]
// (byte~) main::$0 = (byte) inccnt::return#0 // register copy reg byte a
//SEG10 [3] *((word) 1024) ← (byte~) main::$0 [ cnt#1 cnt2#1 ] -- _star_cowo1=aby
sta 1024
//SEG11 [4] (byte) cnt#3 ← ++ (byte) cnt#1 [ cnt#3 cnt2#1 ] -- xby=_inc_xby
inx
//SEG12 [5] call inccnt param-assignment [ inccnt::return#0 ]
//SEG13 [9] phi from main::@1 to inccnt
inccnt_from_B1:
//SEG14 [9] phi (byte) cnt2#11 = (byte) cnt2#1 -- register_copy
//SEG15 [9] phi (byte) cnt#12 = (byte) cnt#3 -- register_copy
jsr inccnt
//SEG16 main::@2
main__B2:
//SEG17 [6] (byte~) main::$1 ← (byte) inccnt::return#0 [ main::$1 ]
// (byte~) main::$1 = (byte) inccnt::return#0 // register copy reg byte a
//SEG18 [7] *((word) 1025) ← (byte~) main::$1 [ ] -- _star_cowo1=aby
sta 1025
//SEG19 main::@return
main__Breturn:
//SEG20 [8] return [ ]
rts
//SEG21 inccnt
inccnt:
//SEG22 [10] (byte) cnt#1 ← ++ (byte) cnt#12 [ cnt#1 cnt2#11 ] -- xby=_inc_xby
inx
//SEG23 [11] (byte) cnt2#1 ← ++ (byte) cnt2#11 [ cnt#1 cnt2#1 ] -- yby=_inc_yby
iny
//SEG24 [12] (byte) inccnt::return#0 ← (byte) cnt#1 [ inccnt::return#0 cnt#1 cnt2#1 ] -- aby=xby
txa
//SEG25 inccnt::@return
inccnt__Breturn:
//SEG26 [13] return [ inccnt::return#0 cnt#1 cnt2#1 ]
rts

View File

@ -0,0 +1,27 @@
(label) @BEGIN
(label) @END
(byte[256]) SCREEN
(byte) cnt
(byte) cnt#1 reg byte x 0.8571428571428571
(byte) cnt#12 reg byte x 4.0
(byte) cnt#3 reg byte x 4.0
(byte) cnt2
(byte) cnt2#1 reg byte y 0.5714285714285714
(byte) cnt2#11 reg byte y 2.0
(byte()) inccnt()
(label) inccnt::@return
(byte) inccnt::return
(byte) inccnt::return#0 reg byte a 1.5
(void()) main()
(byte~) main::$0 reg byte a 4.0
(byte~) main::$1 reg byte a 4.0
(label) main::@1
(label) main::@2
(label) main::@return
reg byte x [ cnt#12 cnt#3 ]
reg byte y [ cnt2#11 cnt2#1 ]
reg byte a [ main::$0 ]
reg byte a [ main::$1 ]
reg byte x [ cnt#1 ]
reg byte a [ inccnt::return#0 ]

View File

@ -445,6 +445,8 @@ rvaluevar::@return: from rvaluevar::@1
to:@RETURN
@END: from @BEGIN
PROCEDURE MODIFY VARIABLE ANALYSIS
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
call main param-assignment

View File

@ -109,6 +109,8 @@ main::@return: from main::@1
to:@RETURN
@END: from @BEGIN
PROCEDURE MODIFY VARIABLE ANALYSIS
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
call main param-assignment

View File

@ -1,8 +1,8 @@
@BEGIN: from
[0] call sum param-assignment [ sum::return#0 s1#0 ]
[0] call sum param-assignment [ sum::return#0 ]
to:@2
@2: from @BEGIN
[1] (byte) s1#0 ← (byte) sum::return#0 [ sum::return#0 s1#0 ]
[1] (byte) s1#0 ← (byte) sum::return#0 [ s1#0 ]
[2] call sum param-assignment [ sum::return#0 s1#0 ]
to:@3
@3: from @2

View File

@ -79,6 +79,8 @@ sum::@return: from sum
to:@RETURN
@END: from @BEGIN
PROCEDURE MODIFY VARIABLE ANALYSIS
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte) sum::a ← (byte) 1
@ -282,10 +284,10 @@ Propagating live ranges...
Propagating live ranges...
CONTROL FLOW GRAPH - LIVE RANGES
@BEGIN: from
[0] call sum param-assignment [ sum::return#0 s1#0 ]
[0] call sum param-assignment [ sum::return#0 ]
to:@2
@2: from @BEGIN
[1] (byte) s1#0 ← (byte) sum::return#0 [ sum::return#0 s1#0 ]
[1] (byte) s1#0 ← (byte) sum::return#0 [ s1#0 ]
[2] call sum param-assignment [ sum::return#0 s1#0 ]
to:@3
@3: from @2
@ -313,10 +315,10 @@ Propagating live ranges...
Propagating live ranges...
CONTROL FLOW GRAPH - PHI MEM COALESCED
@BEGIN: from
[0] call sum param-assignment [ sum::return#0 s1#0 ]
[0] call sum param-assignment [ sum::return#0 ]
to:@2
@2: from @BEGIN
[1] (byte) s1#0 ← (byte) sum::return#0 [ sum::return#0 s1#0 ]
[1] (byte) s1#0 ← (byte) sum::return#0 [ s1#0 ]
[2] call sum param-assignment [ sum::return#0 s1#0 ]
to:@3
@3: from @2
@ -353,7 +355,7 @@ NATURAL LOOPS WITH DEPTH
VARIABLE REGISTER WEIGHTS
(byte) s1
(byte) s1#0 0.5714285714285714
(byte) s1#0 0.6666666666666666
(byte) s2
(byte) s2#0 4.0
(byte) s3
@ -364,7 +366,7 @@ VARIABLE REGISTER WEIGHTS
(byte) sum::b
(byte) sum::b#2 2.0
(byte) sum::return
(byte) sum::return#0 1.2000000000000002
(byte) sum::return#0 1.5
Initial phi equivalence classes
[ sum::a#2 ]
@ -389,7 +391,7 @@ Allocated zp byte:7 to zp byte:7 [ sum::return#0 ]
INITIAL ASM
//SEG0 @BEGIN
BBEGIN:
//SEG1 [0] call sum param-assignment [ sum::return#0 s1#0 ]
//SEG1 [0] call sum param-assignment [ sum::return#0 ]
//SEG2 [5] phi from @BEGIN to sum
sum_from_BBEGIN:
//SEG3 [5] phi (byte) sum::b#2 = (byte) 2 -- zpby1=coby1
@ -402,7 +404,7 @@ sum_from_BBEGIN:
jmp B2
//SEG5 @2
B2:
//SEG6 [1] (byte) s1#0 ← (byte) sum::return#0 [ sum::return#0 s1#0 ] -- zpby1=zpby2
//SEG6 [1] (byte) s1#0 ← (byte) sum::return#0 [ s1#0 ] -- zpby1=zpby2
lda 7
sta 4
//SEG7 [2] call sum param-assignment [ sum::return#0 s1#0 ]
@ -451,8 +453,8 @@ Potential registers zp byte:6 [ s3#0 ] : zp byte:6 , reg byte a , reg byte x , r
Potential registers zp byte:7 [ sum::return#0 ] : zp byte:7 , 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.57: zp byte:4 [ s1#0 ]
Uplift Scope [sum] 2: zp byte:2 [ sum::a#2 ] 2: zp byte:3 [ sum::b#2 ] 1.2: zp byte:7 [ sum::return#0 ]
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 ]
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 ]
@ -465,7 +467,7 @@ Succesful ASM optimization Pass5NextJumpElimination
ASSEMBLER
//SEG0 @BEGIN
BBEGIN:
//SEG1 [0] call sum param-assignment [ sum::return#0 s1#0 ]
//SEG1 [0] call sum param-assignment [ sum::return#0 ]
//SEG2 [5] phi from @BEGIN to sum
sum_from_BBEGIN:
//SEG3 [5] phi (byte) sum::b#2 = (byte) 2 -- aby=coby1
@ -475,7 +477,7 @@ sum_from_BBEGIN:
jsr sum
//SEG5 @2
B2:
//SEG6 [1] (byte) s1#0 ← (byte) sum::return#0 [ sum::return#0 s1#0 ] -- zpby1=aby
//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
@ -511,7 +513,7 @@ FINAL SYMBOL TABLE
(label) @BEGIN
(label) @END
(byte) s1
(byte) s1#0 zp byte:2 0.5714285714285714
(byte) s1#0 zp byte:2 0.6666666666666666
(byte) s2
(byte) s2#0 reg byte a 4.0
(byte) s3
@ -523,7 +525,7 @@ FINAL SYMBOL TABLE
(byte) sum::b
(byte) sum::b#2 reg byte a 2.0
(byte) sum::return
(byte) sum::return#0 reg byte a 1.2000000000000002
(byte) sum::return#0 reg byte a 1.5
reg byte x [ sum::a#2 ]
reg byte a [ sum::b#2 ]
@ -535,7 +537,7 @@ reg byte a [ sum::return#0 ]
FINAL CODE
//SEG0 @BEGIN
BBEGIN:
//SEG1 [0] call sum param-assignment [ sum::return#0 s1#0 ]
//SEG1 [0] call sum param-assignment [ sum::return#0 ]
//SEG2 [5] phi from @BEGIN to sum
sum_from_BBEGIN:
//SEG3 [5] phi (byte) sum::b#2 = (byte) 2 -- aby=coby1
@ -545,7 +547,7 @@ sum_from_BBEGIN:
jsr sum
//SEG5 @2
B2:
//SEG6 [1] (byte) s1#0 ← (byte) sum::return#0 [ sum::return#0 s1#0 ] -- zpby1=aby
//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

View File

@ -3,7 +3,7 @@
(label) @BEGIN
(label) @END
(byte) s1
(byte) s1#0 zp byte:2 0.5714285714285714
(byte) s1#0 zp byte:2 0.6666666666666666
(byte) s2
(byte) s2#0 reg byte a 4.0
(byte) s3
@ -15,7 +15,7 @@
(byte) sum::b
(byte) sum::b#2 reg byte a 2.0
(byte) sum::return
(byte) sum::return#0 reg byte a 1.2000000000000002
(byte) sum::return#0 reg byte a 1.5
reg byte x [ sum::a#2 ]
reg byte a [ sum::b#2 ]

View File

@ -48,6 +48,8 @@ main::@return: from main
to:@RETURN
@END: from @BEGIN
PROCEDURE MODIFY VARIABLE ANALYSIS
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte*) SCREEN ← (word) 1024

View File

@ -148,12 +148,12 @@ render__B2_from_B1:
render__B2_from_B5:
render__B2:
lda 5
sta 9
sta 8
lda 2
sta 10
sta 9
jsr findcol
render__B5:
lda 8
tya
ldy 5
sta (3),y
inc 5
@ -176,80 +176,77 @@ render__Breturn:
rts
findcol:
findcol__B1_from_findcol:
lda #0
sta 8
ldy #0
lda #255
sta 6
ldy #0
ldx #0
findcol__B1_from_B13:
findcol__B1:
ldx 4096,y
lda 4352,y
sta 11
cpx 9
lda 4096,x
sta 7
lda 4352,x
sta 10
lda 8
cmp 7
beq findcol__B2
findcol__B3:
cpx 9
bcs findcol__B6
lda 8
cmp 7
bcc findcol__B6
findcol__B7:
stx 255
lda 9
lda 8
sec
sbc 255
sbc 7
sta 7
findcol__B8_from_B7:
findcol__B8:
lda 10
cmp 11
lda 9
cmp 10
bcc findcol__B9
findcol__B10:
lda 10
sec
sbc 11
clc
adc 7
tax
findcol__B11_from_B10:
findcol__B11:
cpx 6
bcc findcol__B12
findcol__B13_from_B11:
findcol__B13:
iny
cpy #6
bcc findcol__B1_from_B13
findcol__Breturn_from_B13:
jmp findcol__Breturn
findcol__Breturn_from_B2:
lda #0
sta 8
findcol__Breturn:
rts
findcol__B12:
lda 4608,y
sta 8
stx 6
findcol__B13_from_B12:
jmp findcol__B13
findcol__B9:
lda 11
lda 9
sec
sbc 10
clc
adc 7
tax
findcol__B11_from_B10:
findcol__B11:
cmp 6
bcc findcol__B12
findcol__B13_from_B11:
findcol__B13:
inx
cpx #6
bcc findcol__B1_from_B13
findcol__Breturn_from_B13:
jmp findcol__Breturn
findcol__Breturn_from_B2:
ldy #0
findcol__Breturn:
rts
findcol__B12:
ldy 4608,x
sta 6
findcol__B13_from_B12:
jmp findcol__B13
findcol__B9:
lda 10
sec
sbc 9
clc
adc 7
findcol__B11_from_B9:
jmp findcol__B11
findcol__B6:
txa
lda 7
sec
sbc 9
sbc 8
sta 7
findcol__B8_from_B6:
jmp findcol__B8
findcol__B2:
lda 10
cmp 11
lda 9
cmp 10
beq findcol__Breturn_from_B2
jmp findcol__B3
initscreen:

View File

@ -1,128 +1,128 @@
@BEGIN: from
[0] call main param-assignment [ findcol::return#0 ]
[0] call main param-assignment [ ]
to:@END
@END: from @BEGIN
main: from @BEGIN
[1] call addpoint param-assignment [ findcol::return#0 ]
[1] call addpoint param-assignment [ ]
to:main::@3
main::@3: from main
[2] call addpoint param-assignment [ findcol::return#0 ]
[2] call addpoint param-assignment [ ]
to:main::@4
main::@4: from main::@3
[3] call addpoint param-assignment [ findcol::return#0 ]
[3] call addpoint param-assignment [ ]
to:main::@5
main::@5: from main::@4
[4] call addpoint param-assignment [ findcol::return#0 ]
[4] call addpoint param-assignment [ ]
to:main::@6
main::@6: from main::@5
[5] call addpoint param-assignment [ findcol::return#0 ]
[5] call addpoint param-assignment [ ]
to:main::@7
main::@7: from main::@6
[6] call addpoint param-assignment [ findcol::return#0 ]
[6] call addpoint param-assignment [ ]
to:main::@8
main::@8: from main::@7
[7] call initscreen param-assignment [ findcol::return#0 ]
[7] call initscreen param-assignment [ ]
to:main::@1
main::@1: from main::@11 main::@8
[8] call render param-assignment [ findcol::return#0 ]
[8] call render param-assignment [ ]
to:main::@10
main::@10: from main::@1
[9] call animate param-assignment [ findcol::return#0 ]
[9] call animate param-assignment [ ]
to:main::@11
main::@11: from main::@10
[10] if(true) goto main::@1 [ findcol::return#0 ]
[10] if(true) goto main::@1 [ ]
to:main::@return
main::@return: from main::@11
[11] return [ findcol::return#0 ]
[11] return [ ]
to:@RETURN
animate: from main::@10
[12] (byte~) animate::$0 ← * (word) 4096 [ animate::$0 findcol::return#0 ]
[13] (byte~) animate::$1 ← (byte~) animate::$0 + (byte) 1 [ animate::$1 findcol::return#0 ]
[14] *((word) 4096) ← (byte~) animate::$1 [ findcol::return#0 ]
[15] (byte~) animate::$2 ← * (word) 4096 [ animate::$2 findcol::return#0 ]
[16] if((byte~) animate::$2==(byte) 40) goto animate::@1 [ findcol::return#0 ]
[12] (byte~) animate::$0 ← * (word) 4096 [ animate::$0 ]
[13] (byte~) animate::$1 ← (byte~) animate::$0 + (byte) 1 [ animate::$1 ]
[14] *((word) 4096) ← (byte~) animate::$1 [ ]
[15] (byte~) animate::$2 ← * (word) 4096 [ animate::$2 ]
[16] if((byte~) animate::$2==(byte) 40) goto animate::@1 [ ]
to:animate::@2
animate::@2: from animate animate::@1
[17] (byte~) animate::$4 ← * (word) 4352 [ animate::$4 findcol::return#0 ]
[18] (byte~) animate::$5 ← (byte~) animate::$4 + (byte) 1 [ animate::$5 findcol::return#0 ]
[19] *((word) 4352) ← (byte~) animate::$5 [ findcol::return#0 ]
[20] (byte~) animate::$6 ← * (word) 4352 [ animate::$6 findcol::return#0 ]
[21] if((byte~) animate::$6==(byte) 25) goto animate::@3 [ findcol::return#0 ]
[17] (byte~) animate::$4 ← * (word) 4352 [ animate::$4 ]
[18] (byte~) animate::$5 ← (byte~) animate::$4 + (byte) 1 [ animate::$5 ]
[19] *((word) 4352) ← (byte~) animate::$5 [ ]
[20] (byte~) animate::$6 ← * (word) 4352 [ animate::$6 ]
[21] if((byte~) animate::$6==(byte) 25) goto animate::@3 [ ]
to:animate::@4
animate::@4: from animate::@2 animate::@3
[22] (byte~) animate::$8 ← * (word) 4097 [ animate::$8 findcol::return#0 ]
[23] (byte~) animate::$9 ← (byte~) animate::$8 - (byte) 1 [ animate::$9 findcol::return#0 ]
[24] *((word) 4097) ← (byte~) animate::$9 [ findcol::return#0 ]
[25] (byte~) animate::$10 ← * (word) 4097 [ animate::$10 findcol::return#0 ]
[26] if((byte~) animate::$10==(byte) 255) goto animate::@5 [ findcol::return#0 ]
[22] (byte~) animate::$8 ← * (word) 4097 [ animate::$8 ]
[23] (byte~) animate::$9 ← (byte~) animate::$8 - (byte) 1 [ animate::$9 ]
[24] *((word) 4097) ← (byte~) animate::$9 [ ]
[25] (byte~) animate::$10 ← * (word) 4097 [ animate::$10 ]
[26] if((byte~) animate::$10==(byte) 255) goto animate::@5 [ ]
to:animate::@6
animate::@6: from animate::@4 animate::@5
[27] (byte~) animate::$12 ← * (word) 4354 [ animate::$12 findcol::return#0 ]
[28] (byte~) animate::$13 ← (byte~) animate::$12 + (byte) 1 [ animate::$13 findcol::return#0 ]
[29] *((word) 4354) ← (byte~) animate::$13 [ findcol::return#0 ]
[30] (byte~) animate::$14 ← * (word) 4354 [ animate::$14 findcol::return#0 ]
[31] if((byte~) animate::$14==(byte) 25) goto animate::@7 [ findcol::return#0 ]
[27] (byte~) animate::$12 ← * (word) 4354 [ animate::$12 ]
[28] (byte~) animate::$13 ← (byte~) animate::$12 + (byte) 1 [ animate::$13 ]
[29] *((word) 4354) ← (byte~) animate::$13 [ ]
[30] (byte~) animate::$14 ← * (word) 4354 [ animate::$14 ]
[31] if((byte~) animate::$14==(byte) 25) goto animate::@7 [ ]
to:animate::@8
animate::@8: from animate::@6 animate::@7
[32] (byte~) animate::$16 ← * (word) 4355 [ animate::$16 findcol::return#0 ]
[33] (byte~) animate::$17 ← (byte~) animate::$16 - (byte) 1 [ animate::$17 findcol::return#0 ]
[34] *((word) 4355) ← (byte~) animate::$17 [ findcol::return#0 ]
[35] (byte~) animate::$18 ← * (word) 4355 [ animate::$18 findcol::return#0 ]
[36] if((byte~) animate::$18==(byte) 255) goto animate::@9 [ findcol::return#0 ]
[32] (byte~) animate::$16 ← * (word) 4355 [ animate::$16 ]
[33] (byte~) animate::$17 ← (byte~) animate::$16 - (byte) 1 [ animate::$17 ]
[34] *((word) 4355) ← (byte~) animate::$17 [ ]
[35] (byte~) animate::$18 ← * (word) 4355 [ animate::$18 ]
[36] if((byte~) animate::$18==(byte) 255) goto animate::@9 [ ]
to:animate::@return
animate::@return: from animate::@11 animate::@8 animate::@9
[37] return [ findcol::return#0 ]
[37] return [ ]
to:@RETURN
animate::@9: from animate::@8
[38] *((word) 4355) ← (byte) 25 [ findcol::return#0 ]
[39] (byte~) animate::$20 ← * (word) 4099 [ animate::$20 findcol::return#0 ]
[40] (byte~) animate::$21 ← (byte~) animate::$20 + (byte) 7 [ animate::$21 findcol::return#0 ]
[41] *((word) 4099) ← (byte~) animate::$21 [ findcol::return#0 ]
[42] (byte~) animate::$22 ← * (word) 4099 [ animate::$22 findcol::return#0 ]
[43] if((byte~) animate::$22>=(byte) 40) goto animate::@11 [ findcol::return#0 ]
[38] *((word) 4355) ← (byte) 25 [ ]
[39] (byte~) animate::$20 ← * (word) 4099 [ animate::$20 ]
[40] (byte~) animate::$21 ← (byte~) animate::$20 + (byte) 7 [ animate::$21 ]
[41] *((word) 4099) ← (byte~) animate::$21 [ ]
[42] (byte~) animate::$22 ← * (word) 4099 [ animate::$22 ]
[43] if((byte~) animate::$22>=(byte) 40) goto animate::@11 [ ]
to:animate::@return
animate::@11: from animate::@9
[44] (byte~) animate::$24 ← * (word) 4099 [ animate::$24 findcol::return#0 ]
[45] (byte~) animate::$25 ← (byte~) animate::$24 - (byte) 40 [ animate::$25 findcol::return#0 ]
[46] *((word) 4099) ← (byte~) animate::$25 [ findcol::return#0 ]
[44] (byte~) animate::$24 ← * (word) 4099 [ animate::$24 ]
[45] (byte~) animate::$25 ← (byte~) animate::$24 - (byte) 40 [ animate::$25 ]
[46] *((word) 4099) ← (byte~) animate::$25 [ ]
to:animate::@return
animate::@7: from animate::@6
[47] *((word) 4354) ← (byte) 0 [ findcol::return#0 ]
[47] *((word) 4354) ← (byte) 0 [ ]
to:animate::@8
animate::@5: from animate::@4
[48] *((word) 4097) ← (byte) 40 [ findcol::return#0 ]
[48] *((word) 4097) ← (byte) 40 [ ]
to:animate::@6
animate::@3: from animate::@2
[49] *((word) 4352) ← (byte) 0 [ findcol::return#0 ]
[49] *((word) 4352) ← (byte) 0 [ ]
to:animate::@4
animate::@1: from animate
[50] *((word) 4096) ← (byte) 0 [ findcol::return#0 ]
[50] *((word) 4096) ← (byte) 0 [ ]
to:animate::@2
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 findcol::return#0 render::colline#2 ]
[51] (byte) render::y#2 ← phi( render/(byte) 0 render::@3/(byte) render::y#1 ) [ render::y#2 findcol::return#0 render::colline#2 ]
[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 findcol::return#0 render::colline#2 ]
[53] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 findcol::return#0 render::colline#2 findcol::x#0 ]
[54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 findcol::return#0 render::colline#2 findcol::x#0 findcol::y#0 ]
[55] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 findcol::x#0 findcol::y#0 ]
[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 findcol::x#0 ]
[54] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 render::colline#2 findcol::x#0 findcol::y#0 ]
[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 findcol::return#0 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 findcol::return#0 render::colline#2 ]
[58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 findcol::return#0 render::colline#2 ]
[59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 findcol::return#0 render::colline#2 ]
[56] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 render::colline#2 render::col#0 ]
[57] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 render::colline#2 ]
[58] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 render::colline#2 ]
[59] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 render::colline#2 ]
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 findcol::return#0 ]
[61] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 findcol::return#0 ]
[62] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 findcol::return#0 ]
[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 [ findcol::return#0 ]
[63] return [ ]
to:@RETURN
findcol: from render::@2
to:findcol::@1
@ -159,8 +159,8 @@ findcol::@13: from findcol::@11 findcol::@12
[78] if((byte) findcol::i#1<(byte) 6) 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 ]
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 findcol::x#0 findcol::y#0 ]
[80] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 findcol::x#0 findcol::y#0 ]
[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 ]
@ -179,23 +179,23 @@ findcol::@2: from findcol::@1
initscreen: from main::@8
to:initscreen::@1
initscreen::@1: from initscreen initscreen::@1
[87] (byte*) initscreen::screen#2 ← phi( initscreen/(word) 1024 initscreen::@1/(byte*) initscreen::screen#1 ) [ findcol::return#0 initscreen::screen#2 ]
[88] *((byte*) initscreen::screen#2) ← (byte) 230 [ findcol::return#0 initscreen::screen#2 ]
[89] (byte*) initscreen::screen#1 ← ++ (byte*) initscreen::screen#2 [ findcol::return#0 initscreen::screen#1 ]
[90] if((byte*) initscreen::screen#1<(word) 2048) goto initscreen::@1 [ findcol::return#0 initscreen::screen#1 ]
[87] (byte*) initscreen::screen#2 ← phi( initscreen/(word) 1024 initscreen::@1/(byte*) initscreen::screen#1 ) [ initscreen::screen#2 ]
[88] *((byte*) initscreen::screen#2) ← (byte) 230 [ initscreen::screen#2 ]
[89] (byte*) initscreen::screen#1 ← ++ (byte*) initscreen::screen#2 [ initscreen::screen#1 ]
[90] if((byte*) initscreen::screen#1<(word) 2048) goto initscreen::@1 [ initscreen::screen#1 ]
to:initscreen::@return
initscreen::@return: from initscreen::@1
[91] return [ findcol::return#0 ]
[91] return [ ]
to:@RETURN
addpoint: from main main::@3 main::@4 main::@5 main::@6 main::@7
[92] (byte) addpoint::c#6 ← phi( main/(byte) 1 main::@3/(byte) 2 main::@4/(byte) 3 main::@5/(byte) 4 main::@6/(byte) 5 main::@7/(byte) 7 ) [ findcol::return#0 addpoint::idx#6 addpoint::x#6 addpoint::y#6 addpoint::c#6 ]
[92] (byte) addpoint::y#6 ← phi( main/(byte) 5 main::@3/(byte) 8 main::@4/(byte) 14 main::@5/(byte) 2 main::@6/(byte) 17 main::@7/(byte) 22 ) [ findcol::return#0 addpoint::idx#6 addpoint::x#6 addpoint::y#6 addpoint::c#6 ]
[92] (byte) addpoint::idx#6 ← phi( main/(byte) 0 main::@3/(byte) 1 main::@4/(byte) 2 main::@5/(byte) 3 main::@6/(byte) 4 main::@7/(byte) 5 ) [ findcol::return#0 addpoint::idx#6 addpoint::x#6 addpoint::y#6 addpoint::c#6 ]
[92] (byte) addpoint::x#6 ← phi( main/(byte) 5 main::@3/(byte) 15 main::@4/(byte) 6 main::@5/(byte) 34 main::@6/(byte) 21 main::@7/(byte) 31 ) [ findcol::return#0 addpoint::idx#6 addpoint::x#6 addpoint::y#6 addpoint::c#6 ]
[93] *((word) 4096 + (byte) addpoint::idx#6) ← (byte) addpoint::x#6 [ findcol::return#0 addpoint::idx#6 addpoint::y#6 addpoint::c#6 ]
[94] *((word) 4352 + (byte) addpoint::idx#6) ← (byte) addpoint::y#6 [ findcol::return#0 addpoint::idx#6 addpoint::c#6 ]
[95] *((word) 4608 + (byte) addpoint::idx#6) ← (byte) addpoint::c#6 [ findcol::return#0 ]
[92] (byte) addpoint::c#6 ← phi( main/(byte) 1 main::@3/(byte) 2 main::@4/(byte) 3 main::@5/(byte) 4 main::@6/(byte) 5 main::@7/(byte) 7 ) [ addpoint::idx#6 addpoint::x#6 addpoint::y#6 addpoint::c#6 ]
[92] (byte) addpoint::y#6 ← phi( main/(byte) 5 main::@3/(byte) 8 main::@4/(byte) 14 main::@5/(byte) 2 main::@6/(byte) 17 main::@7/(byte) 22 ) [ addpoint::idx#6 addpoint::x#6 addpoint::y#6 addpoint::c#6 ]
[92] (byte) addpoint::idx#6 ← phi( main/(byte) 0 main::@3/(byte) 1 main::@4/(byte) 2 main::@5/(byte) 3 main::@6/(byte) 4 main::@7/(byte) 5 ) [ addpoint::idx#6 addpoint::x#6 addpoint::y#6 addpoint::c#6 ]
[92] (byte) addpoint::x#6 ← phi( main/(byte) 5 main::@3/(byte) 15 main::@4/(byte) 6 main::@5/(byte) 34 main::@6/(byte) 21 main::@7/(byte) 31 ) [ addpoint::idx#6 addpoint::x#6 addpoint::y#6 addpoint::c#6 ]
[93] *((word) 4096 + (byte) addpoint::idx#6) ← (byte) addpoint::x#6 [ addpoint::idx#6 addpoint::y#6 addpoint::c#6 ]
[94] *((word) 4352 + (byte) addpoint::idx#6) ← (byte) addpoint::y#6 [ addpoint::idx#6 addpoint::c#6 ]
[95] *((word) 4608 + (byte) addpoint::idx#6) ← (byte) addpoint::c#6 [ ]
to:addpoint::@return
addpoint::@return: from addpoint
[96] return [ findcol::return#0 ]
[96] return [ ]
to:@RETURN

File diff suppressed because it is too large Load Diff

View File

@ -67,30 +67,30 @@
(byte) findcol::diff#0 zp byte:7 20002.0
(byte) findcol::diff#1 zp byte:7 20002.0
(byte~) findcol::diff#13 zp byte:6 20002.0
(byte) findcol::diff#2 reg byte x 20002.0
(byte) findcol::diff#3 reg byte x 20002.0
(byte) findcol::diff#2 reg byte a 20002.0
(byte) findcol::diff#3 reg byte a 20002.0
(byte) findcol::diff#4 zp byte:7 10001.0
(byte) findcol::diff#6 reg byte x 13334.666666666666
(byte) findcol::diff#6 reg byte a 13334.666666666666
(byte) findcol::i
(byte) findcol::i#1 reg byte y 15001.5
(byte) findcol::i#12 reg byte y 2631.842105263158
(byte) findcol::i#1 reg byte x 15001.5
(byte) findcol::i#12 reg byte x 2631.842105263158
(byte) findcol::mincol
(byte) findcol::mincol#1 zp byte:8 10001.0
(byte) findcol::mincol#11 zp byte:8 1250.125
(byte) findcol::mincol#2 zp byte:8 13334.666666666666
(byte) findcol::mincol#1 reg byte y 10001.0
(byte) findcol::mincol#11 reg byte y 1250.125
(byte) findcol::mincol#2 reg byte y 13334.666666666666
(byte) findcol::mindiff
(byte) findcol::mindiff#10 zp byte:6 1875.1875
(byte) findcol::mindiff#11 zp byte:6 10001.0
(byte) findcol::return
(byte) findcol::return#0 zp byte:8 144.76315789473685
(byte) findcol::return#0 reg byte y 3667.333333333333
(byte) findcol::x
(byte) findcol::x#0 zp byte:9 1577.1153846153845
(byte) findcol::x#0 zp byte:8 1782.8260869565217
(byte) findcol::xp
(byte) findcol::xp#0 reg byte x 10001.0
(byte) findcol::xp#0 zp byte:7 10001.0
(byte) findcol::y
(byte) findcol::y#0 zp byte:10 1640.2
(byte) findcol::y#0 zp byte:9 1863.8636363636363
(byte) findcol::yp
(byte) findcol::yp#0 zp byte:11 6250.625
(byte) findcol::yp#0 zp byte:10 6250.625
(void()) initscreen()
(label) initscreen::@1
(label) initscreen::@return
@ -130,11 +130,11 @@
zp byte:2 [ render::y#2 render::y#1 addpoint::c#6 ]
zp ptr byte:3 [ render::colline#2 render::colline#1 initscreen::screen#2 initscreen::screen#1 ]
zp byte:5 [ render::x#2 render::x#1 ]
reg byte y [ findcol::i#12 findcol::i#1 ]
reg byte x [ findcol::i#12 findcol::i#1 ]
zp byte:6 [ findcol::mindiff#10 findcol::mindiff#11 findcol::diff#13 ]
zp byte:7 [ findcol::diff#4 findcol::diff#0 findcol::diff#1 ]
reg byte x [ findcol::diff#6 findcol::diff#3 findcol::diff#2 ]
zp byte:8 [ findcol::return#0 findcol::mincol#11 findcol::mincol#2 findcol::mincol#1 ]
zp byte:7 [ findcol::diff#4 findcol::diff#0 findcol::diff#1 findcol::xp#0 ]
reg byte a [ findcol::diff#6 findcol::diff#3 findcol::diff#2 ]
reg byte y [ findcol::return#0 findcol::mincol#11 findcol::mincol#2 findcol::mincol#1 ]
reg byte a [ addpoint::x#6 ]
reg byte y [ addpoint::idx#6 ]
reg byte x [ addpoint::y#6 ]
@ -158,10 +158,9 @@ reg byte a [ animate::$21 ]
reg byte a [ animate::$22 ]
reg byte a [ animate::$24 ]
reg byte a [ animate::$25 ]
zp byte:9 [ findcol::x#0 ]
zp byte:10 [ findcol::y#0 ]
zp byte:8 [ findcol::x#0 ]
zp byte:9 [ findcol::y#0 ]
reg byte a [ render::col#0 ]
reg byte x [ findcol::xp#0 ]
zp byte:11 [ findcol::yp#0 ]
zp byte:10 [ findcol::yp#0 ]
reg byte a [ findcol::$10 ]
reg byte a [ findcol::$8 ]