mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-12 11:31:11 +00:00
Optimized live range equivalence classe set lookup from variable to spped up uplift.
This commit is contained in:
parent
58500b39e0
commit
a3c18cf756
@ -8,8 +8,8 @@ import java.util.List;
|
||||
**/
|
||||
public class LiveRangeEquivalenceClass {
|
||||
|
||||
/** The containing program. */
|
||||
private Program program;
|
||||
/** The containing set. */
|
||||
private LiveRangeEquivalenceClassSet set;
|
||||
|
||||
/** The variables of the equivalence class. */
|
||||
private List<VariableRef> variables;
|
||||
@ -20,8 +20,8 @@ public class LiveRangeEquivalenceClass {
|
||||
/** A register allocated to hold all variables of the equivalence class. (null if no register is currently allocated) */
|
||||
private Registers.Register register;
|
||||
|
||||
public LiveRangeEquivalenceClass(Program program) {
|
||||
this.program = program;
|
||||
public LiveRangeEquivalenceClass(LiveRangeEquivalenceClassSet set) {
|
||||
this.set = set;
|
||||
this.variables = new ArrayList<>();
|
||||
this.liveRange = new LiveRange();
|
||||
this.register = null;
|
||||
@ -44,13 +44,18 @@ public class LiveRangeEquivalenceClass {
|
||||
if(variables.contains(variable)) {
|
||||
return;
|
||||
}
|
||||
LiveRangeVariables liveRanges = program.getLiveRangeVariables();
|
||||
LiveRangeVariables liveRanges = set.getProgram().getLiveRangeVariables();
|
||||
LiveRange varLiveRange = liveRanges.getLiveRange(variable);
|
||||
if (liveRange.overlaps(varLiveRange)) {
|
||||
throw new RuntimeException("Compilation error! Variable live range overlaps live range equivalence class live range. " + variable);
|
||||
}
|
||||
liveRange.add(varLiveRange);
|
||||
variables.add(variable);
|
||||
set.setVarClass(variable, this);
|
||||
}
|
||||
|
||||
public List<VariableRef> getVariables() {
|
||||
return variables;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,17 +73,18 @@ public class LiveRangeEquivalenceClass {
|
||||
}
|
||||
|
||||
public void addAll(LiveRangeEquivalenceClass other) {
|
||||
variables.addAll(other.variables);
|
||||
liveRange.add(other.liveRange);
|
||||
variables.addAll(other.variables);
|
||||
for (VariableRef variable : other.variables) {
|
||||
set.setVarClass(variable, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
LiveRangeEquivalenceClass that = (LiveRangeEquivalenceClass) o;
|
||||
|
||||
return variables.equals(that.variables);
|
||||
}
|
||||
|
||||
@ -107,7 +113,4 @@ public class LiveRangeEquivalenceClass {
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public List<VariableRef> getVariables() {
|
||||
return variables;
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,43 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/** A set of live range equivalence classes. */
|
||||
/**
|
||||
* A set of live range equivalence classes.
|
||||
*/
|
||||
public class LiveRangeEquivalenceClassSet {
|
||||
|
||||
/**
|
||||
* The containing program.
|
||||
*/
|
||||
private Program program;
|
||||
|
||||
/**
|
||||
* The equivalence classes of the set.
|
||||
*/
|
||||
private List<LiveRangeEquivalenceClass> equivalenceClasses;
|
||||
|
||||
/**
|
||||
* Maps variables to their containing class.
|
||||
*/
|
||||
Map<VariableRef, LiveRangeEquivalenceClass> varClass;
|
||||
|
||||
public LiveRangeEquivalenceClassSet(Program program) {
|
||||
this.program = program;
|
||||
this.equivalenceClasses = new ArrayList<>();
|
||||
this.varClass = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the containing program
|
||||
*
|
||||
* @return The program
|
||||
*/
|
||||
Program getProgram() {
|
||||
return program;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,12 +53,33 @@ public class LiveRangeEquivalenceClassSet {
|
||||
return equivalenceClass;
|
||||
}
|
||||
// Not found - create it
|
||||
equivalenceClass = new LiveRangeEquivalenceClass(program);
|
||||
equivalenceClass = new LiveRangeEquivalenceClass(this);
|
||||
equivalenceClasses.add(equivalenceClass);
|
||||
equivalenceClass.addVariable(variable);
|
||||
return equivalenceClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consolidates two live range equivalence calsses into one.
|
||||
* All variables and live ranges from the other class is added to the first one - and the other one is deleted.
|
||||
* @param equivalenceClass The first live range equivalence class.
|
||||
* @param otherEquivalenceClass The other live range equivalence class, that is added to the first and deleted.
|
||||
*/
|
||||
public void consolidate(LiveRangeEquivalenceClass equivalenceClass, LiveRangeEquivalenceClass otherEquivalenceClass) {
|
||||
equivalenceClass.addAll(otherEquivalenceClass);
|
||||
equivalenceClasses.remove(otherEquivalenceClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs the set that class of a variable has ben set - called by add/remove methods inside LiveRangeEquivalenceClass
|
||||
*
|
||||
* @param variable The variable
|
||||
* @param equivalenceClass The class
|
||||
*/
|
||||
void setVarClass(VariableRef variable, LiveRangeEquivalenceClass equivalenceClass) {
|
||||
varClass.put(variable, equivalenceClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the phi equivalence class for a specific variable.
|
||||
*
|
||||
@ -41,12 +87,7 @@ public class LiveRangeEquivalenceClassSet {
|
||||
* @return The existing phi equivalence class. null if no equivalence class contains the variable.
|
||||
*/
|
||||
public LiveRangeEquivalenceClass getEquivalenceClass(VariableRef variable) {
|
||||
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
||||
if (equivalenceClass.contains(variable)) {
|
||||
return equivalenceClass;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return varClass.get(variable);
|
||||
}
|
||||
|
||||
public List<LiveRangeEquivalenceClass> getEquivalenceClasses() {
|
||||
@ -57,10 +98,6 @@ public class LiveRangeEquivalenceClassSet {
|
||||
return equivalenceClasses.size();
|
||||
}
|
||||
|
||||
public void remove(LiveRangeEquivalenceClass equivalenceClass) {
|
||||
equivalenceClasses.remove(equivalenceClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the register allocation of the live range equivalence classes into the variables in the symbol table (program scope).
|
||||
*/
|
||||
|
@ -76,8 +76,7 @@ public class Pass3PhiMemCoalesce extends Pass2SsaOptimization {
|
||||
replace.put((VariableRef) assignment.getlValue(), assignVar);
|
||||
getLog().append("Coalesced (already) " + assignment);
|
||||
} else if (!lValEquivalenceClass.getLiveRange().overlaps(assignVarEquivalenceClass.getLiveRange())) {
|
||||
lValEquivalenceClass.addAll(assignVarEquivalenceClass);
|
||||
phiEquivalenceClassSet.remove(assignVarEquivalenceClass);
|
||||
phiEquivalenceClassSet.consolidate(lValEquivalenceClass, assignVarEquivalenceClass);
|
||||
remove.add((VariableRef) assignment.getlValue());
|
||||
replace.put((VariableRef) assignment.getlValue(), assignVar);
|
||||
getLog().append("Coalesced " + assignment);
|
||||
@ -112,8 +111,7 @@ public class Pass3PhiMemCoalesce extends Pass2SsaOptimization {
|
||||
VariableRef phiRVar = (VariableRef) phiRValue.getrValue();
|
||||
LiveRangeEquivalenceClass rValEquivalenceClass = phiEquivalenceClasses.getOrCreateEquivalenceClass(phiRVar);
|
||||
if(!rValEquivalenceClass.equals(equivalenceClass)) {
|
||||
equivalenceClass.addAll(rValEquivalenceClass);
|
||||
phiEquivalenceClasses.remove(rValEquivalenceClass);
|
||||
phiEquivalenceClasses.consolidate(equivalenceClass, rValEquivalenceClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,8 +124,7 @@ public class Pass4RegisterUpliftStatic extends Pass2Base {
|
||||
VariableRef variableRef2 = scope.getVariable(varFullName2).getRef();
|
||||
LiveRangeEquivalenceClass equivalenceClass2 = equivalenceClassSet.getEquivalenceClass(variableRef2);
|
||||
if(!equivalenceClass1.equals(equivalenceClass2)) {
|
||||
equivalenceClass1.addAll(equivalenceClass2);
|
||||
equivalenceClassSet.remove(equivalenceClass2);
|
||||
equivalenceClassSet.consolidate(equivalenceClass1, equivalenceClass2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,7 @@ public class Pass4ZeroPageCoalesce extends Pass2Base {
|
||||
if (!myEquivalenceClass.equals(otherEquivalenceClass)) {
|
||||
if(canCoalesce(myEquivalenceClass, otherEquivalenceClass)) {
|
||||
getLog().append("Coalescing zero page register [ "+myEquivalenceClass+" ] with [ "+otherEquivalenceClass+" ]" );
|
||||
myEquivalenceClass.addAll(otherEquivalenceClass);
|
||||
liveRangeEquivalenceClassSet.remove(otherEquivalenceClass);
|
||||
liveRangeEquivalenceClassSet.consolidate(myEquivalenceClass, otherEquivalenceClass);
|
||||
// Reset the program register allocation
|
||||
getProgram().getLiveRangeEquivalenceClassSet().storeRegisterAllocation();
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user