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:
parent
867d78fd31
commit
fc859e8a03
@ -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));
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -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,17 +28,17 @@ 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);
|
||||
copyCall.setProcedure(procedureRef);
|
||||
addStatementToCurrentBlock(copyCall);
|
||||
getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
|
||||
if(!SymbolTypeBasic.VOID.equals(procedure.getReturnType())) {
|
||||
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));
|
||||
|
@ -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()) {
|
||||
|
@ -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,8 +137,17 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
LabelRef predecessorRef = phiRValue.getPredecessor();
|
||||
ControlFlowBlock predecessor = program.getGraph().getBlock(predecessorRef);
|
||||
List<Statement> predecessorStatements = predecessor.getStatements();
|
||||
Statement predecessorLastStatement = predecessorStatements.get(predecessorStatements.size() - 1);
|
||||
liveRanges.addAlive((VariableRef) phiRValue.getrValue(), predecessorLastStatement);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -315,10 +324,18 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
ArrayList<Statement> statements = new ArrayList<>();
|
||||
List<ControlFlowBlock> predecessors = program.getGraph().getPredecessors(block);
|
||||
for (ControlFlowBlock predecessor : predecessors) {
|
||||
ArrayList<Statement> lastStatements = getLastStatements(predecessor);
|
||||
|
||||
|
||||
statements.addAll(lastStatements);
|
||||
// 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);
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
ControlFlowBlock block = graph.getBlockFromStatementIdx(statementIdx);
|
||||
int maxLoopDepth = loopSet.getMaxLoopDepth(block.getLabel());
|
||||
int maxLoopDepth=1;
|
||||
if(statementIdx!=null) {
|
||||
ControlFlowBlock block = graph.getBlockFromStatementIdx(statementIdx);
|
||||
maxLoopDepth = loopSet.getMaxLoopDepth(block.getLabel());
|
||||
}
|
||||
score += asmSegmentCycles * Math.pow(10, maxLoopDepth);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
20
src/main/java/dk/camelot64/kickc/test/modglobal.kc
Normal file
20
src/main/java/dk/camelot64/kickc/test/modglobal.kc
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 [ ]
|
||||
|
@ -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 [ ]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
23
src/main/java/dk/camelot64/kickc/test/ref/modglobal.asm
Normal file
23
src/main/java/dk/camelot64/kickc/test/ref/modglobal.asm
Normal 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
|
30
src/main/java/dk/camelot64/kickc/test/ref/modglobal.cfg
Normal file
30
src/main/java/dk/camelot64/kickc/test/ref/modglobal.cfg
Normal 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
|
955
src/main/java/dk/camelot64/kickc/test/ref/modglobal.log
Normal file
955
src/main/java/dk/camelot64/kickc/test/ref/modglobal.log
Normal 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
|
||||
|
27
src/main/java/dk/camelot64/kickc/test/ref/modglobal.sym
Normal file
27
src/main/java/dk/camelot64/kickc/test/ref/modglobal.sym
Normal 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 ]
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ]
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
@ -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 ]
|
||||
|
Loading…
Reference in New Issue
Block a user