Skip to content

Commit 2b02afb

Browse files
#53 When a phi goes dead all references to its def in the memoized set of defs must be removed
1 parent 4a956bf commit 2b02afb

File tree

5 files changed

+320
-255
lines changed

5 files changed

+320
-255
lines changed

optvm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,32 @@ private Register addPhiOperands(Register variable, Instruction.Phi phi) {
965965
return tryRemovingPhi(phi);
966966
}
967967

968+
// The Phi's def is dead so we need to remove
969+
// all occurrences of this def from the memoized defs
970+
// per Basic Block
971+
private void clearDefs(Instruction.Phi phi) {
972+
// TODO rethink the data structure for currentDef
973+
var def = phi.value();
974+
var defs = currentDef.get(def.nonSSAId());
975+
// Make a list of block/reg that we need to delete
976+
var bbList = new ArrayList<BasicBlock>();
977+
var regList = new ArrayList<Register>();
978+
for (var entries : defs.entrySet()) {
979+
var bb = entries.getKey();
980+
var reg = entries.getValue();
981+
if (reg.equals(def)) {
982+
bbList.add(bb);
983+
regList.add(reg);
984+
}
985+
}
986+
// Now delete them
987+
for (int i = 0; i < bbList.size(); i++) {
988+
var bb = bbList.get(i);
989+
var reg = regList.get(i);
990+
defs.remove(bb, reg);
991+
}
992+
}
993+
968994
private Register tryRemovingPhi(Instruction.Phi phi) {
969995
Register same = null;
970996
// Check if phi has distinct inputs
@@ -991,6 +1017,9 @@ private Register tryRemovingPhi(Instruction.Phi phi) {
9911017
// remove all uses of phi to same and remove phi
9921018
replacePhiValueAndUsers(phi, same);
9931019
phi.block.deleteInstruction(phi);
1020+
// Since the phi is dead any references to its def
1021+
// must be removed; this is not mentioned in the paper
1022+
clearDefs(phi);
9941023
// try to recursively remove all phi users, which might have become trivial
9951024
for (var use: users) {
9961025
if (use instanceof Instruction.Phi phiuser)
@@ -1003,25 +1032,28 @@ private Register tryRemovingPhi(Instruction.Phi phi) {
10031032
* Reroute all uses of phi to new value
10041033
*/
10051034
private void replacePhiValueAndUsers(Instruction.Phi phi, Register newValue) {
1006-
var oldDefUseChain = ssaDefUses.get(phi.value());
1035+
var oldValue = phi.value();
1036+
var oldDefUseChain = ssaDefUses.get(oldValue);
10071037
var newDefUseChain = ssaDefUses.get(newValue);
10081038
if (newDefUseChain == null) {
1009-
// Can be null because this may be existing def
1010-
newDefUseChain = SSAEdges.addDef(ssaDefUses, newValue, phi);
1039+
throw new CompilerException("Expected error: undefined var " + newValue);
10111040
}
10121041
if (oldDefUseChain != null) {
10131042
for (Instruction instruction: oldDefUseChain.useList) {
1043+
boolean replaced;
10141044
if (instruction instanceof Instruction.Phi somePhi) {
1015-
somePhi.replaceInput(phi.value(), newValue);
1045+
replaced = somePhi.replaceInput(oldValue, newValue);
10161046
}
10171047
else {
1018-
instruction.replaceUse(phi.value(), newValue);
1048+
replaced = instruction.replaceUse(oldValue, newValue);
1049+
}
1050+
if (!replaced) {
1051+
throw new CompilerException("Discrepancy between var use list and var definition");
10191052
}
10201053
}
10211054
// Users of phi old value become users of the new value
10221055
newDefUseChain.useList.addAll(oldDefUseChain.useList);
10231056
oldDefUseChain.useList.clear();
1024-
// FIXME remove old def from def-use chains
10251057
}
10261058
}
10271059

optvm/src/main/java/com/compilerprogramming/ezlang/compiler/Instruction.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,15 +431,18 @@ public void addInput(Register register) {
431431
newUses[newUses.length-1] = new Operand.RegisterOperand(register);
432432
this.uses = newUses;
433433
}
434-
public void replaceInput(Register oldReg, Register newReg) {
434+
public boolean replaceInput(Register oldReg, Register newReg) {
435+
boolean replaced = false;
435436
for (int i = 0; i < numInputs(); i++) {
436437
if (isRegisterInput(i)) {
437438
Register in = inputAsRegister(i);
438439
if (in.equals(oldReg)) {
439440
replaceInput(i, newReg);
441+
replaced = true;
440442
}
441443
}
442444
}
445+
return replaced;
443446
}
444447
}
445448

optvm/src/main/java/com/compilerprogramming/ezlang/compiler/Register.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class Register {
4040
*
4141
* Not unique.
4242
*/
43-
private final String name;
43+
protected final String name;
4444
/**
4545
* The type of the register
4646
*/
@@ -50,7 +50,7 @@ public class Register {
5050
* of the executing function. Multiple registers may share the same
5151
* frame slot because of different non-overlapping life times.
5252
*/
53-
private int frameSlot;
53+
protected int frameSlot;
5454

5555
public Register(int id, String name, Type type) {
5656
this(id,name,type,id); // Initially frame slot is set to the unique ID
@@ -107,7 +107,15 @@ public SSARegister(Register original, int id, int version) {
107107
public int nonSSAId() {
108108
return originalRegNumber;
109109
}
110-
}
111110

111+
@Override
112+
public String toString() {
113+
return "SSARegister{name=" + name + ", id=" + id + ", frameSlot=" + frameSlot + ", ssaVersion=" + ssaVersion + ", originalRegNumber=" + originalRegNumber + '}';
114+
}
115+
}
112116

117+
@Override
118+
public String toString() {
119+
return "Register{name=" + name + ", id=" + id + ", frameSlot=" + frameSlot + "}";
120+
}
113121
}

optvm/src/main/java/com/compilerprogramming/ezlang/compiler/SSAEdges.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ private static void recordUses(Map<Register, SSADef> defUseChains, Register[] in
8989

9090
public static void recordUse(Map<Register, SSADef> defUseChains, Instruction instruction, Register register) {
9191
SSADef def = defUseChains.get(register);
92+
if (def == null)
93+
throw new CompilerException("No def found for " + register);
9294
def.useList.add(instruction);
9395
}
9496

0 commit comments

Comments
 (0)