1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-01-20 05:30:12 +00:00

Split zero page register allocation into separate phase steps. Added live range information to register allocation phases.

This commit is contained in:
jespergravgaard 2017-07-29 10:24:37 +02:00
parent b4d5685222
commit 9634741d76
21 changed files with 770 additions and 480 deletions

View File

@ -49,7 +49,7 @@ public class Compiler {
KickCParser.FileContext file = pass0ParseInput(input, log);
Program program = pass1GenerateSSA(file, log);
pass2OptimizeSSA(program, log);
pass3LiveRangeAnalysis(program, log);
pass3RegisterAllocation(program, log);
AsmProgram asmProgram = pass4GenerateAsm(program, log);
pass5OptimizeAsm(asmProgram, log);
@ -66,13 +66,13 @@ public class Compiler {
}
public void pass5OptimizeAsm(AsmProgram asmProgram, CompileLog log) {
List<Pass5AsmOptimization> pass4Optimizations = new ArrayList<>();
pass4Optimizations.add(new Pass5NextJumpElimination(asmProgram, log));
pass4Optimizations.add(new Pass5UnnecesaryLoadElimination(asmProgram, log));
List<Pass5AsmOptimization> pass5Optimizations = new ArrayList<>();
pass5Optimizations.add(new Pass5NextJumpElimination(asmProgram, log));
pass5Optimizations.add(new Pass5UnnecesaryLoadElimination(asmProgram, log));
boolean asmOptimized = true;
while (asmOptimized) {
asmOptimized = false;
for (Pass5AsmOptimization optimization : pass4Optimizations) {
for (Pass5AsmOptimization optimization : pass5Optimizations) {
boolean stepOptimized = optimization.optimize();
if (stepOptimized) {
log.append("Succesful ASM optimization " + optimization.getClass().getSimpleName());
@ -86,9 +86,6 @@ public class Compiler {
public AsmProgram pass4GenerateAsm(Program program, CompileLog log) {
Pass4ZeroPageAllocationLiveRange pass4ZeroPageAllocationLiveRange = new Pass4ZeroPageAllocationLiveRange(program, log);
pass4ZeroPageAllocationLiveRange.allocate();
Pass4CodeGeneration pass4CodeGeneration = new Pass4CodeGeneration(program);
AsmProgram asmProgram = pass4CodeGeneration.generate();
@ -98,54 +95,53 @@ public class Compiler {
}
private void pass3LiveRangeAnalysis(Program program, CompileLog log) {
private void pass3RegisterAllocation(Program program, CompileLog log) {
Pass3BlockSequencePlanner pass3BlockSequencePlanner = new Pass3BlockSequencePlanner(program, log);
pass3BlockSequencePlanner.plan();
Pass3PhiLifting pass3PhiLifting = new Pass3PhiLifting(program, log);
pass3PhiLifting.perform();
new Pass3PhiLifting(program, log).perform();
pass3BlockSequencePlanner.plan();
log.append("CONTROL FLOW GRAPH - PHI LIFTED");
log.append(program.getGraph().toString(program.getScope()));
pass2AssertSSA(program, log);
Pass3LiveRangesAnalysis pass3LiveRangesAnalysis = new Pass3LiveRangesAnalysis(program, log);
pass3LiveRangesAnalysis.findLiveRanges();
new Pass3LiveRangesAnalysis(program, log).findLiveRanges();
log.append("CONTROL FLOW GRAPH - LIVE RANGES");
log.append(program.getGraph().toString(program.getScope()));
pass2AssertSSA(program, log);
Pass3PhiMemCoalesce pass3PhiMemCoalesce = new Pass3PhiMemCoalesce(program, log);
pass3PhiMemCoalesce.optimize();
Pass2CullEmptyBlocks cullEmptyBlocks = new Pass2CullEmptyBlocks(program, log);
cullEmptyBlocks.optimize();
new Pass3PhiMemCoalesce(program, log).optimize();
new Pass2CullEmptyBlocks(program, log).optimize();
pass3BlockSequencePlanner.plan();
pass3LiveRangesAnalysis.findLiveRanges();
new Pass3LiveRangesAnalysis(program, log).findLiveRanges();
log.append("CONTROL FLOW GRAPH - PHI MEM COALESCED");
log.append(program.getGraph().toString(program.getScope()));
pass2AssertSSA(program, log);
Pass3CallGraphAnalysis pass3CallGraphAnalysis = new Pass3CallGraphAnalysis(program, log);
pass3CallGraphAnalysis.findCallGraph();
new Pass3CallGraphAnalysis(program, log).findCallGraph();
log.append("CALL GRAPH");
log.append(program.getGraph().getCallGraph().toString());
Pass3DominatorsAnalysis pass3DominatorsAnalysis = new Pass3DominatorsAnalysis(program, log);
pass3DominatorsAnalysis.findDominators();
new Pass3DominatorsAnalysis(program, log).findDominators();
log.append("DOMINATORS");
log.append(program.getGraph().getDominators().toString());
Pass3LoopAnalysis pass3LoopAnalysis = new Pass3LoopAnalysis(program, log);
pass3LoopAnalysis.findLoops();
new Pass3LoopAnalysis(program, log).findLoops();
log.append("NATURAL LOOPS");
log.append(program.getGraph().getLoopSet().toString());
Pass3LoopDepthAnalysis pass3LoopDepthAnalysis = new Pass3LoopDepthAnalysis(program, log);
pass3LoopDepthAnalysis.findLoopDepths();
new Pass3LoopDepthAnalysis(program, log).findLoopDepths();
log.append("NATURAL LOOPS WITH DEPTH");
log.append(program.getGraph().getLoopSet().toString());
new Pass3ZeroPageAllocation(program, log).allocate();
new Pass3ZeroPageCoalesce(program, log).allocate();
new Pass3RegistersFinalize(program, log).allocate();
}
public void pass2OptimizeSSA(Program program, CompileLog log) {

View File

@ -15,12 +15,24 @@ public class LiveRangeEquivalenceClass {
private List<VariableRef> variables;
/** The combined live range of the variables. */
private LiveRange classLiveRange;
private LiveRange liveRange;
/** A register allocated to hold all variables of the equivalence class. (null if no register is currently allocated) */
private RegisterAllocation.Register register;
public LiveRangeEquivalenceClass(Program program) {
this.program = program;
this.variables = new ArrayList<>();
this.classLiveRange = new LiveRange();
this.liveRange = new LiveRange();
this.register = null;
}
public RegisterAllocation.Register getRegister() {
return register;
}
public void setRegister(RegisterAllocation.Register register) {
this.register = register;
}
/**
@ -32,12 +44,12 @@ public class LiveRangeEquivalenceClass {
if(variables.contains(variable)) {
return;
}
LiveRangeVariables liveRanges = program.getScope().getLiveRanges();
LiveRangeVariables liveRanges = program.getScope().getLiveRangeVariables();
LiveRange varLiveRange = liveRanges.getLiveRange(variable);
if (classLiveRange.overlaps(varLiveRange)) {
if (liveRange.overlaps(varLiveRange)) {
throw new RuntimeException("Compilation error! Variable live range overlaps live range equivalence class live range. " + variable);
}
classLiveRange.add(varLiveRange);
liveRange.add(varLiveRange);
variables.add(variable);
}
@ -52,12 +64,12 @@ public class LiveRangeEquivalenceClass {
}
public LiveRange getLiveRange() {
return classLiveRange;
return liveRange;
}
public void addAll(LiveRangeEquivalenceClass other) {
variables.addAll(other.variables);
classLiveRange.add(other.classLiveRange);
liveRange.add(other.liveRange);
}
@Override
@ -78,6 +90,9 @@ public class LiveRangeEquivalenceClass {
@Override
public String toString() {
StringBuilder s = new StringBuilder();
if(register!=null) {
s.append(register.toString()).append(" ");
}
s.append("[ ");
for (VariableRef variable : variables) {
s.append(variable.toString());

View File

@ -11,7 +11,9 @@ public class ProgramScope extends Scope {
private RegisterAllocation allocation;
private LiveRangeVariables liveRanges;
private LiveRangeVariables liveRangeVariables;
private LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet;
public ProgramScope() {
super("", null);
@ -50,12 +52,20 @@ public class ProgramScope extends Scope {
return allocation;
}
public void setLiveRanges(LiveRangeVariables liveRanges) {
this.liveRanges = liveRanges;
public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) {
this.liveRangeVariables = liveRangeVariables;
}
public LiveRangeVariables getLiveRanges() {
return liveRanges;
public LiveRangeVariables getLiveRangeVariables() {
return liveRangeVariables;
}
public void setLiveRangeEquivalenceClassSet(LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet) {
this.liveRangeEquivalenceClassSet = liveRangeEquivalenceClassSet;
}
public LiveRangeEquivalenceClassSet getLiveRangeEquivalenceClassSet() {
return liveRangeEquivalenceClassSet;
}
@Override
@ -87,6 +97,19 @@ public class ProgramScope extends Scope {
return getSymbolTableContents(this);
}
@Override
public String getSymbolTableContents(ProgramScope scope) {
StringBuilder out = new StringBuilder();
out.append(super.getSymbolTableContents(scope));
if(liveRangeEquivalenceClassSet!=null) {
out.append("\n");
for (LiveRangeEquivalenceClass liveRangeEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
out.append(liveRangeEquivalenceClass);
out.append("\n");
}
}
return out.toString();
}
@Override
public String toString(ProgramScope scope) {

View File

@ -1,7 +1,6 @@
package dk.camelot64.kickc.icl;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@ -40,6 +39,8 @@ public class RegisterAllocation {
RegisterType getType();
boolean isZp();
}
/** The register type. */
@ -65,6 +66,11 @@ public class RegisterAllocation {
return RegisterType.ZP_BYTE;
}
@Override
public boolean isZp() {
return true;
}
@Override
public String toString() {
return "zp byte:"+zp;
@ -108,6 +114,11 @@ public class RegisterAllocation {
return RegisterType.ZP_WORD;
}
@Override
public boolean isZp() {
return true;
}
@Override
public String toString() {
return "zp word :"+zp;
@ -151,6 +162,11 @@ public class RegisterAllocation {
return RegisterType.ZP_BOOL;
}
@Override
public boolean isZp() {
return true;
}
@Override
public String toString() {
return "zp bool:"+zp;
@ -189,6 +205,11 @@ public class RegisterAllocation {
return RegisterType.ZP_PTR_BYTE;
}
@Override
public boolean isZp() {
return true;
}
@Override
public String toString() {
return "zp ptr byte:"+zp;
@ -226,6 +247,11 @@ public class RegisterAllocation {
return RegisterType.REG_X_BYTE;
}
@Override
public boolean isZp() {
return false;
}
@Override
public String toString() {
return "reg byte x";
@ -252,6 +278,11 @@ public class RegisterAllocation {
return RegisterType.REG_Y_BYTE;
}
@Override
public boolean isZp() {
return false;
}
@Override
public String toString() {
return "reg byte y";
@ -278,6 +309,11 @@ public class RegisterAllocation {
return RegisterType.REG_A_BYTE;
}
@Override
public boolean isZp() {
return false;
}
@Override
public String toString() {
return "reg byte a";
@ -304,6 +340,11 @@ public class RegisterAllocation {
return RegisterType.REG_ALU_BYTE;
}
@Override
public boolean isZp() {
return false;
}
@Override
public String toString() {
return "reg byte alu";

View File

@ -46,10 +46,10 @@ public abstract class StatementBase implements Statement {
}
public String aliveString(ProgramScope scope) {
if(scope==null || scope.getLiveRanges()==null) {
if(scope==null || scope.getLiveRangeVariables()==null) {
return "";
}
LiveRangeVariables liveRanges = scope.getLiveRanges();
LiveRangeVariables liveRanges = scope.getLiveRangeVariables();
List<VariableRef> alive = liveRanges.getAlive(this);
StringBuilder str = new StringBuilder();
str.append(" [ ");

View File

@ -24,18 +24,18 @@ public class Pass3LiveRangesAnalysis {
public void findLiveRanges() {
generateStatementIndexes();
LiveRangeVariables liveRanges = initializeLiveRanges();
program.getScope().setLiveRanges(liveRanges);
program.getScope().setLiveRangeVariables(liveRanges);
//log.append("CONTROL FLOW GRAPH - LIVE RANGES");
//log.append(program.getGraph().toString(program.getScope()));
boolean propagating;
do {
propagating = propagateLiveRanges(liveRanges);
program.getScope().setLiveRanges(liveRanges);
program.getScope().setLiveRangeVariables(liveRanges);
log.append("Propagating live ranges...");
//log.append("CONTROL FLOW GRAPH - LIVE RANGES");
//log.append(program.getGraph().toString(program.getScope()));
} while (propagating);
program.getScope().setLiveRanges(liveRanges);
program.getScope().setLiveRangeVariables(liveRanges);
}

View File

@ -0,0 +1,78 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.icl.*;
/**
* Move register allocation from equivalence classes to RegisterAllocation.
* Also rebase zero page registers.
*/
public class Pass3RegistersFinalize {
private Program program;
private CompileLog log;
public Pass3RegistersFinalize(Program program, CompileLog log) {
this.program = program;
this.log = log;
}
public void allocate() {
LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet = program.getScope().getLiveRangeEquivalenceClassSet();
RegisterAllocation allocation = new RegisterAllocation();
for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
RegisterAllocation.Register register = equivalenceClass.getRegister();
if(register.isZp()) {
String before = register.toString();
VariableRef variable = equivalenceClass.getVariables().get(0);
Variable symbol = program.getScope().getVariable(variable);
register = allocateNewRegisterZp(symbol.getType());
log.append("Re-allocated ZP register from "+before+" to "+register.toString());
}
for (VariableRef variable : equivalenceClass.getVariables()) {
allocation.allocate(variable, register);
}
}
program.getScope().setAllocation(allocation);
}
/**
* The current zero page used to create new registers when needed.
*/
private int currentZp = 2;
/**
* Create a new register for a specific variable type.
*
* @param varType The variable type to create a register for.
* The register type created uses one or more zero page locations based on the variable type
* @return The new zeropage register
*/
private RegisterAllocation.Register allocateNewRegisterZp(SymbolType varType) {
if (varType.equals(SymbolTypeBasic.BYTE)) {
return new RegisterAllocation.RegisterZpByte(currentZp++);
} else if (varType.equals(SymbolTypeBasic.WORD)) {
RegisterAllocation.RegisterZpWord registerZpWord =
new RegisterAllocation.RegisterZpWord(currentZp);
currentZp = currentZp + 2;
return registerZpWord;
} else if (varType.equals(SymbolTypeBasic.BOOLEAN)) {
return new RegisterAllocation.RegisterZpBool(currentZp++);
} else if (varType.equals(SymbolTypeBasic.VOID)) {
// No need to allocate register for VOID value
return null;
} else if (varType instanceof SymbolTypePointer) {
RegisterAllocation.RegisterZpPointerByte registerZpPointerByte =
new RegisterAllocation.RegisterZpPointerByte(currentZp);
currentZp = currentZp + 2;
return registerZpPointerByte;
} else {
throw new RuntimeException("Unhandled variable type " + varType);
}
}
}

View File

@ -9,12 +9,12 @@ import java.util.List;
/**
* Zero Page Register Allocation for variables based on live ranges and phi equivalence classes.
*/
public class Pass4ZeroPageAllocationLiveRange {
public class Pass3ZeroPageAllocation {
private Program program;
private CompileLog log;
public Pass4ZeroPageAllocationLiveRange(Program program, CompileLog log) {
public Pass3ZeroPageAllocation(Program program, CompileLog log) {
this.program = program;
this.log = log;
}
@ -51,16 +51,16 @@ public class Pass4ZeroPageAllocationLiveRange {
for (LiveRangeEquivalenceClass liveRangeEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
List<VariableRef> variables = liveRangeEquivalenceClass.getVariables();
Variable firstVar = program.getScope().getVariable(variables.get(0));
RegisterAllocation.Register zpRegister = allocateNewRegister(firstVar.getType());
for (VariableRef variable : variables) {
allocation.allocate(variable, zpRegister);
}
log.append("Allocated "+zpRegister+" to "+liveRangeEquivalenceClass);
RegisterAllocation.Register zpRegister = allocateNewRegisterZp(firstVar.getType());
liveRangeEquivalenceClass.setRegister(zpRegister);
log.append("Allocated " + zpRegister + " to " + liveRangeEquivalenceClass);
}
program.getScope().setAllocation(allocation);
program.getScope().setLiveRangeEquivalenceClassSet(liveRangeEquivalenceClassSet);
}
/** Add all variables to a non-overlapping equivalence or create a new one. */
/**
* Add all variables to a non-overlapping equivalence or create a new one.
*/
private class EquivalenceClassAdder extends ControlFlowGraphBaseVisitor<Void> {
private LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet;
@ -82,10 +82,10 @@ public class Pass4ZeroPageAllocationLiveRange {
}
private void addToEquivalenceClassSet(VariableRef lValVar, List<VariableRef> preferences) {
LiveRangeVariables liveRangeVariables = program.getScope().getLiveRanges();
LiveRangeVariables liveRangeVariables = program.getScope().getLiveRangeVariables();
LiveRangeEquivalenceClass lValEquivalenceClass =
liveRangeEquivalenceClassSet.getEquivalenceClass(lValVar);
if(lValEquivalenceClass==null) {
if (lValEquivalenceClass == null) {
LiveRange lValLiveRange = liveRangeVariables.getLiveRange(lValVar);
// Variable in need of an equivalence class - Look through preferences
LiveRangeEquivalenceClass chosen = null;
@ -104,37 +104,24 @@ public class Pass4ZeroPageAllocationLiveRange {
}
}
if (chosen == null) {
// No preference usable - look through all others
for (LiveRangeEquivalenceClass potentialEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
VariableRef potentialVariableRef = potentialEquivalenceClass.getVariables().get(0);
Variable potentialVariable = program.getScope().getVariable(potentialVariableRef);
Variable lValVariable = program.getScope().getVariable(lValVar);
if (lValVariable.getType().equals(potentialVariable.getType())) {
if (!lValLiveRange.overlaps(potentialEquivalenceClass.getLiveRange())) {
chosen = potentialEquivalenceClass;
chosen.addVariable(lValVar);
break;
}
}
}
}
if(chosen==null) {
// No other equivalence class is usable - create a new one
// No preference usable - create a new one
chosen = liveRangeEquivalenceClassSet.getOrCreateEquivalenceClass(lValVar);
}
log.append("Added variable "+lValVar+" to zero page equivalence class "+chosen);
log.append("Added variable " + lValVar + " to zero page equivalence class " + chosen);
}
}
private void addPreference(List<VariableRef> preferences, RValue rValue) {
if(rValue instanceof VariableRef) {
if (rValue instanceof VariableRef) {
preferences.add((VariableRef) rValue);
}
}
}
/** Coalesce equivalence classes when they do not overlap based on all copy assignments to variables. */
/**
* Coalesce equivalence classes when they do not overlap based on all copy assignments to variables.
*/
private class EquivalenceClassCopyCoalescer extends ControlFlowGraphBaseVisitor<Void> {
private LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet;
@ -153,11 +140,11 @@ public class Pass4ZeroPageAllocationLiveRange {
VariableRef assignVar = (VariableRef) assignment.getrValue2();
LiveRangeEquivalenceClass assignVarEquivalenceClass = liveRangeEquivalenceClassSet.getOrCreateEquivalenceClass(assignVar);
if (lValEquivalenceClass.equals(assignVarEquivalenceClass)) {
log.append("Coalesced (already) " + assignment+" in "+lValEquivalenceClass);
log.append("Coalesced (already) " + assignment + " in " + lValEquivalenceClass);
} else if (!lValEquivalenceClass.getLiveRange().overlaps(assignVarEquivalenceClass.getLiveRange())) {
lValEquivalenceClass.addAll(assignVarEquivalenceClass);
liveRangeEquivalenceClassSet.remove(assignVarEquivalenceClass);
log.append("Coalesced " + assignment+" into "+lValEquivalenceClass);
log.append("Coalesced " + assignment + " into " + lValEquivalenceClass);
} else {
log.append("Not coalescing " + assignment);
}
@ -168,16 +155,19 @@ public class Pass4ZeroPageAllocationLiveRange {
}
/** The current zero page used to create new registers when needed. */
/**
* The current zero page used to create new registers when needed.
*/
private int currentZp = 2;
/**
* Create a new register for a specific variable type.
*
* @param varType The variable type to create a register for.
* The register type created uses one or more zero page locations based on the variable type
* The register type created uses one or more zero page locations based on the variable type
* @return The new zeropage register
*/
private RegisterAllocation.Register allocateNewRegister(SymbolType varType) {
private RegisterAllocation.Register allocateNewRegisterZp(SymbolType varType) {
if (varType.equals(SymbolTypeBasic.BYTE)) {
return new RegisterAllocation.RegisterZpByte(currentZp++);
} else if (varType.equals(SymbolTypeBasic.WORD)) {

View File

@ -0,0 +1,71 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.icl.*;
/**
* Coalesces zero page registers where their live ranges do not overlap.
* A final step done after all other register optimizations and before ASM generation.
*/
public class Pass3ZeroPageCoalesce {
private Program program;
private CompileLog log;
public Pass3ZeroPageCoalesce(Program program, CompileLog log) {
this.program = program;
this.log = log;
}
public void allocate() {
LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet = program.getScope().getLiveRangeEquivalenceClassSet();
boolean change;
do {
change = coalesce(liveRangeEquivalenceClassSet);
} while (change);
}
/**
* Find two equivalence classes that can be coalesced into one - and perform the colalescence.
*
* @param liveRangeEquivalenceClassSet The set of live range equivalence classes
* @return true if any classes were coalesced. False otherwise.
*/
private boolean coalesce(LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet) {
for (LiveRangeEquivalenceClass myEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
for (LiveRangeEquivalenceClass otherEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
if (!myEquivalenceClass.equals(otherEquivalenceClass)) {
if(canCoalesce(myEquivalenceClass, otherEquivalenceClass)) {
log.append("Coalescing zero page register [ "+myEquivalenceClass+" ] with [ "+otherEquivalenceClass+" ]" );
myEquivalenceClass.addAll(otherEquivalenceClass);
liveRangeEquivalenceClassSet.remove(otherEquivalenceClass);
return true;
}
}
}
}
return false;
}
private boolean canCoalesce(LiveRangeEquivalenceClass myEquivalenceClass, LiveRangeEquivalenceClass otherEquivalenceClass) {
VariableRef myVariableRef = myEquivalenceClass.getVariables().get(0);
Variable myVariable = program.getScope().getVariable(myVariableRef);
VariableRef otherVariableRef = otherEquivalenceClass.getVariables().get(0);
Variable otherVariable = program.getScope().getVariable(otherVariableRef);
if (myVariable.getType().equals(otherVariable.getType())) {
// Types match
if (myEquivalenceClass.getRegister().isZp() && otherEquivalenceClass.getRegister().isZp()) {
// Both registers are on Zero Page
if (!myEquivalenceClass.getLiveRange().overlaps(otherEquivalenceClass.getLiveRange())) {
// Live ranges do not overlap
// Perform coalesce!
return true;
}
}
}
return false;
}
}

View File

@ -48,6 +48,7 @@ public class Pass4RegisterAllocationTrivial {
*/
// Optimal Registers for flipper-rex2.kc
/*
allocation.allocate(new VariableRef("plot::i#0"), RegisterAllocation.getRegisterX());
allocation.allocate(new VariableRef("plot::i#1"), RegisterAllocation.getRegisterX());
allocation.allocate(new VariableRef("plot::i#2"), RegisterAllocation.getRegisterX());
@ -103,6 +104,7 @@ public class Pass4RegisterAllocationTrivial {
allocation.allocate(new VariableRef("main::c#2"), RegisterAllocation.getRegisterX());
allocation.allocate(new VariableRef("main::c#3"), RegisterAllocation.getRegisterX());
allocation.allocate(new VariableRef("main::c#4"), RegisterAllocation.getRegisterX());
*/
symbols.setAllocation(allocation);

View File

@ -1019,10 +1019,14 @@ Complete equivalence classes
[ x#2 x#1 ]
[ e#3 e#5 e#1 e#2 ]
[ y#2 y#4 y#1 ]
Allocated zp ptr byte:2 to [ cursor#3 cursor#5 cursor#1 cursor#2 ]
Allocated zp byte:4 to [ x#2 x#1 ]
Allocated zp byte:5 to [ e#3 e#5 e#1 e#2 ]
Allocated zp byte:6 to [ y#2 y#4 y#1 ]
Allocated zp ptr byte:2 to zp ptr byte:2 [ cursor#3 cursor#5 cursor#1 cursor#2 ]
Allocated zp byte:4 to zp byte:4 [ x#2 x#1 ]
Allocated zp byte:5 to zp byte:5 [ e#3 e#5 e#1 e#2 ]
Allocated zp byte:6 to zp byte:6 [ y#2 y#4 y#1 ]
Re-allocated ZP register from zp ptr byte:2 to zp ptr byte:2
Re-allocated ZP register from zp byte:4 to zp byte:4
Re-allocated ZP register from zp byte:5 to zp byte:5
Re-allocated ZP register from zp byte:6 to zp byte:6
INITIAL ASM
BBEGIN:
B1_from_BBEGIN:
@ -1291,6 +1295,11 @@ FINAL SYMBOL TABLE
(byte) y1
(byte) yd
zp ptr byte:2 [ cursor#3 cursor#5 cursor#1 cursor#2 ]
zp byte:4 [ x#2 x#1 ]
zp byte:5 [ e#3 e#5 e#1 e#2 ]
zp byte:6 [ y#2 y#4 y#1 ]
FINAL CODE
BBEGIN:
B1_from_BBEGIN:

View File

@ -39,29 +39,29 @@ main__Breturn:
plot:
plot__B1_from_plot:
lda #16
sta 5
sta 2
lda #<1236
sta 3
lda #>1236
sta 3+1
lda #0
sta 6
sta 5
plot__B1_from_B3:
plot__B1:
plot__B2_from_B1:
lda #0
sta 7
sta 6
plot__B2_from_B2:
plot__B2:
ldy 6
ldy 5
lda 4096,y
sta 2
lda 2
ldy 7
sta (3),y
inc 6
inc 7
sta 7
lda 7
ldy 6
sta (3),y
inc 5
inc 6
lda 6
cmp #16
bcc plot__B2_from_B2
plot__B3:
@ -72,72 +72,72 @@ plot__B3:
bcc !+
inc 3+1
!:
dec 5
lda 5
dec 2
lda 2
bne plot__B1_from_B3
plot__Breturn:
rts
flip:
flip__B1_from_flip:
lda #16
sta 8
sta 2
lda #15
sta 10
sta 6
lda #0
sta 9
sta 5
flip__B1_from_B4:
flip__B1:
flip__B2_from_B1:
lda #16
sta 11
sta 7
flip__B2_from_B2:
flip__B2:
ldy 9
ldy 5
lda 4096,y
sta 2
lda 2
ldy 10
sta 8
lda 8
ldy 6
sta 4352,y
inc 9
lda 10
inc 5
lda 6
clc
adc #16
sta 10
dec 11
lda 11
sta 6
dec 7
lda 7
bne flip__B2_from_B2
flip__B4:
dec 10
dec 8
lda 8
dec 6
dec 2
lda 2
bne flip__B1_from_B4
flip__B3_from_B4:
lda #0
sta 12
sta 2
flip__B3_from_B3:
flip__B3:
ldy 12
ldy 2
lda 4352,y
sta 2
lda 2
ldy 12
sta 5
lda 5
ldy 2
sta 4096,y
inc 12
lda 12
inc 2
lda 2
bne flip__B3_from_B3
flip__Breturn:
rts
prepare:
prepare__B1_from_prepare:
lda #0
sta 13
sta 2
prepare__B1_from_B1:
prepare__B1:
ldy 13
ldy 2
tya
sta 4096,y
inc 13
lda 13
inc 2
lda 2
bne prepare__B1_from_B1
prepare__Breturn:
rts

File diff suppressed because it is too large Load Diff

View File

@ -5,31 +5,31 @@
(byte[256]) buffer1
(byte[256]) buffer2
(void()) flip()
(byte~) flip::$0 zp byte:2
(byte~) flip::$4 zp byte:2
(byte~) flip::$0 zp byte:8
(byte~) flip::$4 zp byte:5
(label) flip::@1
(label) flip::@2
(label) flip::@3
(label) flip::@4
(label) flip::@return
(byte) flip::c
(byte) flip::c#1 zp byte:11
(byte) flip::c#2 zp byte:11
(byte) flip::c#1 zp byte:7
(byte) flip::c#2 zp byte:7
(byte) flip::dstIdx
(byte) flip::dstIdx#1 zp byte:10
(byte) flip::dstIdx#2 zp byte:10
(byte) flip::dstIdx#3 zp byte:10
(byte) flip::dstIdx#5 zp byte:10
(byte) flip::dstIdx#1 zp byte:6
(byte) flip::dstIdx#2 zp byte:6
(byte) flip::dstIdx#3 zp byte:6
(byte) flip::dstIdx#5 zp byte:6
(byte) flip::i
(byte) flip::i#1 zp byte:12
(byte) flip::i#2 zp byte:12
(byte) flip::i#1 zp byte:2
(byte) flip::i#2 zp byte:2
(byte) flip::r
(byte) flip::r#1 zp byte:8
(byte) flip::r#2 zp byte:8
(byte) flip::r#1 zp byte:2
(byte) flip::r#2 zp byte:2
(byte) flip::srcIdx
(byte) flip::srcIdx#1 zp byte:9
(byte) flip::srcIdx#2 zp byte:9
(byte) flip::srcIdx#3 zp byte:9
(byte) flip::srcIdx#1 zp byte:5
(byte) flip::srcIdx#2 zp byte:5
(byte) flip::srcIdx#3 zp byte:5
(void()) main()
(byte~) main::$1 zp byte:5
@ -46,29 +46,29 @@
(byte) main::c#2 zp byte:2
(void()) plot()
(byte~) plot::$3 zp byte:2
(byte~) plot::$3 zp byte:7
(label) plot::@1
(label) plot::@2
(label) plot::@3
(label) plot::@return
(byte) plot::i
(byte) plot::i#1 zp byte:6
(byte) plot::i#2 zp byte:6
(byte) plot::i#3 zp byte:6
(byte) plot::i#1 zp byte:5
(byte) plot::i#2 zp byte:5
(byte) plot::i#3 zp byte:5
(byte*) plot::line
(byte*) plot::line#1 zp ptr byte:3
(byte*) plot::line#2 zp ptr byte:3
(byte) plot::x
(byte) plot::x#1 zp byte:7
(byte) plot::x#2 zp byte:7
(byte) plot::x#1 zp byte:6
(byte) plot::x#2 zp byte:6
(byte) plot::y
(byte) plot::y#1 zp byte:5
(byte) plot::y#2 zp byte:5
(byte) plot::y#1 zp byte:2
(byte) plot::y#2 zp byte:2
(void()) prepare()
(label) prepare::@1
(label) prepare::@return
(byte) prepare::i
(byte) prepare::i#1 zp byte:13
(byte) prepare::i#2 zp byte:13
(byte) prepare::i#1 zp byte:2
(byte) prepare::i#2 zp byte:2

View File

@ -369,8 +369,10 @@ Copy Coalesced equivalence classes
Complete equivalence classes
[ i#2 i#1 ]
[ s#2 s#4 s#1 ]
Allocated zp byte:2 to [ i#2 i#1 ]
Allocated zp byte:3 to [ s#2 s#4 s#1 ]
Allocated zp byte:2 to zp byte:2 [ i#2 i#1 ]
Allocated zp byte:3 to zp byte:3 [ s#2 s#4 s#1 ]
Re-allocated ZP register from zp byte:2 to zp byte:2
Re-allocated ZP register from zp byte:3 to zp byte:3
INITIAL ASM
BBEGIN:
B1_from_BBEGIN:
@ -510,6 +512,9 @@ FINAL SYMBOL TABLE
(byte) s#2 zp byte:3
(byte) s#4 zp byte:3
zp byte:2 [ i#2 i#1 ]
zp byte:3 [ s#2 s#4 s#1 ]
FINAL CODE
BBEGIN:
B1_from_BBEGIN:

View File

@ -26,44 +26,44 @@ main__Breturn:
nest1:
nest1__B1_from_nest1:
lda #100
sta 4
sta 2
nest1__B1_from_B3:
nest1__B1:
nest1__B2_from_B1:
lda #100
sta 5
sta 3
nest1__B2_from_B5:
nest1__B2:
jsr nest2
nest1__B5:
dec 5
lda 5
dec 3
lda 3
bne nest1__B2_from_B5
nest1__B3:
dec 4
lda 4
dec 2
lda 2
bne nest1__B1_from_B3
nest1__Breturn:
rts
nest2:
nest2__B1_from_nest2:
lda #100
sta 6
sta 2
nest2__B1_from_B3:
nest2__B1:
nest2__B2_from_B1:
lda #100
sta 7
sta 3
nest2__B2_from_B2:
nest2__B2:
lda 7
lda 3
sta 1024
dec 7
lda 7
dec 3
lda 3
bne nest2__B2_from_B2
nest2__B3:
dec 6
lda 6
dec 2
lda 2
bne nest2__B1_from_B3
nest2__Breturn:
rts

View File

@ -1793,12 +1793,18 @@ Complete equivalence classes
[ nest1::j#2 nest1::j#1 ]
[ nest2::i#2 nest2::i#1 ]
[ nest2::j#2 nest2::j#1 ]
Allocated zp byte:2 to [ main::i#2 main::i#1 ]
Allocated zp byte:3 to [ main::j#2 main::j#1 ]
Allocated zp byte:4 to [ nest1::i#2 nest1::i#1 ]
Allocated zp byte:5 to [ nest1::j#2 nest1::j#1 ]
Allocated zp byte:6 to [ nest2::i#2 nest2::i#1 ]
Allocated zp byte:7 to [ nest2::j#2 nest2::j#1 ]
Allocated zp byte:2 to zp byte:2 [ main::i#2 main::i#1 ]
Allocated zp byte:3 to zp byte:3 [ main::j#2 main::j#1 ]
Allocated zp byte:4 to zp byte:4 [ nest1::i#2 nest1::i#1 ]
Allocated zp byte:5 to zp byte:5 [ nest1::j#2 nest1::j#1 ]
Allocated zp byte:6 to zp byte:6 [ nest2::i#2 nest2::i#1 ]
Allocated zp byte:7 to zp byte:7 [ nest2::j#2 nest2::j#1 ]
Coalescing zero page register [ zp byte:2 [ main::i#2 main::i#1 ] ] with [ zp byte:4 [ nest1::i#2 nest1::i#1 ] ]
Coalescing zero page register [ zp byte:2 [ main::i#2 main::i#1 nest1::i#2 nest1::i#1 ] ] with [ zp byte:6 [ nest2::i#2 nest2::i#1 ] ]
Coalescing zero page register [ zp byte:3 [ main::j#2 main::j#1 ] ] with [ zp byte:5 [ nest1::j#2 nest1::j#1 ] ]
Coalescing zero page register [ zp byte:3 [ main::j#2 main::j#1 nest1::j#2 nest1::j#1 ] ] with [ zp byte:7 [ nest2::j#2 nest2::j#1 ] ]
Re-allocated ZP register from zp byte:2 to zp byte:2
Re-allocated ZP register from zp byte:3 to zp byte:3
INITIAL ASM
BBEGIN:
jsr main
@ -1845,7 +1851,7 @@ nest1:
nest1__B1_from_nest1:
// (byte) nest1::i#2 = (byte) 100 // zpby1=coby1
lda #100
sta 4
sta 2
jmp nest1__B1
nest1__B1_from_B3:
// (byte) nest1::i#2 = (byte) nest1::i#1 // register copy
@ -1854,7 +1860,7 @@ nest1__B1:
nest1__B2_from_B1:
// (byte) nest1::j#2 = (byte) 100 // zpby1=coby1
lda #100
sta 5
sta 3
jmp nest1__B2
nest1__B2_from_B5:
// (byte) nest1::j#2 = (byte) nest1::j#1 // register copy
@ -1864,16 +1870,16 @@ nest1__B2:
jmp nest1__B5
nest1__B5:
// [12] (byte) nest1::j#1 ← -- (byte) nest1::j#2 [ nest1::j#1 nest1::i#2 ] // zpby1=_dec_zpby1
dec 5
dec 3
// [13] if((byte) nest1::j#1>(byte) 0) goto nest1::@2 [ nest1::j#1 nest1::i#2 ] // zpby1_gt_0_then_la1
lda 5
lda 3
bne nest1__B2_from_B5
jmp nest1__B3
nest1__B3:
// [14] (byte) nest1::i#1 ← -- (byte) nest1::i#2 [ nest1::i#1 ] // zpby1=_dec_zpby1
dec 4
dec 2
// [15] if((byte) nest1::i#1>(byte) 0) goto nest1::@1 [ nest1::i#1 ] // zpby1_gt_0_then_la1
lda 4
lda 2
bne nest1__B1_from_B3
jmp nest1__Breturn
nest1__Breturn:
@ -1882,7 +1888,7 @@ nest2:
nest2__B1_from_nest2:
// (byte) nest2::i#2 = (byte) 100 // zpby1=coby1
lda #100
sta 6
sta 2
jmp nest2__B1
nest2__B1_from_B3:
// (byte) nest2::i#2 = (byte) nest2::i#1 // register copy
@ -1891,26 +1897,26 @@ nest2__B1:
nest2__B2_from_B1:
// (byte) nest2::j#2 = (byte) 100 // zpby1=coby1
lda #100
sta 7
sta 3
jmp nest2__B2
nest2__B2_from_B2:
// (byte) nest2::j#2 = (byte) nest2::j#1 // register copy
jmp nest2__B2
nest2__B2:
// [19] *((word) 1024) ← (byte) nest2::j#2 [ nest2::j#2 nest2::i#2 ] // coptr1=zpby1
lda 7
lda 3
sta 1024
// [20] (byte) nest2::j#1 ← -- (byte) nest2::j#2 [ nest2::j#1 nest2::i#2 ] // zpby1=_dec_zpby1
dec 7
dec 3
// [21] if((byte) nest2::j#1>(byte) 0) goto nest2::@2 [ nest2::j#1 nest2::i#2 ] // zpby1_gt_0_then_la1
lda 7
lda 3
bne nest2__B2_from_B2
jmp nest2__B3
nest2__B3:
// [22] (byte) nest2::i#1 ← -- (byte) nest2::i#2 [ nest2::i#1 ] // zpby1=_dec_zpby1
dec 6
dec 2
// [23] if((byte) nest2::i#1>(byte) 0) goto nest2::@1 [ nest2::i#1 ] // zpby1_gt_0_then_la1
lda 6
lda 2
bne nest2__B1_from_B3
jmp nest2__Breturn
nest2__Breturn:
@ -1972,7 +1978,7 @@ nest1:
nest1__B1_from_nest1:
// (byte) nest1::i#2 = (byte) 100 // zpby1=coby1
lda #100
sta 4
sta 2
jmp nest1__B1
nest1__B1_from_B3:
// (byte) nest1::i#2 = (byte) nest1::i#1 // register copy
@ -1980,7 +1986,7 @@ nest1__B1:
nest1__B2_from_B1:
// (byte) nest1::j#2 = (byte) 100 // zpby1=coby1
lda #100
sta 5
sta 3
jmp nest1__B2
nest1__B2_from_B5:
// (byte) nest1::j#2 = (byte) nest1::j#1 // register copy
@ -1988,15 +1994,15 @@ nest1__B2:
jsr nest2
nest1__B5:
// [12] (byte) nest1::j#1 ← -- (byte) nest1::j#2 [ nest1::j#1 nest1::i#2 ] // zpby1=_dec_zpby1
dec 5
dec 3
// [13] if((byte) nest1::j#1>(byte) 0) goto nest1::@2 [ nest1::j#1 nest1::i#2 ] // zpby1_gt_0_then_la1
lda 5
lda 3
bne nest1__B2_from_B5
nest1__B3:
// [14] (byte) nest1::i#1 ← -- (byte) nest1::i#2 [ nest1::i#1 ] // zpby1=_dec_zpby1
dec 4
dec 2
// [15] if((byte) nest1::i#1>(byte) 0) goto nest1::@1 [ nest1::i#1 ] // zpby1_gt_0_then_la1
lda 4
lda 2
bne nest1__B1_from_B3
nest1__Breturn:
rts
@ -2004,7 +2010,7 @@ nest2:
nest2__B1_from_nest2:
// (byte) nest2::i#2 = (byte) 100 // zpby1=coby1
lda #100
sta 6
sta 2
jmp nest2__B1
nest2__B1_from_B3:
// (byte) nest2::i#2 = (byte) nest2::i#1 // register copy
@ -2012,24 +2018,24 @@ nest2__B1:
nest2__B2_from_B1:
// (byte) nest2::j#2 = (byte) 100 // zpby1=coby1
lda #100
sta 7
sta 3
jmp nest2__B2
nest2__B2_from_B2:
// (byte) nest2::j#2 = (byte) nest2::j#1 // register copy
nest2__B2:
// [19] *((word) 1024) ← (byte) nest2::j#2 [ nest2::j#2 nest2::i#2 ] // coptr1=zpby1
lda 7
lda 3
sta 1024
// [20] (byte) nest2::j#1 ← -- (byte) nest2::j#2 [ nest2::j#1 nest2::i#2 ] // zpby1=_dec_zpby1
dec 7
dec 3
// [21] if((byte) nest2::j#1>(byte) 0) goto nest2::@2 [ nest2::j#1 nest2::i#2 ] // zpby1_gt_0_then_la1
lda 7
lda 3
bne nest2__B2_from_B2
nest2__B3:
// [22] (byte) nest2::i#1 ← -- (byte) nest2::i#2 [ nest2::i#1 ] // zpby1=_dec_zpby1
dec 6
dec 2
// [23] if((byte) nest2::i#1>(byte) 0) goto nest2::@1 [ nest2::i#1 ] // zpby1_gt_0_then_la1
lda 6
lda 2
bne nest2__B1_from_B3
nest2__Breturn:
rts
@ -2079,29 +2085,29 @@ nest1:
nest1__B1_from_nest1:
// (byte) nest1::i#2 = (byte) 100 // zpby1=coby1
lda #100
sta 4
sta 2
nest1__B1_from_B3:
// (byte) nest1::i#2 = (byte) nest1::i#1 // register copy
nest1__B1:
nest1__B2_from_B1:
// (byte) nest1::j#2 = (byte) 100 // zpby1=coby1
lda #100
sta 5
sta 3
nest1__B2_from_B5:
// (byte) nest1::j#2 = (byte) nest1::j#1 // register copy
nest1__B2:
jsr nest2
nest1__B5:
// [12] (byte) nest1::j#1 ← -- (byte) nest1::j#2 [ nest1::j#1 nest1::i#2 ] // zpby1=_dec_zpby1
dec 5
dec 3
// [13] if((byte) nest1::j#1>(byte) 0) goto nest1::@2 [ nest1::j#1 nest1::i#2 ] // zpby1_gt_0_then_la1
lda 5
lda 3
bne nest1__B2_from_B5
nest1__B3:
// [14] (byte) nest1::i#1 ← -- (byte) nest1::i#2 [ nest1::i#1 ] // zpby1=_dec_zpby1
dec 4
dec 2
// [15] if((byte) nest1::i#1>(byte) 0) goto nest1::@1 [ nest1::i#1 ] // zpby1_gt_0_then_la1
lda 4
lda 2
bne nest1__B1_from_B3
nest1__Breturn:
rts
@ -2109,30 +2115,30 @@ nest2:
nest2__B1_from_nest2:
// (byte) nest2::i#2 = (byte) 100 // zpby1=coby1
lda #100
sta 6
sta 2
nest2__B1_from_B3:
// (byte) nest2::i#2 = (byte) nest2::i#1 // register copy
nest2__B1:
nest2__B2_from_B1:
// (byte) nest2::j#2 = (byte) 100 // zpby1=coby1
lda #100
sta 7
sta 3
nest2__B2_from_B2:
// (byte) nest2::j#2 = (byte) nest2::j#1 // register copy
nest2__B2:
// [19] *((word) 1024) ← (byte) nest2::j#2 [ nest2::j#2 nest2::i#2 ] // coptr1=zpby1
lda 7
lda 3
sta 1024
// [20] (byte) nest2::j#1 ← -- (byte) nest2::j#2 [ nest2::j#1 nest2::i#2 ] // zpby1=_dec_zpby1
dec 7
dec 3
// [21] if((byte) nest2::j#1>(byte) 0) goto nest2::@2 [ nest2::j#1 nest2::i#2 ] // zpby1_gt_0_then_la1
lda 7
lda 3
bne nest2__B2_from_B2
nest2__B3:
// [22] (byte) nest2::i#1 ← -- (byte) nest2::i#2 [ nest2::i#1 ] // zpby1=_dec_zpby1
dec 6
dec 2
// [23] if((byte) nest2::i#1>(byte) 0) goto nest2::@1 [ nest2::i#1 ] // zpby1_gt_0_then_la1
lda 6
lda 2
bne nest2__B1_from_B3
nest2__Breturn:
rts
@ -2161,11 +2167,11 @@ FINAL SYMBOL TABLE
(label) nest1::@5
(label) nest1::@return
(byte) nest1::i
(byte) nest1::i#1 zp byte:4
(byte) nest1::i#2 zp byte:4
(byte) nest1::i#1 zp byte:2
(byte) nest1::i#2 zp byte:2
(byte) nest1::j
(byte) nest1::j#1 zp byte:5
(byte) nest1::j#2 zp byte:5
(byte) nest1::j#1 zp byte:3
(byte) nest1::j#2 zp byte:3
(void()) nest2()
(label) nest2::@1
@ -2173,13 +2179,16 @@ FINAL SYMBOL TABLE
(label) nest2::@3
(label) nest2::@return
(byte) nest2::i
(byte) nest2::i#1 zp byte:6
(byte) nest2::i#2 zp byte:6
(byte) nest2::i#1 zp byte:2
(byte) nest2::i#2 zp byte:2
(byte) nest2::j
(byte) nest2::j#1 zp byte:7
(byte) nest2::j#2 zp byte:7
(byte) nest2::j#1 zp byte:3
(byte) nest2::j#2 zp byte:3
zp byte:2 [ main::i#2 main::i#1 nest1::i#2 nest1::i#1 nest2::i#2 nest2::i#1 ]
zp byte:3 [ main::j#2 main::j#1 nest1::j#2 nest1::j#1 nest2::j#2 nest2::j#1 ]
FINAL CODE
BBEGIN:
jsr main
@ -2218,29 +2227,29 @@ nest1:
nest1__B1_from_nest1:
// (byte) nest1::i#2 = (byte) 100 // zpby1=coby1
lda #100
sta 4
sta 2
nest1__B1_from_B3:
// (byte) nest1::i#2 = (byte) nest1::i#1 // register copy
nest1__B1:
nest1__B2_from_B1:
// (byte) nest1::j#2 = (byte) 100 // zpby1=coby1
lda #100
sta 5
sta 3
nest1__B2_from_B5:
// (byte) nest1::j#2 = (byte) nest1::j#1 // register copy
nest1__B2:
jsr nest2
nest1__B5:
// [12] (byte) nest1::j#1 ← -- (byte) nest1::j#2 [ nest1::j#1 nest1::i#2 ] // zpby1=_dec_zpby1
dec 5
dec 3
// [13] if((byte) nest1::j#1>(byte) 0) goto nest1::@2 [ nest1::j#1 nest1::i#2 ] // zpby1_gt_0_then_la1
lda 5
lda 3
bne nest1__B2_from_B5
nest1__B3:
// [14] (byte) nest1::i#1 ← -- (byte) nest1::i#2 [ nest1::i#1 ] // zpby1=_dec_zpby1
dec 4
dec 2
// [15] if((byte) nest1::i#1>(byte) 0) goto nest1::@1 [ nest1::i#1 ] // zpby1_gt_0_then_la1
lda 4
lda 2
bne nest1__B1_from_B3
nest1__Breturn:
rts
@ -2248,30 +2257,30 @@ nest2:
nest2__B1_from_nest2:
// (byte) nest2::i#2 = (byte) 100 // zpby1=coby1
lda #100
sta 6
sta 2
nest2__B1_from_B3:
// (byte) nest2::i#2 = (byte) nest2::i#1 // register copy
nest2__B1:
nest2__B2_from_B1:
// (byte) nest2::j#2 = (byte) 100 // zpby1=coby1
lda #100
sta 7
sta 3
nest2__B2_from_B2:
// (byte) nest2::j#2 = (byte) nest2::j#1 // register copy
nest2__B2:
// [19] *((word) 1024) ← (byte) nest2::j#2 [ nest2::j#2 nest2::i#2 ] // coptr1=zpby1
lda 7
lda 3
sta 1024
// [20] (byte) nest2::j#1 ← -- (byte) nest2::j#2 [ nest2::j#1 nest2::i#2 ] // zpby1=_dec_zpby1
dec 7
dec 3
// [21] if((byte) nest2::j#1>(byte) 0) goto nest2::@2 [ nest2::j#1 nest2::i#2 ] // zpby1_gt_0_then_la1
lda 7
lda 3
bne nest2__B2_from_B2
nest2__B3:
// [22] (byte) nest2::i#1 ← -- (byte) nest2::i#2 [ nest2::i#1 ] // zpby1=_dec_zpby1
dec 6
dec 2
// [23] if((byte) nest2::i#1>(byte) 0) goto nest2::@1 [ nest2::i#1 ] // zpby1_gt_0_then_la1
lda 6
lda 2
bne nest2__B1_from_B3
nest2__Breturn:
rts

View File

@ -21,11 +21,11 @@
(label) nest1::@5
(label) nest1::@return
(byte) nest1::i
(byte) nest1::i#1 zp byte:4
(byte) nest1::i#2 zp byte:4
(byte) nest1::i#1 zp byte:2
(byte) nest1::i#2 zp byte:2
(byte) nest1::j
(byte) nest1::j#1 zp byte:5
(byte) nest1::j#2 zp byte:5
(byte) nest1::j#1 zp byte:3
(byte) nest1::j#2 zp byte:3
(void()) nest2()
(label) nest2::@1
@ -33,9 +33,12 @@
(label) nest2::@3
(label) nest2::@return
(byte) nest2::i
(byte) nest2::i#1 zp byte:6
(byte) nest2::i#2 zp byte:6
(byte) nest2::i#1 zp byte:2
(byte) nest2::i#2 zp byte:2
(byte) nest2::j
(byte) nest2::j#1 zp byte:7
(byte) nest2::j#2 zp byte:7
(byte) nest2::j#1 zp byte:3
(byte) nest2::j#2 zp byte:3
zp byte:2 [ main::i#2 main::i#1 nest1::i#2 nest1::i#1 nest2::i#2 nest2::i#1 ]
zp byte:3 [ main::j#2 main::j#1 nest1::j#2 nest1::j#1 nest2::j#2 nest2::j#1 ]

View File

@ -393,8 +393,10 @@ Copy Coalesced equivalence classes
Complete equivalence classes
[ i#2 i#1 ]
[ s#3 s#1 s#2 ]
Allocated zp byte:2 to [ i#2 i#1 ]
Allocated zp byte:3 to [ s#3 s#1 s#2 ]
Allocated zp byte:2 to zp byte:2 [ i#2 i#1 ]
Allocated zp byte:3 to zp byte:3 [ s#3 s#1 s#2 ]
Re-allocated ZP register from zp byte:2 to zp byte:2
Re-allocated ZP register from zp byte:3 to zp byte:3
INITIAL ASM
BBEGIN:
B1_from_BBEGIN:
@ -532,6 +534,9 @@ FINAL SYMBOL TABLE
(byte) s#2 zp byte:3
(byte) s#3 zp byte:3
zp byte:2 [ i#2 i#1 ]
zp byte:3 [ s#3 s#1 s#2 ]
FINAL CODE
BBEGIN:
B1_from_BBEGIN:

View File

@ -289,8 +289,10 @@ Added variable $1 to zero page equivalence class [ $0 $1 ]
Complete equivalence classes
[ i#2 i#1 ]
[ $0 $1 ]
Allocated zp byte:2 to [ i#2 i#1 ]
Allocated zp byte:3 to [ $0 $1 ]
Allocated zp byte:2 to zp byte:2 [ i#2 i#1 ]
Allocated zp byte:3 to zp byte:3 [ $0 $1 ]
Re-allocated ZP register from zp byte:2 to zp byte:2
Re-allocated ZP register from zp byte:3 to zp byte:3
INITIAL ASM
BBEGIN:
B1_from_BBEGIN:
@ -404,6 +406,9 @@ FINAL SYMBOL TABLE
(byte) i#2 zp byte:2
(byte[16]) p
zp byte:2 [ i#2 i#1 ]
zp byte:3 [ $0 $1 ]
FINAL CODE
BBEGIN:
B1_from_BBEGIN:

View File

@ -324,8 +324,10 @@ Added variable s1#0 to zero page equivalence class [ sum::a#2 s1#0 ]
Complete equivalence classes
[ sum::a#2 s1#0 ]
[ sum::b#2 ]
Allocated zp byte:2 to [ sum::a#2 s1#0 ]
Allocated zp byte:3 to [ sum::b#2 ]
Allocated zp byte:2 to zp byte:2 [ sum::a#2 s1#0 ]
Allocated zp byte:3 to zp byte:3 [ sum::b#2 ]
Re-allocated ZP register from zp byte:2 to zp byte:2
Re-allocated ZP register from zp byte:3 to zp byte:3
INITIAL ASM
BBEGIN:
sum_from_BBEGIN:
@ -407,6 +409,9 @@ FINAL SYMBOL TABLE
(byte) sum::return
zp byte:2 [ sum::a#2 s1#0 ]
zp byte:3 [ sum::b#2 ]
FINAL CODE
BBEGIN:
sum_from_BBEGIN: