1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-02-22 13:29:18 +00:00

Moved register allocation into symbol table Variable

This commit is contained in:
jespergravgaard 2017-08-20 21:41:17 +02:00
parent 1982d01297
commit 5a91902c21
17 changed files with 126 additions and 175 deletions

View File

@ -59,8 +59,10 @@ public class AsmFragment {
throw new AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment); throw new AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
} }
VariableRef assignmentRValue2 = (VariableRef) assignment.getrValue2(); VariableRef assignmentRValue2 = (VariableRef) assignment.getrValue2();
RegisterAllocation.Register rVal2Register = program.getAllocation().getRegister(assignmentRValue2); Variable assignmentRValue2Var = program.getScope().getVariable(assignmentRValue2);
if (!rVal2Register.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) { Registers.Register rVal2Register = assignmentRValue2Var.getAllocation();
if (!rVal2Register.getType().equals(Registers.RegisterType.REG_ALU_BYTE)) {
throw new AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment); throw new AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
} }
StringBuilder signature = new StringBuilder(); StringBuilder signature = new StringBuilder();
@ -218,7 +220,7 @@ public class AsmFragment {
value = program.getScope().getVariable((VariableRef) value); value = program.getScope().getVariable((VariableRef) value);
} }
if (value instanceof Variable) { if (value instanceof Variable) {
value = program.getAllocation().getRegister(((Variable) value).getRef()); value = ((Variable) value).getAllocation();
} else if (value instanceof PointerDereferenceSimple) { } else if (value instanceof PointerDereferenceSimple) {
PointerDereferenceSimple deref = (PointerDereferenceSimple) value; PointerDereferenceSimple deref = (PointerDereferenceSimple) value;
return "_star_" + bind(deref.getPointer()); return "_star_" + bind(deref.getPointer());
@ -233,37 +235,37 @@ public class AsmFragment {
return name; return name;
} }
} }
if (value instanceof RegisterAllocation.Register) { if (value instanceof Registers.Register) {
RegisterAllocation.Register register = (RegisterAllocation.Register) value; Registers.Register register = (Registers.Register) value;
if (RegisterAllocation.RegisterType.ZP_BYTE.equals(register.getType())) { if (Registers.RegisterType.ZP_BYTE.equals(register.getType())) {
String name = "zpby" + nextZpByteIdx++; String name = "zpby" + nextZpByteIdx++;
bindings.put(name, value); bindings.put(name, value);
return name; return name;
} else if (RegisterAllocation.RegisterType.ZP_WORD.equals(register.getType())) { } else if (Registers.RegisterType.ZP_WORD.equals(register.getType())) {
String name = "zpwo" + nextZpWordIdx++; String name = "zpwo" + nextZpWordIdx++;
bindings.put(name, value); bindings.put(name, value);
return name; return name;
} else if (RegisterAllocation.RegisterType.ZP_BOOL.equals(register.getType())) { } else if (Registers.RegisterType.ZP_BOOL.equals(register.getType())) {
String name = "zpbo" + nextZpBoolIdx++; String name = "zpbo" + nextZpBoolIdx++;
bindings.put(name, value); bindings.put(name, value);
return name; return name;
} else if (RegisterAllocation.RegisterType.REG_X_BYTE.equals(register.getType())) { } else if (Registers.RegisterType.REG_X_BYTE.equals(register.getType())) {
String name = "xby"; String name = "xby";
bindings.put(name, value); bindings.put(name, value);
return name; return name;
} else if (RegisterAllocation.RegisterType.REG_Y_BYTE.equals(register.getType())) { } else if (Registers.RegisterType.REG_Y_BYTE.equals(register.getType())) {
String name = "yby"; String name = "yby";
bindings.put(name, value); bindings.put(name, value);
return name; return name;
} else if (RegisterAllocation.RegisterType.REG_A_BYTE.equals(register.getType())) { } else if (Registers.RegisterType.REG_A_BYTE.equals(register.getType())) {
String name = "aby"; String name = "aby";
bindings.put(name, value); bindings.put(name, value);
return name; return name;
} else if (RegisterAllocation.RegisterType.ZP_PTR_BYTE.equals(register.getType())) { } else if (Registers.RegisterType.ZP_PTR_BYTE.equals(register.getType())) {
String name = "zpptrby" + nextZpPtrIdx++; String name = "zpptrby" + nextZpPtrIdx++;
bindings.put(name, value); bindings.put(name, value);
return name; return name;
} else if (RegisterAllocation.RegisterType.REG_ALU_BYTE.equals(register.getType())) { } else if (Registers.RegisterType.REG_ALU_BYTE.equals(register.getType())) {
throw new AluNotApplicableException(); throw new AluNotApplicableException();
} }
} else if (value instanceof ConstantInteger) { } else if (value instanceof ConstantInteger) {
@ -297,16 +299,16 @@ public class AsmFragment {
throw new RuntimeException("Binding '" + name + "' not found in fragment " + signature + ".asm"); throw new RuntimeException("Binding '" + name + "' not found in fragment " + signature + ".asm");
} }
String bound; String bound;
if (boundValue instanceof RegisterAllocation.Register) { if (boundValue instanceof Registers.Register) {
RegisterAllocation.Register register = (RegisterAllocation.Register) boundValue; Registers.Register register = (Registers.Register) boundValue;
if (register instanceof RegisterAllocation.RegisterZpByte) { if (register instanceof Registers.RegisterZpByte) {
bound = String.format("$%x", ((RegisterAllocation.RegisterZpByte) register).getZp()); bound = String.format("$%x", ((Registers.RegisterZpByte) register).getZp());
} else if (register instanceof RegisterAllocation.RegisterZpWord) { } else if (register instanceof Registers.RegisterZpWord) {
bound = String.format("$%x", ((RegisterAllocation.RegisterZpWord) register).getZp()); bound = String.format("$%x", ((Registers.RegisterZpWord) register).getZp());
} else if (register instanceof RegisterAllocation.RegisterZpBool) { } else if (register instanceof Registers.RegisterZpBool) {
bound = String.format("$%x", ((RegisterAllocation.RegisterZpBool) register).getZp()); bound = String.format("$%x", ((Registers.RegisterZpBool) register).getZp());
} else if (register instanceof RegisterAllocation.RegisterZpPointerByte) { } else if (register instanceof Registers.RegisterZpPointerByte) {
bound = String.format("$%x", ((RegisterAllocation.RegisterZpPointerByte) register).getZp()); bound = String.format("$%x", ((Registers.RegisterZpPointerByte) register).getZp());
} else { } else {
throw new RuntimeException("Register Type not implemented " + register); throw new RuntimeException("Register Type not implemented " + register);
} }

View File

@ -18,7 +18,7 @@ public class LiveRangeEquivalenceClass {
private LiveRange liveRange; private LiveRange liveRange;
/** A register allocated to hold all variables of the equivalence class. (null if no register is currently allocated) */ /** A register allocated to hold all variables of the equivalence class. (null if no register is currently allocated) */
private RegisterAllocation.Register register; private Registers.Register register;
public LiveRangeEquivalenceClass(Program program) { public LiveRangeEquivalenceClass(Program program) {
this.program = program; this.program = program;
@ -27,11 +27,11 @@ public class LiveRangeEquivalenceClass {
this.register = null; this.register = null;
} }
public RegisterAllocation.Register getRegister() { public Registers.Register getRegister() {
return register; return register;
} }
public void setRegister(RegisterAllocation.Register register) { public void setRegister(Registers.Register register) {
this.register = register; this.register = register;
} }

View File

@ -61,15 +61,17 @@ public class LiveRangeEquivalenceClassSet {
equivalenceClasses.remove(equivalenceClass); equivalenceClasses.remove(equivalenceClass);
} }
public RegisterAllocation createRegisterAllocation() { /**
RegisterAllocation allocation = new RegisterAllocation(); * Store the register allocation of the live range equivalence classes into the variables in the symbol table (program scope).
*/
public void storeRegisterAllocation() {
for (LiveRangeEquivalenceClass equivalenceClass : getEquivalenceClasses()) { for (LiveRangeEquivalenceClass equivalenceClass : getEquivalenceClasses()) {
RegisterAllocation.Register register = equivalenceClass.getRegister(); Registers.Register register = equivalenceClass.getRegister();
for (VariableRef variable : equivalenceClass.getVariables()) { for (VariableRef variable : equivalenceClass.getVariables()) {
allocation.setRegister(variable, register); Variable var = program.getScope().getVariable(variable);
var.setAllocation(register);
} }
} }
return allocation;
} }

View File

@ -28,8 +28,6 @@ public class Program {
/** Information about loops. */ /** Information about loops. */
private NaturalLoopSet loopSet; private NaturalLoopSet loopSet;
/** The register allocation for the variables used during ASM code generation. */
private RegisterAllocation allocation;
/** The live ranges of all variables. */ /** The live ranges of all variables. */
private LiveRangeVariables liveRangeVariables; private LiveRangeVariables liveRangeVariables;
/** Live range equivalence classes containing variables that do not have overlapping live ranges. */ /** Live range equivalence classes containing variables that do not have overlapping live ranges. */
@ -80,7 +78,6 @@ public class Program {
return procedureModifiedVars; return procedureModifiedVars;
} }
public AsmProgram getAsm() { public AsmProgram getAsm() {
return asm; return asm;
} }
@ -113,14 +110,6 @@ public class Program {
return loopSet; return loopSet;
} }
public void setAllocation(RegisterAllocation allocation) {
this.allocation = allocation;
}
public RegisterAllocation getAllocation() {
return allocation;
}
public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) { public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) {
this.liveRangeVariables = liveRangeVariables; this.liveRangeVariables = liveRangeVariables;
} }

View File

@ -6,31 +6,32 @@ import java.util.Map;
/** A combination of register/ZP assignments for a set of equivalence classes */ /** A combination of register/ZP assignments for a set of equivalence classes */
public class RegisterCombination { public class RegisterCombination {
/** /** The registers allocated to each equivalence class. */
* The registers allocated to each equivalence class. private Map<LiveRangeEquivalenceClass, Registers.Register> allocation;
*/
private Map<LiveRangeEquivalenceClass, RegisterAllocation.Register> allocation;
public RegisterCombination() { public RegisterCombination() {
this.allocation = new LinkedHashMap<>(); this.allocation = new LinkedHashMap<>();
} }
void setRegister(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) { void setRegister(LiveRangeEquivalenceClass equivalenceClass, Registers.Register register) {
allocation.put(equivalenceClass, register); allocation.put(equivalenceClass, register);
} }
public RegisterAllocation.Register getRegister(LiveRangeEquivalenceClass equivalenceClass) { public Registers.Register getRegister(LiveRangeEquivalenceClass equivalenceClass) {
return allocation.get(equivalenceClass); return allocation.get(equivalenceClass);
} }
/** /**
* Allocate the registers of the combination into the programs register allocation * Allocate the registers of the combination into the programs register allocation
*/ */
public void allocate(RegisterAllocation registerAllocation) { public void allocate(ProgramScope scope) {
for (LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) { for (LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) {
RegisterAllocation.Register register = allocation.get(equivalenceClass); Registers.Register register = allocation.get(equivalenceClass);
for (VariableRef variable : equivalenceClass.getVariables()) { for (VariableRef variable : equivalenceClass.getVariables()) {
registerAllocation.setRegister(variable, register); Variable var = scope.getVariable(variable);
var.setAllocation(register);
} }
} }
} }
@ -42,7 +43,7 @@ public class RegisterCombination {
for (LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) { for (LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) {
VariableRef variable = equivalenceClass.getVariables().get(0); VariableRef variable = equivalenceClass.getVariables().get(0);
LiveRangeEquivalenceClass globalEquivalenceClass = equivalenceClassSet.getEquivalenceClass(variable); LiveRangeEquivalenceClass globalEquivalenceClass = equivalenceClassSet.getEquivalenceClass(variable);
RegisterAllocation.Register register = allocation.get(equivalenceClass); Registers.Register register = allocation.get(equivalenceClass);
globalEquivalenceClass.setRegister(register); globalEquivalenceClass.setRegister(register);
} }
} }
@ -51,7 +52,7 @@ public class RegisterCombination {
public String toString() { public String toString() {
StringBuilder out = new StringBuilder(); StringBuilder out = new StringBuilder();
for (LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) { for (LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) {
RegisterAllocation.Register register = allocation.get(equivalenceClass); Registers.Register register = allocation.get(equivalenceClass);
out.append(register.toString()).append(" ").append(equivalenceClass.toString(false)).append(" "); out.append(register.toString()).append(" ").append(equivalenceClass.toString(false)).append(" ");
} }
return out.toString(); return out.toString();

View File

@ -31,7 +31,7 @@ public class RegisterCombinationIterator implements Iterator<RegisterCombination
public int getNumIterations() { public int getNumIterations() {
int numIterations = 1; int numIterations = 1;
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) { for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
List<RegisterAllocation.Register> registers = registerPotentials.getPotentialRegisters(equivalenceClass); List<Registers.Register> registers = registerPotentials.getPotentialRegisters(equivalenceClass);
numIterations = numIterations * registers.size(); numIterations = numIterations * registers.size();
} }
return numIterations; return numIterations;
@ -42,9 +42,9 @@ public class RegisterCombinationIterator implements Iterator<RegisterCombination
RegisterCombination combination = new RegisterCombination(); RegisterCombination combination = new RegisterCombination();
int combinationIdRest = nextIterationId; int combinationIdRest = nextIterationId;
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) { for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
List<RegisterAllocation.Register> potentials = registerPotentials.getPotentialRegisters(equivalenceClass); List<Registers.Register> potentials = registerPotentials.getPotentialRegisters(equivalenceClass);
int registerIdx = (combinationIdRest % potentials.size()); int registerIdx = (combinationIdRest % potentials.size());
RegisterAllocation.Register register = potentials.get(registerIdx); Registers.Register register = potentials.get(registerIdx);
combination.setRegister(equivalenceClass, register); combination.setRegister(equivalenceClass, register);
combinationIdRest = (int) Math.floor(combinationIdRest / potentials.size()); combinationIdRest = (int) Math.floor(combinationIdRest / potentials.size());
} }

View File

@ -7,22 +7,22 @@ import java.util.*;
*/ */
public class RegisterPotentials { public class RegisterPotentials {
private Map<LiveRangeEquivalenceClass, List<RegisterAllocation.Register>> potentials; private Map<LiveRangeEquivalenceClass, List<Registers.Register>> potentials;
public RegisterPotentials() { public RegisterPotentials() {
this.potentials = new LinkedHashMap<>(); this.potentials = new LinkedHashMap<>();
} }
public List<RegisterAllocation.Register> getPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass) { public List<Registers.Register> getPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass) {
return potentials.get(equivalenceClass); return potentials.get(equivalenceClass);
} }
public void setPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass, List<RegisterAllocation.Register> registers) { public void setPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass, List<Registers.Register> registers) {
potentials.put(equivalenceClass, new ArrayList<>(registers)); potentials.put(equivalenceClass, new ArrayList<>(registers));
} }
public void removePotentialRegister(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) { public void removePotentialRegister(LiveRangeEquivalenceClass equivalenceClass, Registers.Register register) {
List<RegisterAllocation.Register> registers = potentials.get(equivalenceClass); List<Registers.Register> registers = potentials.get(equivalenceClass);
registers.remove(register); registers.remove(register);
} }
@ -37,8 +37,8 @@ public class RegisterPotentials {
out.append("Potential registers "); out.append("Potential registers ");
out.append(liveRangeEquivalenceClass.toString()); out.append(liveRangeEquivalenceClass.toString());
out.append(" : "); out.append(" : ");
List<RegisterAllocation.Register> registers = potentials.get(liveRangeEquivalenceClass); List<Registers.Register> registers = potentials.get(liveRangeEquivalenceClass);
for (RegisterAllocation.Register register : registers) { for (Registers.Register register : registers) {
out.append(register.toString()); out.append(register.toString());
out.append(" , "); out.append(" , ");
} }
@ -47,8 +47,8 @@ public class RegisterPotentials {
return out.toString(); return out.toString();
} }
public void addPotentialRegister(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) { public void addPotentialRegister(LiveRangeEquivalenceClass equivalenceClass, Registers.Register register) {
List<RegisterAllocation.Register> registers = potentials.get(equivalenceClass); List<Registers.Register> registers = potentials.get(equivalenceClass);
if (!registers.contains(register)) { if (!registers.contains(register)) {
registers.add(register); registers.add(register);
} }

View File

@ -1,33 +1,28 @@
package dk.camelot64.kickc.icl; package dk.camelot64.kickc.icl;
/** The different registers available for a program */
public class Registers {
import java.util.LinkedHashMap;
import java.util.Map;
/** Register Allocation for Variable Symbols */ public static Register getRegisterX() {
public class RegisterAllocation { return new RegisterXByte();
private Map<VariableRef, Register> allocation;
public RegisterAllocation() {
this.allocation = new LinkedHashMap<>();
} }
/** public static Register getRegisterY() {
* Get the register allocated for a specific variable return new RegisterYByte();
*
* @param variable The variable
* @return The allocated register.
*/
public Register getRegister(VariableRef ref) {
return allocation.get(ref);
} }
public static Register getRegisterA() {
return new RegisterAByte();
}
public void setRegister(VariableRef variable, Register register) { public static Register getRegisterALU() {
if(variable!=null) { return new RegisterALUByte();
allocation.put(variable, register); }
}
/** The register type. */
public enum RegisterType {
ZP_BYTE, ZP_BOOL, REG_A_BYTE, REG_ALU_BYTE, REG_Y_BYTE, REG_X_BYTE, ZP_PTR_BYTE, ZP_WORD
} }
/** A register used for storing a single variable. */ /** A register used for storing a single variable. */
@ -39,11 +34,6 @@ public class RegisterAllocation {
} }
/** The register type. */
public enum RegisterType {
ZP_BYTE, ZP_BOOL, REG_A_BYTE, REG_ALU_BYTE, REG_Y_BYTE, REG_X_BYTE, ZP_PTR_BYTE, ZP_WORD
}
/** A zero page address used as a register for a single byte variable. */ /** A zero page address used as a register for a single byte variable. */
public static class RegisterZpByte implements Register { public static class RegisterZpByte implements Register {
@ -144,7 +134,6 @@ public class RegisterAllocation {
} }
/** A zero page address used as a register for a boolean variable. */ /** A zero page address used as a register for a boolean variable. */
public static class RegisterZpBool implements Register { public static class RegisterZpBool implements Register {
private int zp; private int zp;
@ -239,7 +228,6 @@ public class RegisterAllocation {
} }
/** The X register. */ /** The X register. */
public static class RegisterXByte implements Register { public static class RegisterXByte implements Register {
@Override @Override
@ -363,31 +351,4 @@ public class RegisterAllocation {
} }
} }
public static Register getRegisterX() {
return new RegisterXByte();
}
public static Register getRegisterY() {
return new RegisterYByte();
}
public static Register getRegisterA() {
return new RegisterAByte();
}
public static Register getRegisterALU() {
return new RegisterALUByte();
}
@Override
public String toString() {
StringBuffer out = new StringBuffer();
for (VariableRef var: allocation.keySet()) {
Register register = getRegister(var);
out.append(var.toString()+" : "+register.toString()+"\n");
}
return out.toString();
}
} }

View File

@ -256,8 +256,6 @@ public abstract class Scope implements Symbol {
@JsonIgnore @JsonIgnore
public String getSymbolTableContents(Program program, Class symbolClass) { public String getSymbolTableContents(Program program, Class symbolClass) {
ProgramScope scope = program.getScope();
RegisterAllocation allocation = program.getAllocation();
VariableRegisterWeights registerWeights = program.getVariableRegisterWeights(); VariableRegisterWeights registerWeights = program.getVariableRegisterWeights();
StringBuilder res = new StringBuilder(); StringBuilder res = new StringBuilder();
Set<String> names = symbols.keySet(); Set<String> names = symbols.keySet();
@ -270,8 +268,8 @@ public abstract class Scope implements Symbol {
} else { } else {
if (symbolClass == null || symbolClass.isInstance(symbol)) { if (symbolClass == null || symbolClass.isInstance(symbol)) {
res.append(symbol.toString(program)); res.append(symbol.toString(program));
if (symbol instanceof Variable && allocation != null) { if (symbol instanceof Variable) {
RegisterAllocation.Register register = allocation.getRegister(((Variable) symbol).getRef()); Registers.Register register = ((Variable) symbol).getAllocation();
if (register != null) { if (register != null) {
res.append(" " + register); res.append(" " + register);
} }

View File

@ -19,7 +19,7 @@ public abstract class Variable implements Symbol {
private boolean inferredType; private boolean inferredType;
/** If the variable is assigned to an ASM register, this contains the register. If null the variable has no no allocation (yet). Constants are never assigned to registers. */ /** If the variable is assigned to an ASM register, this contains the register. If null the variable has no no allocation (yet). Constants are never assigned to registers. */
private RegisterAllocation.Register allocation; private Registers.Register allocation;
/** If the variable is a constant this is the constant value. If null the variable is not considered constant.*/ /** If the variable is a constant this is the constant value. If null the variable is not considered constant.*/
private Constant constant; private Constant constant;
@ -74,11 +74,11 @@ public abstract class Variable implements Symbol {
return name; return name;
} }
public RegisterAllocation.Register getAllocation() { public Registers.Register getAllocation() {
return allocation; return allocation;
} }
public void setAllocation(RegisterAllocation.Register allocation) { public void setAllocation(Registers.Register allocation) {
this.allocation = allocation; this.allocation = allocation;
} }

View File

@ -31,7 +31,6 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
* @return true if there is a clobber problem in the program * @return true if there is a clobber problem in the program
*/ */
public boolean hasClobberProblem(boolean verbose) { public boolean hasClobberProblem(boolean verbose) {
RegisterAllocation allocation = getProgram().getAllocation();
LiveRangeVariables liveRangeVariables = getProgram().getLiveRangeVariables(); LiveRangeVariables liveRangeVariables = getProgram().getLiveRangeVariables();
AsmProgram asm = getProgram().getAsm(); AsmProgram asm = getProgram().getAsm();
boolean clobberProblem = false; boolean clobberProblem = false;
@ -42,7 +41,7 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
Statement statement = getGraph().getStatementByIndex(statementIdx); Statement statement = getGraph().getStatementByIndex(statementIdx);
// Find the registered clobbered by the ASM asmSegment // Find the registered clobbered by the ASM asmSegment
AsmClobber asmSegmentClobber = asmSegment.getClobber(); AsmClobber asmSegmentClobber = asmSegment.getClobber();
Collection<RegisterAllocation.Register> clobberRegisters = getClobberRegisters(asmSegmentClobber); Collection<Registers.Register> clobberRegisters = getClobberRegisters(asmSegmentClobber);
// Find vars assigned to in the statement // Find vars assigned to in the statement
Collection<VariableRef> assignedVars = Pass4RegisterUpliftPotentialRegisterAnalysis.getAssignedVars(statement); Collection<VariableRef> assignedVars = Pass4RegisterUpliftPotentialRegisterAnalysis.getAssignedVars(statement);
// Two assigned vars cannot use same register // Two assigned vars cannot use same register
@ -53,8 +52,8 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
// Same variable - not relevant // Same variable - not relevant
continue; continue;
} }
RegisterAllocation.Register register1 = allocation.getRegister(assignedVar1); Registers.Register register1 = getProgram().getScope().getVariable(assignedVar1).getAllocation();
RegisterAllocation.Register register2 = allocation.getRegister(assignedVar2); Registers.Register register2 = getProgram().getScope().getVariable(assignedVar2).getAllocation();
if (register1.equals(register2)) { if (register1.equals(register2)) {
if (verbose) { if (verbose) {
getLog().append("Two assigned variables " + assignedVar1 + " and " + assignedVar2 + " clobbered by use of same register " + register1 + " in statement " + statement); getLog().append("Two assigned variables " + assignedVar1 + " and " + assignedVar2 + " clobbered by use of same register " + register1 + " in statement " + statement);
@ -70,7 +69,7 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
List<VariableRef> aliveVars = new ArrayList<>(liveRangeVariables.getAlive(statement)); List<VariableRef> aliveVars = new ArrayList<>(liveRangeVariables.getAlive(statement));
// Non-assigned alive variables must not be clobbered // Non-assigned alive variables must not be clobbered
for (VariableRef aliveVar : aliveVars) { for (VariableRef aliveVar : aliveVars) {
RegisterAllocation.Register aliveVarRegister = allocation.getRegister(aliveVar); Registers.Register aliveVarRegister = getProgram().getScope().getVariable(aliveVar).getAllocation();
if (aliveVarRegister.isZp()) { if (aliveVarRegister.isZp()) {
// No need to check a zp-register - here we are only interested in CPU registers // No need to check a zp-register - here we are only interested in CPU registers
continue; continue;
@ -99,16 +98,16 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
* @param clobber The clobber * @param clobber The clobber
* @return The clobbered CPU registers * @return The clobbered CPU registers
*/ */
public static Collection<RegisterAllocation.Register> getClobberRegisters(AsmClobber clobber) { public static Collection<Registers.Register> getClobberRegisters(AsmClobber clobber) {
List<RegisterAllocation.Register> clobberRegisters = new ArrayList<>(); List<Registers.Register> clobberRegisters = new ArrayList<>();
if (clobber.isClobberA()) { if (clobber.isClobberA()) {
clobberRegisters.add(RegisterAllocation.getRegisterA()); clobberRegisters.add(Registers.getRegisterA());
} }
if (clobber.isClobberX()) { if (clobber.isClobberX()) {
clobberRegisters.add(RegisterAllocation.getRegisterX()); clobberRegisters.add(Registers.getRegisterX());
} }
if (clobber.isClobberY()) { if (clobber.isClobberY()) {
clobberRegisters.add(RegisterAllocation.getRegisterY()); clobberRegisters.add(Registers.getRegisterY());
} }
return clobberRegisters; return clobberRegisters;
} }

View File

@ -106,8 +106,8 @@ public class Pass4CodeGeneration {
boolean isAlu = false; boolean isAlu = false;
if (lValue instanceof VariableRef) { if (lValue instanceof VariableRef) {
VariableRef lValueRef = (VariableRef) lValue; VariableRef lValueRef = (VariableRef) lValue;
RegisterAllocation.Register lValRegister = program.getAllocation().getRegister(lValueRef); Registers.Register lValRegister = program.getScope().getVariable(lValueRef).getAllocation();
if (lValRegister.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) { if (lValRegister.getType().equals(Registers.RegisterType.REG_ALU_BYTE)) {
asm.addComment(statement + " // ALU"); asm.addComment(statement + " // ALU");
StatementAssignment assignmentAlu = assignment; StatementAssignment assignmentAlu = assignment;
aluState.setAluAssignment(assignmentAlu); aluState.setAluAssignment(assignmentAlu);
@ -214,10 +214,10 @@ public class Pass4CodeGeneration {
} }
} }
private RegisterAllocation.Register getRegister(RValue rValue) { private Registers.Register getRegister(RValue rValue) {
if (rValue instanceof VariableRef) { if (rValue instanceof VariableRef) {
VariableRef rValueRef = (VariableRef) rValue; VariableRef rValueRef = (VariableRef) rValue;
return program.getAllocation().getRegister(rValueRef); return program.getScope().getVariable(rValueRef).getAllocation();
} else { } else {
return null; return null;
} }

View File

@ -35,7 +35,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
// Reset register allocation to original zero page allocation // Reset register allocation to original zero page allocation
new Pass4RegistersFinalize(getProgram()).allocate(false); new Pass4RegistersFinalize(getProgram()).allocate(false);
// Apply the uplift combination // Apply the uplift combination
combination.allocate(getProgram().getAllocation()); combination.allocate(getProgram().getScope());
// Generate ASM // Generate ASM
try { try {
new Pass4CodeGeneration(getProgram()).generate(); new Pass4CodeGeneration(getProgram()).generate();

View File

@ -87,7 +87,7 @@ public class Pass4RegisterUpliftPotentialAluAnalysis extends Pass2Base {
private void hasAluPotential(RegisterPotentials registerPotentials, VariableRef ref) { private void hasAluPotential(RegisterPotentials registerPotentials, VariableRef ref) {
LiveRangeEquivalenceClass potentialAluEquivalenceClass = liveRangeEquivalenceClassSet.getEquivalenceClass(ref); LiveRangeEquivalenceClass potentialAluEquivalenceClass = liveRangeEquivalenceClassSet.getEquivalenceClass(ref);
registerPotentials.addPotentialRegister(potentialAluEquivalenceClass, RegisterAllocation.getRegisterALU()); registerPotentials.addPotentialRegister(potentialAluEquivalenceClass, Registers.getRegisterALU());
getLog().append("Equivalence Class "+potentialAluEquivalenceClass+" has ALU potential."); getLog().append("Equivalence Class "+potentialAluEquivalenceClass+" has ALU potential.");
} }

View File

@ -36,14 +36,14 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
modified = true; modified = true;
registerPotentials = new RegisterPotentials(); registerPotentials = new RegisterPotentials();
for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) { for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
RegisterAllocation.Register defaultRegister = equivalenceClass.getRegister(); Registers.Register defaultRegister = equivalenceClass.getRegister();
RegisterAllocation.RegisterType registerType = defaultRegister.getType(); Registers.RegisterType registerType = defaultRegister.getType();
if (registerType.equals(RegisterAllocation.RegisterType.ZP_BYTE)) { if (registerType.equals(Registers.RegisterType.ZP_BYTE)) {
List<RegisterAllocation.Register> potentials = Arrays.asList( List<Registers.Register> potentials = Arrays.asList(
defaultRegister, defaultRegister,
RegisterAllocation.getRegisterA(), Registers.getRegisterA(),
RegisterAllocation.getRegisterX(), Registers.getRegisterX(),
RegisterAllocation.getRegisterY()); Registers.getRegisterY());
registerPotentials.setPotentialRegisters(equivalenceClass, potentials); registerPotentials.setPotentialRegisters(equivalenceClass, potentials);
} else { } else {
registerPotentials.setPotentialRegisters(equivalenceClass, Arrays.asList(defaultRegister)); registerPotentials.setPotentialRegisters(equivalenceClass, Arrays.asList(defaultRegister));
@ -74,7 +74,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
// For each combination generate the ASM and examine the clobber of all alive variables // For each combination generate the ASM and examine the clobber of all alive variables
// Find the registers clobbered by all combinations! // Find the registers clobbered by all combinations!
Set<RegisterAllocation.Register> alwaysClobbered = findAlwaysClobberedRegisters(block, statement, combinationIterator); Set<Registers.Register> alwaysClobbered = findAlwaysClobberedRegisters(block, statement, combinationIterator);
if (alwaysClobbered.isEmpty()) { if (alwaysClobbered.isEmpty()) {
// No registers are always clobbered - move on to the next statement // No registers are always clobbered - move on to the next statement
continue; continue;
@ -82,7 +82,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
msg.append("Statement ").append(statement.toString(getProgram())); msg.append("Statement ").append(statement.toString(getProgram()));
msg.append(" always clobbers "); msg.append(" always clobbers ");
for (RegisterAllocation.Register register : alwaysClobbered) { for (Registers.Register register : alwaysClobbered) {
msg.append(register).append(" "); msg.append(register).append(" ");
} }
getLog().append(msg.toString()); getLog().append(msg.toString());
@ -96,8 +96,8 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
// Assigned registers are allowed to be be clobbered // Assigned registers are allowed to be be clobbered
continue; continue;
} }
List<RegisterAllocation.Register> alivePotentialRegisters = registerPotentials.getPotentialRegisters(aliveClass); List<Registers.Register> alivePotentialRegisters = registerPotentials.getPotentialRegisters(aliveClass);
for (RegisterAllocation.Register clobberedRegister : alwaysClobbered) { for (Registers.Register clobberedRegister : alwaysClobbered) {
if (alivePotentialRegisters.contains(clobberedRegister)) { if (alivePotentialRegisters.contains(clobberedRegister)) {
registerPotentials.removePotentialRegister(aliveClass, clobberedRegister); registerPotentials.removePotentialRegister(aliveClass, clobberedRegister);
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
@ -125,13 +125,13 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
* @param combinations The regsiter combinations to test * @param combinations The regsiter combinations to test
* @return A set with registers that are clobbered by all different register assignments in the combination * @return A set with registers that are clobbered by all different register assignments in the combination
*/ */
private Set<RegisterAllocation.Register> findAlwaysClobberedRegisters(ControlFlowBlock block, Statement statement, RegisterCombinationIterator combinations) { private Set<Registers.Register> findAlwaysClobberedRegisters(ControlFlowBlock block, Statement statement, RegisterCombinationIterator combinations) {
// Initially assume all registers are always clobbered // Initially assume all registers are always clobbered
Set<RegisterAllocation.Register> alwaysClobbered = new LinkedHashSet<>(); Set<Registers.Register> alwaysClobbered = new LinkedHashSet<>();
alwaysClobbered.add(RegisterAllocation.getRegisterA()); alwaysClobbered.add(Registers.getRegisterA());
alwaysClobbered.add(RegisterAllocation.getRegisterX()); alwaysClobbered.add(Registers.getRegisterX());
alwaysClobbered.add(RegisterAllocation.getRegisterY()); alwaysClobbered.add(Registers.getRegisterY());
Set<String> unknownFragments = new LinkedHashSet<>(); Set<String> unknownFragments = new LinkedHashSet<>();
@ -140,7 +140,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
// Reset register allocation to original zero page allocation // Reset register allocation to original zero page allocation
new Pass4RegistersFinalize(getProgram()).allocate(false); new Pass4RegistersFinalize(getProgram()).allocate(false);
// Apply the combination // Apply the combination
combination.allocate(getProgram().getAllocation()); combination.allocate(getProgram().getScope());
// Generate ASM // Generate ASM
AsmProgram asm = new AsmProgram(); AsmProgram asm = new AsmProgram();
asm.startSegment(statement.getIndex(), statement.toString(getProgram())); asm.startSegment(statement.getIndex(), statement.toString(getProgram()));
@ -157,10 +157,10 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
continue; continue;
} }
AsmClobber clobber = asm.getClobber(); AsmClobber clobber = asm.getClobber();
Collection<RegisterAllocation.Register> clobberRegisters = Pass4AssertNoCpuClobber.getClobberRegisters(clobber); Collection<Registers.Register> clobberRegisters = Pass4AssertNoCpuClobber.getClobberRegisters(clobber);
Iterator<RegisterAllocation.Register> alwaysClobberIt = alwaysClobbered.iterator(); Iterator<Registers.Register> alwaysClobberIt = alwaysClobbered.iterator();
while (alwaysClobberIt.hasNext()) { while (alwaysClobberIt.hasNext()) {
RegisterAllocation.Register alwaysClobberRegister = alwaysClobberIt.next(); Registers.Register alwaysClobberRegister = alwaysClobberIt.next();
if (!clobberRegisters.contains(alwaysClobberRegister)) { if (!clobberRegisters.contains(alwaysClobberRegister)) {
alwaysClobberIt.remove(); alwaysClobberIt.remove();
} }

View File

@ -27,7 +27,7 @@ public class Pass4RegisterUpliftRemains extends Pass2Base {
Set<String> unknownFragments = new LinkedHashSet<>(); Set<String> unknownFragments = new LinkedHashSet<>();
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) { for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
if (equivalenceClass.getRegister().getType().equals(RegisterAllocation.RegisterType.ZP_BYTE)) { if (equivalenceClass.getRegister().getType().equals(Registers.RegisterType.ZP_BYTE)) {
int bestScore = Integer.MAX_VALUE; int bestScore = Integer.MAX_VALUE;
RegisterCombination bestCombination = null; RegisterCombination bestCombination = null;
RegisterCombinationIterator combinationIterator = new RegisterCombinationIterator(Arrays.asList(equivalenceClass), getProgram().getRegisterPotentials()); RegisterCombinationIterator combinationIterator = new RegisterCombinationIterator(Arrays.asList(equivalenceClass), getProgram().getRegisterPotentials());
@ -37,7 +37,7 @@ public class Pass4RegisterUpliftRemains extends Pass2Base {
// Reset register allocation to original zero page allocation // Reset register allocation to original zero page allocation
new Pass4RegistersFinalize(getProgram()).allocate(false); new Pass4RegistersFinalize(getProgram()).allocate(false);
// Apply the uplift combination // Apply the uplift combination
combination.allocate(getProgram().getAllocation()); combination.allocate(getProgram().getScope());
// Generate ASM // Generate ASM
try { try {
new Pass4CodeGeneration(getProgram()).generate(); new Pass4CodeGeneration(getProgram()).generate();

View File

@ -17,8 +17,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
if(reallocZp) { if(reallocZp) {
reallocateZp(liveRangeEquivalenceClassSet); reallocateZp(liveRangeEquivalenceClassSet);
} }
RegisterAllocation allocation = liveRangeEquivalenceClassSet.createRegisterAllocation(); liveRangeEquivalenceClassSet.storeRegisterAllocation();
getProgram().setAllocation(allocation);
} }
/** /**
@ -28,7 +27,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
*/ */
private void reallocateZp(LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet) { private void reallocateZp(LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet) {
for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) { for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
RegisterAllocation.Register register = equivalenceClass.getRegister(); Registers.Register register = equivalenceClass.getRegister();
if(register==null || register.isZp()) { if(register==null || register.isZp()) {
String before = register==null?null:register.toString(); String before = register==null?null:register.toString();
VariableRef variable = equivalenceClass.getVariables().get(0); VariableRef variable = equivalenceClass.getVariables().get(0);
@ -54,22 +53,22 @@ public class Pass4RegistersFinalize extends Pass2Base {
* 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 * @return The new zeropage register
*/ */
private RegisterAllocation.Register allocateNewRegisterZp(SymbolType varType) { private Registers.Register allocateNewRegisterZp(SymbolType varType) {
if (varType.equals(SymbolTypeBasic.BYTE)) { if (varType.equals(SymbolTypeBasic.BYTE)) {
return new RegisterAllocation.RegisterZpByte(currentZp++); return new Registers.RegisterZpByte(currentZp++);
} else if (varType.equals(SymbolTypeBasic.WORD)) { } else if (varType.equals(SymbolTypeBasic.WORD)) {
RegisterAllocation.RegisterZpWord registerZpWord = Registers.RegisterZpWord registerZpWord =
new RegisterAllocation.RegisterZpWord(currentZp); new Registers.RegisterZpWord(currentZp);
currentZp = currentZp + 2; currentZp = currentZp + 2;
return registerZpWord; return registerZpWord;
} else if (varType.equals(SymbolTypeBasic.BOOLEAN)) { } else if (varType.equals(SymbolTypeBasic.BOOLEAN)) {
return new RegisterAllocation.RegisterZpBool(currentZp++); return new Registers.RegisterZpBool(currentZp++);
} else if (varType.equals(SymbolTypeBasic.VOID)) { } else if (varType.equals(SymbolTypeBasic.VOID)) {
// No need to setRegister register for VOID value // No need to setRegister register for VOID value
return null; return null;
} else if (varType instanceof SymbolTypePointer) { } else if (varType instanceof SymbolTypePointer) {
RegisterAllocation.RegisterZpPointerByte registerZpPointerByte = Registers.RegisterZpPointerByte registerZpPointerByte =
new RegisterAllocation.RegisterZpPointerByte(currentZp); new Registers.RegisterZpPointerByte(currentZp);
currentZp = currentZp + 2; currentZp = currentZp + 2;
return registerZpPointerByte; return registerZpPointerByte;
} else { } else {