mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-09-08 17:54:40 +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 {
|
public class LiveRangeEquivalenceClass {
|
||||||
|
|
||||||
/** The containing program. */
|
/** The containing set. */
|
||||||
private Program program;
|
private LiveRangeEquivalenceClassSet set;
|
||||||
|
|
||||||
/** The variables of the equivalence class. */
|
/** The variables of the equivalence class. */
|
||||||
private List<VariableRef> variables;
|
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) */
|
/** A register allocated to hold all variables of the equivalence class. (null if no register is currently allocated) */
|
||||||
private Registers.Register register;
|
private Registers.Register register;
|
||||||
|
|
||||||
public LiveRangeEquivalenceClass(Program program) {
|
public LiveRangeEquivalenceClass(LiveRangeEquivalenceClassSet set) {
|
||||||
this.program = program;
|
this.set = set;
|
||||||
this.variables = new ArrayList<>();
|
this.variables = new ArrayList<>();
|
||||||
this.liveRange = new LiveRange();
|
this.liveRange = new LiveRange();
|
||||||
this.register = null;
|
this.register = null;
|
||||||
@ -44,13 +44,18 @@ public class LiveRangeEquivalenceClass {
|
|||||||
if(variables.contains(variable)) {
|
if(variables.contains(variable)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LiveRangeVariables liveRanges = program.getLiveRangeVariables();
|
LiveRangeVariables liveRanges = set.getProgram().getLiveRangeVariables();
|
||||||
LiveRange varLiveRange = liveRanges.getLiveRange(variable);
|
LiveRange varLiveRange = liveRanges.getLiveRange(variable);
|
||||||
if (liveRange.overlaps(varLiveRange)) {
|
if (liveRange.overlaps(varLiveRange)) {
|
||||||
throw new RuntimeException("Compilation error! Variable live range overlaps live range equivalence class live range. " + variable);
|
throw new RuntimeException("Compilation error! Variable live range overlaps live range equivalence class live range. " + variable);
|
||||||
}
|
}
|
||||||
liveRange.add(varLiveRange);
|
liveRange.add(varLiveRange);
|
||||||
variables.add(variable);
|
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) {
|
public void addAll(LiveRangeEquivalenceClass other) {
|
||||||
variables.addAll(other.variables);
|
|
||||||
liveRange.add(other.liveRange);
|
liveRange.add(other.liveRange);
|
||||||
|
variables.addAll(other.variables);
|
||||||
|
for (VariableRef variable : other.variables) {
|
||||||
|
set.setVarClass(variable, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
LiveRangeEquivalenceClass that = (LiveRangeEquivalenceClass) o;
|
LiveRangeEquivalenceClass that = (LiveRangeEquivalenceClass) o;
|
||||||
|
|
||||||
return variables.equals(that.variables);
|
return variables.equals(that.variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +113,4 @@ public class LiveRangeEquivalenceClass {
|
|||||||
return s.toString();
|
return s.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<VariableRef> getVariables() {
|
|
||||||
return variables;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,43 @@
|
|||||||
package dk.camelot64.kickc.model;
|
package dk.camelot64.kickc.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
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 {
|
public class LiveRangeEquivalenceClassSet {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The containing program.
|
||||||
|
*/
|
||||||
private Program program;
|
private Program program;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The equivalence classes of the set.
|
||||||
|
*/
|
||||||
private List<LiveRangeEquivalenceClass> equivalenceClasses;
|
private List<LiveRangeEquivalenceClass> equivalenceClasses;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps variables to their containing class.
|
||||||
|
*/
|
||||||
|
Map<VariableRef, LiveRangeEquivalenceClass> varClass;
|
||||||
|
|
||||||
public LiveRangeEquivalenceClassSet(Program program) {
|
public LiveRangeEquivalenceClassSet(Program program) {
|
||||||
this.program = program;
|
this.program = program;
|
||||||
this.equivalenceClasses = new ArrayList<>();
|
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;
|
return equivalenceClass;
|
||||||
}
|
}
|
||||||
// Not found - create it
|
// Not found - create it
|
||||||
equivalenceClass = new LiveRangeEquivalenceClass(program);
|
equivalenceClass = new LiveRangeEquivalenceClass(this);
|
||||||
equivalenceClasses.add(equivalenceClass);
|
equivalenceClasses.add(equivalenceClass);
|
||||||
equivalenceClass.addVariable(variable);
|
equivalenceClass.addVariable(variable);
|
||||||
return equivalenceClass;
|
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.
|
* 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.
|
* @return The existing phi equivalence class. null if no equivalence class contains the variable.
|
||||||
*/
|
*/
|
||||||
public LiveRangeEquivalenceClass getEquivalenceClass(VariableRef variable) {
|
public LiveRangeEquivalenceClass getEquivalenceClass(VariableRef variable) {
|
||||||
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
return varClass.get(variable);
|
||||||
if (equivalenceClass.contains(variable)) {
|
|
||||||
return equivalenceClass;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LiveRangeEquivalenceClass> getEquivalenceClasses() {
|
public List<LiveRangeEquivalenceClass> getEquivalenceClasses() {
|
||||||
@ -57,10 +98,6 @@ public class LiveRangeEquivalenceClassSet {
|
|||||||
return equivalenceClasses.size();
|
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).
|
* 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);
|
replace.put((VariableRef) assignment.getlValue(), assignVar);
|
||||||
getLog().append("Coalesced (already) " + assignment);
|
getLog().append("Coalesced (already) " + assignment);
|
||||||
} else if (!lValEquivalenceClass.getLiveRange().overlaps(assignVarEquivalenceClass.getLiveRange())) {
|
} else if (!lValEquivalenceClass.getLiveRange().overlaps(assignVarEquivalenceClass.getLiveRange())) {
|
||||||
lValEquivalenceClass.addAll(assignVarEquivalenceClass);
|
phiEquivalenceClassSet.consolidate(lValEquivalenceClass, assignVarEquivalenceClass);
|
||||||
phiEquivalenceClassSet.remove(assignVarEquivalenceClass);
|
|
||||||
remove.add((VariableRef) assignment.getlValue());
|
remove.add((VariableRef) assignment.getlValue());
|
||||||
replace.put((VariableRef) assignment.getlValue(), assignVar);
|
replace.put((VariableRef) assignment.getlValue(), assignVar);
|
||||||
getLog().append("Coalesced " + assignment);
|
getLog().append("Coalesced " + assignment);
|
||||||
@ -112,8 +111,7 @@ public class Pass3PhiMemCoalesce extends Pass2SsaOptimization {
|
|||||||
VariableRef phiRVar = (VariableRef) phiRValue.getrValue();
|
VariableRef phiRVar = (VariableRef) phiRValue.getrValue();
|
||||||
LiveRangeEquivalenceClass rValEquivalenceClass = phiEquivalenceClasses.getOrCreateEquivalenceClass(phiRVar);
|
LiveRangeEquivalenceClass rValEquivalenceClass = phiEquivalenceClasses.getOrCreateEquivalenceClass(phiRVar);
|
||||||
if(!rValEquivalenceClass.equals(equivalenceClass)) {
|
if(!rValEquivalenceClass.equals(equivalenceClass)) {
|
||||||
equivalenceClass.addAll(rValEquivalenceClass);
|
phiEquivalenceClasses.consolidate(equivalenceClass, rValEquivalenceClass);
|
||||||
phiEquivalenceClasses.remove(rValEquivalenceClass);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,8 +124,7 @@ public class Pass4RegisterUpliftStatic extends Pass2Base {
|
|||||||
VariableRef variableRef2 = scope.getVariable(varFullName2).getRef();
|
VariableRef variableRef2 = scope.getVariable(varFullName2).getRef();
|
||||||
LiveRangeEquivalenceClass equivalenceClass2 = equivalenceClassSet.getEquivalenceClass(variableRef2);
|
LiveRangeEquivalenceClass equivalenceClass2 = equivalenceClassSet.getEquivalenceClass(variableRef2);
|
||||||
if(!equivalenceClass1.equals(equivalenceClass2)) {
|
if(!equivalenceClass1.equals(equivalenceClass2)) {
|
||||||
equivalenceClass1.addAll(equivalenceClass2);
|
equivalenceClassSet.consolidate(equivalenceClass1, equivalenceClass2);
|
||||||
equivalenceClassSet.remove(equivalenceClass2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,8 +34,7 @@ public class Pass4ZeroPageCoalesce extends Pass2Base {
|
|||||||
if (!myEquivalenceClass.equals(otherEquivalenceClass)) {
|
if (!myEquivalenceClass.equals(otherEquivalenceClass)) {
|
||||||
if(canCoalesce(myEquivalenceClass, otherEquivalenceClass)) {
|
if(canCoalesce(myEquivalenceClass, otherEquivalenceClass)) {
|
||||||
getLog().append("Coalescing zero page register [ "+myEquivalenceClass+" ] with [ "+otherEquivalenceClass+" ]" );
|
getLog().append("Coalescing zero page register [ "+myEquivalenceClass+" ] with [ "+otherEquivalenceClass+" ]" );
|
||||||
myEquivalenceClass.addAll(otherEquivalenceClass);
|
liveRangeEquivalenceClassSet.consolidate(myEquivalenceClass, otherEquivalenceClass);
|
||||||
liveRangeEquivalenceClassSet.remove(otherEquivalenceClass);
|
|
||||||
// Reset the program register allocation
|
// Reset the program register allocation
|
||||||
getProgram().getLiveRangeEquivalenceClassSet().storeRegisterAllocation();
|
getProgram().getLiveRangeEquivalenceClassSet().storeRegisterAllocation();
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user