mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-21 07:29:14 +00:00
Moved register allocation into symbol table Variable
This commit is contained in:
parent
1982d01297
commit
5a91902c21
@ -59,8 +59,10 @@ public class AsmFragment {
|
||||
throw new AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
|
||||
}
|
||||
VariableRef assignmentRValue2 = (VariableRef) assignment.getrValue2();
|
||||
RegisterAllocation.Register rVal2Register = program.getAllocation().getRegister(assignmentRValue2);
|
||||
if (!rVal2Register.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) {
|
||||
Variable assignmentRValue2Var = program.getScope().getVariable(assignmentRValue2);
|
||||
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);
|
||||
}
|
||||
StringBuilder signature = new StringBuilder();
|
||||
@ -218,7 +220,7 @@ public class AsmFragment {
|
||||
value = program.getScope().getVariable((VariableRef) value);
|
||||
}
|
||||
if (value instanceof Variable) {
|
||||
value = program.getAllocation().getRegister(((Variable) value).getRef());
|
||||
value = ((Variable) value).getAllocation();
|
||||
} else if (value instanceof PointerDereferenceSimple) {
|
||||
PointerDereferenceSimple deref = (PointerDereferenceSimple) value;
|
||||
return "_star_" + bind(deref.getPointer());
|
||||
@ -233,37 +235,37 @@ public class AsmFragment {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
if (value instanceof RegisterAllocation.Register) {
|
||||
RegisterAllocation.Register register = (RegisterAllocation.Register) value;
|
||||
if (RegisterAllocation.RegisterType.ZP_BYTE.equals(register.getType())) {
|
||||
if (value instanceof Registers.Register) {
|
||||
Registers.Register register = (Registers.Register) value;
|
||||
if (Registers.RegisterType.ZP_BYTE.equals(register.getType())) {
|
||||
String name = "zpby" + nextZpByteIdx++;
|
||||
bindings.put(name, value);
|
||||
return name;
|
||||
} else if (RegisterAllocation.RegisterType.ZP_WORD.equals(register.getType())) {
|
||||
} else if (Registers.RegisterType.ZP_WORD.equals(register.getType())) {
|
||||
String name = "zpwo" + nextZpWordIdx++;
|
||||
bindings.put(name, value);
|
||||
return name;
|
||||
} else if (RegisterAllocation.RegisterType.ZP_BOOL.equals(register.getType())) {
|
||||
} else if (Registers.RegisterType.ZP_BOOL.equals(register.getType())) {
|
||||
String name = "zpbo" + nextZpBoolIdx++;
|
||||
bindings.put(name, value);
|
||||
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";
|
||||
bindings.put(name, value);
|
||||
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";
|
||||
bindings.put(name, value);
|
||||
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";
|
||||
bindings.put(name, value);
|
||||
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++;
|
||||
bindings.put(name, value);
|
||||
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();
|
||||
}
|
||||
} else if (value instanceof ConstantInteger) {
|
||||
@ -297,16 +299,16 @@ public class AsmFragment {
|
||||
throw new RuntimeException("Binding '" + name + "' not found in fragment " + signature + ".asm");
|
||||
}
|
||||
String bound;
|
||||
if (boundValue instanceof RegisterAllocation.Register) {
|
||||
RegisterAllocation.Register register = (RegisterAllocation.Register) boundValue;
|
||||
if (register instanceof RegisterAllocation.RegisterZpByte) {
|
||||
bound = String.format("$%x", ((RegisterAllocation.RegisterZpByte) register).getZp());
|
||||
} else if (register instanceof RegisterAllocation.RegisterZpWord) {
|
||||
bound = String.format("$%x", ((RegisterAllocation.RegisterZpWord) register).getZp());
|
||||
} else if (register instanceof RegisterAllocation.RegisterZpBool) {
|
||||
bound = String.format("$%x", ((RegisterAllocation.RegisterZpBool) register).getZp());
|
||||
} else if (register instanceof RegisterAllocation.RegisterZpPointerByte) {
|
||||
bound = String.format("$%x", ((RegisterAllocation.RegisterZpPointerByte) register).getZp());
|
||||
if (boundValue instanceof Registers.Register) {
|
||||
Registers.Register register = (Registers.Register) boundValue;
|
||||
if (register instanceof Registers.RegisterZpByte) {
|
||||
bound = String.format("$%x", ((Registers.RegisterZpByte) register).getZp());
|
||||
} else if (register instanceof Registers.RegisterZpWord) {
|
||||
bound = String.format("$%x", ((Registers.RegisterZpWord) register).getZp());
|
||||
} else if (register instanceof Registers.RegisterZpBool) {
|
||||
bound = String.format("$%x", ((Registers.RegisterZpBool) register).getZp());
|
||||
} else if (register instanceof Registers.RegisterZpPointerByte) {
|
||||
bound = String.format("$%x", ((Registers.RegisterZpPointerByte) register).getZp());
|
||||
} else {
|
||||
throw new RuntimeException("Register Type not implemented " + register);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ public class LiveRangeEquivalenceClass {
|
||||
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;
|
||||
private Registers.Register register;
|
||||
|
||||
public LiveRangeEquivalenceClass(Program program) {
|
||||
this.program = program;
|
||||
@ -27,11 +27,11 @@ public class LiveRangeEquivalenceClass {
|
||||
this.register = null;
|
||||
}
|
||||
|
||||
public RegisterAllocation.Register getRegister() {
|
||||
public Registers.Register getRegister() {
|
||||
return register;
|
||||
}
|
||||
|
||||
public void setRegister(RegisterAllocation.Register register) {
|
||||
public void setRegister(Registers.Register register) {
|
||||
this.register = register;
|
||||
}
|
||||
|
||||
|
@ -61,15 +61,17 @@ public class LiveRangeEquivalenceClassSet {
|
||||
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()) {
|
||||
RegisterAllocation.Register register = equivalenceClass.getRegister();
|
||||
Registers.Register register = equivalenceClass.getRegister();
|
||||
for (VariableRef variable : equivalenceClass.getVariables()) {
|
||||
allocation.setRegister(variable, register);
|
||||
Variable var = program.getScope().getVariable(variable);
|
||||
var.setAllocation(register);
|
||||
}
|
||||
}
|
||||
return allocation;
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,8 +28,6 @@ public class Program {
|
||||
/** Information about loops. */
|
||||
private NaturalLoopSet loopSet;
|
||||
|
||||
/** The register allocation for the variables used during ASM code generation. */
|
||||
private RegisterAllocation allocation;
|
||||
/** The live ranges of all variables. */
|
||||
private LiveRangeVariables liveRangeVariables;
|
||||
/** Live range equivalence classes containing variables that do not have overlapping live ranges. */
|
||||
@ -80,7 +78,6 @@ public class Program {
|
||||
return procedureModifiedVars;
|
||||
}
|
||||
|
||||
|
||||
public AsmProgram getAsm() {
|
||||
return asm;
|
||||
}
|
||||
@ -113,14 +110,6 @@ public class Program {
|
||||
return loopSet;
|
||||
}
|
||||
|
||||
public void setAllocation(RegisterAllocation allocation) {
|
||||
this.allocation = allocation;
|
||||
}
|
||||
|
||||
public RegisterAllocation getAllocation() {
|
||||
return allocation;
|
||||
}
|
||||
|
||||
public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) {
|
||||
this.liveRangeVariables = liveRangeVariables;
|
||||
}
|
||||
|
@ -6,31 +6,32 @@ import java.util.Map;
|
||||
/** A combination of register/ZP assignments for a set of equivalence classes */
|
||||
public class RegisterCombination {
|
||||
|
||||
/**
|
||||
* The registers allocated to each equivalence class.
|
||||
*/
|
||||
private Map<LiveRangeEquivalenceClass, RegisterAllocation.Register> allocation;
|
||||
/** The registers allocated to each equivalence class. */
|
||||
private Map<LiveRangeEquivalenceClass, Registers.Register> allocation;
|
||||
|
||||
|
||||
|
||||
public RegisterCombination() {
|
||||
this.allocation = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
void setRegister(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) {
|
||||
void setRegister(LiveRangeEquivalenceClass equivalenceClass, Registers.Register register) {
|
||||
allocation.put(equivalenceClass, register);
|
||||
}
|
||||
|
||||
public RegisterAllocation.Register getRegister(LiveRangeEquivalenceClass equivalenceClass) {
|
||||
public Registers.Register getRegister(LiveRangeEquivalenceClass equivalenceClass) {
|
||||
return allocation.get(equivalenceClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()) {
|
||||
RegisterAllocation.Register register = allocation.get(equivalenceClass);
|
||||
Registers.Register register = allocation.get(equivalenceClass);
|
||||
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()) {
|
||||
VariableRef variable = equivalenceClass.getVariables().get(0);
|
||||
LiveRangeEquivalenceClass globalEquivalenceClass = equivalenceClassSet.getEquivalenceClass(variable);
|
||||
RegisterAllocation.Register register = allocation.get(equivalenceClass);
|
||||
Registers.Register register = allocation.get(equivalenceClass);
|
||||
globalEquivalenceClass.setRegister(register);
|
||||
}
|
||||
}
|
||||
@ -51,7 +52,7 @@ public class RegisterCombination {
|
||||
public String toString() {
|
||||
StringBuilder out = new StringBuilder();
|
||||
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(" ");
|
||||
}
|
||||
return out.toString();
|
||||
|
@ -31,7 +31,7 @@ public class RegisterCombinationIterator implements Iterator<RegisterCombination
|
||||
public int getNumIterations() {
|
||||
int numIterations = 1;
|
||||
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
||||
List<RegisterAllocation.Register> registers = registerPotentials.getPotentialRegisters(equivalenceClass);
|
||||
List<Registers.Register> registers = registerPotentials.getPotentialRegisters(equivalenceClass);
|
||||
numIterations = numIterations * registers.size();
|
||||
}
|
||||
return numIterations;
|
||||
@ -42,9 +42,9 @@ public class RegisterCombinationIterator implements Iterator<RegisterCombination
|
||||
RegisterCombination combination = new RegisterCombination();
|
||||
int combinationIdRest = nextIterationId;
|
||||
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
||||
List<RegisterAllocation.Register> potentials = registerPotentials.getPotentialRegisters(equivalenceClass);
|
||||
List<Registers.Register> potentials = registerPotentials.getPotentialRegisters(equivalenceClass);
|
||||
int registerIdx = (combinationIdRest % potentials.size());
|
||||
RegisterAllocation.Register register = potentials.get(registerIdx);
|
||||
Registers.Register register = potentials.get(registerIdx);
|
||||
combination.setRegister(equivalenceClass, register);
|
||||
combinationIdRest = (int) Math.floor(combinationIdRest / potentials.size());
|
||||
}
|
||||
|
@ -7,22 +7,22 @@ import java.util.*;
|
||||
*/
|
||||
public class RegisterPotentials {
|
||||
|
||||
private Map<LiveRangeEquivalenceClass, List<RegisterAllocation.Register>> potentials;
|
||||
private Map<LiveRangeEquivalenceClass, List<Registers.Register>> potentials;
|
||||
|
||||
public RegisterPotentials() {
|
||||
this.potentials = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
public List<RegisterAllocation.Register> getPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass) {
|
||||
public List<Registers.Register> getPotentialRegisters(LiveRangeEquivalenceClass 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));
|
||||
}
|
||||
|
||||
public void removePotentialRegister(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) {
|
||||
List<RegisterAllocation.Register> registers = potentials.get(equivalenceClass);
|
||||
public void removePotentialRegister(LiveRangeEquivalenceClass equivalenceClass, Registers.Register register) {
|
||||
List<Registers.Register> registers = potentials.get(equivalenceClass);
|
||||
registers.remove(register);
|
||||
}
|
||||
|
||||
@ -37,8 +37,8 @@ public class RegisterPotentials {
|
||||
out.append("Potential registers ");
|
||||
out.append(liveRangeEquivalenceClass.toString());
|
||||
out.append(" : ");
|
||||
List<RegisterAllocation.Register> registers = potentials.get(liveRangeEquivalenceClass);
|
||||
for (RegisterAllocation.Register register : registers) {
|
||||
List<Registers.Register> registers = potentials.get(liveRangeEquivalenceClass);
|
||||
for (Registers.Register register : registers) {
|
||||
out.append(register.toString());
|
||||
out.append(" , ");
|
||||
}
|
||||
@ -47,8 +47,8 @@ public class RegisterPotentials {
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public void addPotentialRegister(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) {
|
||||
List<RegisterAllocation.Register> registers = potentials.get(equivalenceClass);
|
||||
public void addPotentialRegister(LiveRangeEquivalenceClass equivalenceClass, Registers.Register register) {
|
||||
List<Registers.Register> registers = potentials.get(equivalenceClass);
|
||||
if (!registers.contains(register)) {
|
||||
registers.add(register);
|
||||
}
|
||||
|
@ -1,33 +1,28 @@
|
||||
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 class RegisterAllocation {
|
||||
|
||||
private Map<VariableRef, Register> allocation;
|
||||
|
||||
public RegisterAllocation() {
|
||||
this.allocation = new LinkedHashMap<>();
|
||||
public static Register getRegisterX() {
|
||||
return new RegisterXByte();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the register allocated for a specific variable
|
||||
*
|
||||
* @param variable The variable
|
||||
* @return The allocated register.
|
||||
*/
|
||||
public Register getRegister(VariableRef ref) {
|
||||
return allocation.get(ref);
|
||||
public static Register getRegisterY() {
|
||||
return new RegisterYByte();
|
||||
}
|
||||
|
||||
public static Register getRegisterA() {
|
||||
return new RegisterAByte();
|
||||
}
|
||||
|
||||
public void setRegister(VariableRef variable, Register register) {
|
||||
if(variable!=null) {
|
||||
allocation.put(variable, register);
|
||||
}
|
||||
public static Register getRegisterALU() {
|
||||
return new RegisterALUByte();
|
||||
}
|
||||
|
||||
/** 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. */
|
||||
@ -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. */
|
||||
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. */
|
||||
public static class RegisterZpBool implements Register {
|
||||
private int zp;
|
||||
@ -239,7 +228,6 @@ public class RegisterAllocation {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** The X register. */
|
||||
public static class RegisterXByte implements Register {
|
||||
@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();
|
||||
}
|
||||
|
||||
}
|
@ -256,8 +256,6 @@ public abstract class Scope implements Symbol {
|
||||
|
||||
@JsonIgnore
|
||||
public String getSymbolTableContents(Program program, Class symbolClass) {
|
||||
ProgramScope scope = program.getScope();
|
||||
RegisterAllocation allocation = program.getAllocation();
|
||||
VariableRegisterWeights registerWeights = program.getVariableRegisterWeights();
|
||||
StringBuilder res = new StringBuilder();
|
||||
Set<String> names = symbols.keySet();
|
||||
@ -270,8 +268,8 @@ public abstract class Scope implements Symbol {
|
||||
} else {
|
||||
if (symbolClass == null || symbolClass.isInstance(symbol)) {
|
||||
res.append(symbol.toString(program));
|
||||
if (symbol instanceof Variable && allocation != null) {
|
||||
RegisterAllocation.Register register = allocation.getRegister(((Variable) symbol).getRef());
|
||||
if (symbol instanceof Variable) {
|
||||
Registers.Register register = ((Variable) symbol).getAllocation();
|
||||
if (register != null) {
|
||||
res.append(" " + register);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public abstract class Variable implements Symbol {
|
||||
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. */
|
||||
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.*/
|
||||
private Constant constant;
|
||||
@ -74,11 +74,11 @@ public abstract class Variable implements Symbol {
|
||||
return name;
|
||||
}
|
||||
|
||||
public RegisterAllocation.Register getAllocation() {
|
||||
public Registers.Register getAllocation() {
|
||||
return allocation;
|
||||
}
|
||||
|
||||
public void setAllocation(RegisterAllocation.Register allocation) {
|
||||
public void setAllocation(Registers.Register allocation) {
|
||||
this.allocation = allocation;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,6 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
|
||||
* @return true if there is a clobber problem in the program
|
||||
*/
|
||||
public boolean hasClobberProblem(boolean verbose) {
|
||||
RegisterAllocation allocation = getProgram().getAllocation();
|
||||
LiveRangeVariables liveRangeVariables = getProgram().getLiveRangeVariables();
|
||||
AsmProgram asm = getProgram().getAsm();
|
||||
boolean clobberProblem = false;
|
||||
@ -42,7 +41,7 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
|
||||
Statement statement = getGraph().getStatementByIndex(statementIdx);
|
||||
// Find the registered clobbered by the ASM asmSegment
|
||||
AsmClobber asmSegmentClobber = asmSegment.getClobber();
|
||||
Collection<RegisterAllocation.Register> clobberRegisters = getClobberRegisters(asmSegmentClobber);
|
||||
Collection<Registers.Register> clobberRegisters = getClobberRegisters(asmSegmentClobber);
|
||||
// Find vars assigned to in the statement
|
||||
Collection<VariableRef> assignedVars = Pass4RegisterUpliftPotentialRegisterAnalysis.getAssignedVars(statement);
|
||||
// Two assigned vars cannot use same register
|
||||
@ -53,8 +52,8 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
|
||||
// Same variable - not relevant
|
||||
continue;
|
||||
}
|
||||
RegisterAllocation.Register register1 = allocation.getRegister(assignedVar1);
|
||||
RegisterAllocation.Register register2 = allocation.getRegister(assignedVar2);
|
||||
Registers.Register register1 = getProgram().getScope().getVariable(assignedVar1).getAllocation();
|
||||
Registers.Register register2 = getProgram().getScope().getVariable(assignedVar2).getAllocation();
|
||||
if (register1.equals(register2)) {
|
||||
if (verbose) {
|
||||
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));
|
||||
// Non-assigned alive variables must not be clobbered
|
||||
for (VariableRef aliveVar : aliveVars) {
|
||||
RegisterAllocation.Register aliveVarRegister = allocation.getRegister(aliveVar);
|
||||
Registers.Register aliveVarRegister = getProgram().getScope().getVariable(aliveVar).getAllocation();
|
||||
if (aliveVarRegister.isZp()) {
|
||||
// No need to check a zp-register - here we are only interested in CPU registers
|
||||
continue;
|
||||
@ -99,16 +98,16 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
|
||||
* @param clobber The clobber
|
||||
* @return The clobbered CPU registers
|
||||
*/
|
||||
public static Collection<RegisterAllocation.Register> getClobberRegisters(AsmClobber clobber) {
|
||||
List<RegisterAllocation.Register> clobberRegisters = new ArrayList<>();
|
||||
public static Collection<Registers.Register> getClobberRegisters(AsmClobber clobber) {
|
||||
List<Registers.Register> clobberRegisters = new ArrayList<>();
|
||||
if (clobber.isClobberA()) {
|
||||
clobberRegisters.add(RegisterAllocation.getRegisterA());
|
||||
clobberRegisters.add(Registers.getRegisterA());
|
||||
}
|
||||
if (clobber.isClobberX()) {
|
||||
clobberRegisters.add(RegisterAllocation.getRegisterX());
|
||||
clobberRegisters.add(Registers.getRegisterX());
|
||||
}
|
||||
if (clobber.isClobberY()) {
|
||||
clobberRegisters.add(RegisterAllocation.getRegisterY());
|
||||
clobberRegisters.add(Registers.getRegisterY());
|
||||
}
|
||||
return clobberRegisters;
|
||||
}
|
||||
|
@ -106,8 +106,8 @@ public class Pass4CodeGeneration {
|
||||
boolean isAlu = false;
|
||||
if (lValue instanceof VariableRef) {
|
||||
VariableRef lValueRef = (VariableRef) lValue;
|
||||
RegisterAllocation.Register lValRegister = program.getAllocation().getRegister(lValueRef);
|
||||
if (lValRegister.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) {
|
||||
Registers.Register lValRegister = program.getScope().getVariable(lValueRef).getAllocation();
|
||||
if (lValRegister.getType().equals(Registers.RegisterType.REG_ALU_BYTE)) {
|
||||
asm.addComment(statement + " // ALU");
|
||||
StatementAssignment assignmentAlu = assignment;
|
||||
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) {
|
||||
VariableRef rValueRef = (VariableRef) rValue;
|
||||
return program.getAllocation().getRegister(rValueRef);
|
||||
return program.getScope().getVariable(rValueRef).getAllocation();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
||||
// Reset register allocation to original zero page allocation
|
||||
new Pass4RegistersFinalize(getProgram()).allocate(false);
|
||||
// Apply the uplift combination
|
||||
combination.allocate(getProgram().getAllocation());
|
||||
combination.allocate(getProgram().getScope());
|
||||
// Generate ASM
|
||||
try {
|
||||
new Pass4CodeGeneration(getProgram()).generate();
|
||||
|
@ -87,7 +87,7 @@ public class Pass4RegisterUpliftPotentialAluAnalysis extends Pass2Base {
|
||||
|
||||
private void hasAluPotential(RegisterPotentials registerPotentials, VariableRef ref) {
|
||||
LiveRangeEquivalenceClass potentialAluEquivalenceClass = liveRangeEquivalenceClassSet.getEquivalenceClass(ref);
|
||||
registerPotentials.addPotentialRegister(potentialAluEquivalenceClass, RegisterAllocation.getRegisterALU());
|
||||
registerPotentials.addPotentialRegister(potentialAluEquivalenceClass, Registers.getRegisterALU());
|
||||
getLog().append("Equivalence Class "+potentialAluEquivalenceClass+" has ALU potential.");
|
||||
}
|
||||
|
||||
|
@ -36,14 +36,14 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
||||
modified = true;
|
||||
registerPotentials = new RegisterPotentials();
|
||||
for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
|
||||
RegisterAllocation.Register defaultRegister = equivalenceClass.getRegister();
|
||||
RegisterAllocation.RegisterType registerType = defaultRegister.getType();
|
||||
if (registerType.equals(RegisterAllocation.RegisterType.ZP_BYTE)) {
|
||||
List<RegisterAllocation.Register> potentials = Arrays.asList(
|
||||
Registers.Register defaultRegister = equivalenceClass.getRegister();
|
||||
Registers.RegisterType registerType = defaultRegister.getType();
|
||||
if (registerType.equals(Registers.RegisterType.ZP_BYTE)) {
|
||||
List<Registers.Register> potentials = Arrays.asList(
|
||||
defaultRegister,
|
||||
RegisterAllocation.getRegisterA(),
|
||||
RegisterAllocation.getRegisterX(),
|
||||
RegisterAllocation.getRegisterY());
|
||||
Registers.getRegisterA(),
|
||||
Registers.getRegisterX(),
|
||||
Registers.getRegisterY());
|
||||
registerPotentials.setPotentialRegisters(equivalenceClass, potentials);
|
||||
} else {
|
||||
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
|
||||
// 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()) {
|
||||
// No registers are always clobbered - move on to the next statement
|
||||
continue;
|
||||
@ -82,7 +82,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Statement ").append(statement.toString(getProgram()));
|
||||
msg.append(" always clobbers ");
|
||||
for (RegisterAllocation.Register register : alwaysClobbered) {
|
||||
for (Registers.Register register : alwaysClobbered) {
|
||||
msg.append(register).append(" ");
|
||||
}
|
||||
getLog().append(msg.toString());
|
||||
@ -96,8 +96,8 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
||||
// Assigned registers are allowed to be be clobbered
|
||||
continue;
|
||||
}
|
||||
List<RegisterAllocation.Register> alivePotentialRegisters = registerPotentials.getPotentialRegisters(aliveClass);
|
||||
for (RegisterAllocation.Register clobberedRegister : alwaysClobbered) {
|
||||
List<Registers.Register> alivePotentialRegisters = registerPotentials.getPotentialRegisters(aliveClass);
|
||||
for (Registers.Register clobberedRegister : alwaysClobbered) {
|
||||
if (alivePotentialRegisters.contains(clobberedRegister)) {
|
||||
registerPotentials.removePotentialRegister(aliveClass, clobberedRegister);
|
||||
StringBuilder msg = new StringBuilder();
|
||||
@ -125,13 +125,13 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
||||
* @param combinations The regsiter combinations to test
|
||||
* @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
|
||||
Set<RegisterAllocation.Register> alwaysClobbered = new LinkedHashSet<>();
|
||||
alwaysClobbered.add(RegisterAllocation.getRegisterA());
|
||||
alwaysClobbered.add(RegisterAllocation.getRegisterX());
|
||||
alwaysClobbered.add(RegisterAllocation.getRegisterY());
|
||||
Set<Registers.Register> alwaysClobbered = new LinkedHashSet<>();
|
||||
alwaysClobbered.add(Registers.getRegisterA());
|
||||
alwaysClobbered.add(Registers.getRegisterX());
|
||||
alwaysClobbered.add(Registers.getRegisterY());
|
||||
|
||||
Set<String> unknownFragments = new LinkedHashSet<>();
|
||||
|
||||
@ -140,7 +140,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
||||
// Reset register allocation to original zero page allocation
|
||||
new Pass4RegistersFinalize(getProgram()).allocate(false);
|
||||
// Apply the combination
|
||||
combination.allocate(getProgram().getAllocation());
|
||||
combination.allocate(getProgram().getScope());
|
||||
// Generate ASM
|
||||
AsmProgram asm = new AsmProgram();
|
||||
asm.startSegment(statement.getIndex(), statement.toString(getProgram()));
|
||||
@ -157,10 +157,10 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
||||
continue;
|
||||
}
|
||||
AsmClobber clobber = asm.getClobber();
|
||||
Collection<RegisterAllocation.Register> clobberRegisters = Pass4AssertNoCpuClobber.getClobberRegisters(clobber);
|
||||
Iterator<RegisterAllocation.Register> alwaysClobberIt = alwaysClobbered.iterator();
|
||||
Collection<Registers.Register> clobberRegisters = Pass4AssertNoCpuClobber.getClobberRegisters(clobber);
|
||||
Iterator<Registers.Register> alwaysClobberIt = alwaysClobbered.iterator();
|
||||
while (alwaysClobberIt.hasNext()) {
|
||||
RegisterAllocation.Register alwaysClobberRegister = alwaysClobberIt.next();
|
||||
Registers.Register alwaysClobberRegister = alwaysClobberIt.next();
|
||||
if (!clobberRegisters.contains(alwaysClobberRegister)) {
|
||||
alwaysClobberIt.remove();
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class Pass4RegisterUpliftRemains extends Pass2Base {
|
||||
Set<String> unknownFragments = new LinkedHashSet<>();
|
||||
|
||||
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;
|
||||
RegisterCombination bestCombination = null;
|
||||
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
|
||||
new Pass4RegistersFinalize(getProgram()).allocate(false);
|
||||
// Apply the uplift combination
|
||||
combination.allocate(getProgram().getAllocation());
|
||||
combination.allocate(getProgram().getScope());
|
||||
// Generate ASM
|
||||
try {
|
||||
new Pass4CodeGeneration(getProgram()).generate();
|
||||
|
@ -17,8 +17,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
||||
if(reallocZp) {
|
||||
reallocateZp(liveRangeEquivalenceClassSet);
|
||||
}
|
||||
RegisterAllocation allocation = liveRangeEquivalenceClassSet.createRegisterAllocation();
|
||||
getProgram().setAllocation(allocation);
|
||||
liveRangeEquivalenceClassSet.storeRegisterAllocation();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,7 +27,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
||||
*/
|
||||
private void reallocateZp(LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet) {
|
||||
for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
|
||||
RegisterAllocation.Register register = equivalenceClass.getRegister();
|
||||
Registers.Register register = equivalenceClass.getRegister();
|
||||
if(register==null || register.isZp()) {
|
||||
String before = register==null?null:register.toString();
|
||||
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
|
||||
* @return The new zeropage register
|
||||
*/
|
||||
private RegisterAllocation.Register allocateNewRegisterZp(SymbolType varType) {
|
||||
private Registers.Register allocateNewRegisterZp(SymbolType varType) {
|
||||
if (varType.equals(SymbolTypeBasic.BYTE)) {
|
||||
return new RegisterAllocation.RegisterZpByte(currentZp++);
|
||||
return new Registers.RegisterZpByte(currentZp++);
|
||||
} else if (varType.equals(SymbolTypeBasic.WORD)) {
|
||||
RegisterAllocation.RegisterZpWord registerZpWord =
|
||||
new RegisterAllocation.RegisterZpWord(currentZp);
|
||||
Registers.RegisterZpWord registerZpWord =
|
||||
new Registers.RegisterZpWord(currentZp);
|
||||
currentZp = currentZp + 2;
|
||||
return registerZpWord;
|
||||
} else if (varType.equals(SymbolTypeBasic.BOOLEAN)) {
|
||||
return new RegisterAllocation.RegisterZpBool(currentZp++);
|
||||
return new Registers.RegisterZpBool(currentZp++);
|
||||
} else if (varType.equals(SymbolTypeBasic.VOID)) {
|
||||
// No need to setRegister register for VOID value
|
||||
return null;
|
||||
} else if (varType instanceof SymbolTypePointer) {
|
||||
RegisterAllocation.RegisterZpPointerByte registerZpPointerByte =
|
||||
new RegisterAllocation.RegisterZpPointerByte(currentZp);
|
||||
Registers.RegisterZpPointerByte registerZpPointerByte =
|
||||
new Registers.RegisterZpPointerByte(currentZp);
|
||||
currentZp = currentZp + 2;
|
||||
return registerZpPointerByte;
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user