Skip to content

Commit 5bdbeba

Browse files
Consider temp registers too as part of SSA because in boolean expressions, a temp is assigned value more than once so although generally temps are SSA already, in this case they are not.
1 parent a456dbb commit 5bdbeba

File tree

3 files changed

+34
-31
lines changed

3 files changed

+34
-31
lines changed

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

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -627,8 +627,6 @@ else if (indexed instanceof Operand.LoadFieldOperand loadFieldOperand) {
627627
}
628628

629629
private void codeNew(Type type) {
630-
// temps are already SSA so we don't need to
631-
// do anything special
632630
var temp = createTemp(type);
633631
if (type instanceof Type.TypeArray typeArray) {
634632
code(new Instruction.NewArray(typeArray, temp));
@@ -650,8 +648,8 @@ private void codeStoreAppend() {
650648
}
651649

652650
private void codeArg(Operand.LocalRegisterOperand target) {
653-
target = (Operand.LocalRegisterOperand) issa.write(target);
654-
var insn = new Instruction.ArgInstruction(target);
651+
var newtarget = (Operand.RegisterOperand) issa.write(target);
652+
var insn = new Instruction.ArgInstruction(newtarget);
655653
issa.recordDef(target, insn);
656654
code(insn);
657655
}
@@ -820,11 +818,14 @@ static final class IncrementalSSABraun implements IncrementalSSA {
820818
// a mapping is maintained for the name to SSA value (virtual register) in each block.
821819
// we could add this mapping to the BB itself but it seems nicer to keep it separate
822820
// at least for now.
823-
Map<Symbol.VarSymbol, Map<BasicBlock, Register>> currentDef = new HashMap<>();
821+
// Note that we use the nonSSAId as proxy for variable name
822+
// because this id is unique for non-SSA variables, but for SSA versions this refers
823+
// back to the original ID
824+
Map<Integer, Map<BasicBlock, Register>> currentDef = new HashMap<>();
824825
// Flags blocks that are completed in terms of instruction generation
825826
BitSet sealedBlocks = new BitSet();
826827
// Tracks Phis that are not finalized because the basic block is not yet sealed
827-
Map<BasicBlock, Map<Symbol.VarSymbol, Instruction.Phi>> incompletePhis = new HashMap<>();
828+
Map<BasicBlock, Map<Register, Instruction.Phi>> incompletePhis = new HashMap<>();
828829

829830
// Not explicitly stated in the paper but implicit in the algo is
830831
// the availability of Def-use chains. We have to main this incrementally as we
@@ -846,17 +847,17 @@ private IncrementalSSABraun(CompiledFunction function) {
846847
/**
847848
* Associates a new definition (value) to a variable name within a basic block
848849
*/
849-
private void writeVariable(Symbol.VarSymbol variable, BasicBlock block, Register value) {
850-
currentDef.computeIfAbsent(variable, k -> new HashMap<>()).put(block, value);
850+
private void writeVariable(Register variable, BasicBlock block, Register value) {
851+
currentDef.computeIfAbsent(variable.nonSSAId(), k -> new HashMap<>()).put(block, value);
851852
}
852853

853854
/**
854855
* Looks up the current SSA value (virtual register) associated with a name, inside a block.
855856
* If no mapping is found, processing depends on status of the block.
856-
* @see #readVariableRecursive(Symbol.VarSymbol, BasicBlock)
857+
* @see #readVariableRecursive(Register, BasicBlock)
857858
*/
858-
private Register readVariable(Symbol.VarSymbol variable, BasicBlock block) {
859-
Map<BasicBlock, Register> defs = currentDef.get(variable);
859+
private Register readVariable(Register variable, BasicBlock block) {
860+
Map<BasicBlock, Register> defs = currentDef.get(variable.nonSSAId());
860861
if (defs != null && defs.containsKey(block)) {
861862
// local value numbering
862863
return defs.get(block);
@@ -874,11 +875,11 @@ private Register readVariable(Symbol.VarSymbol variable, BasicBlock block) {
874875
* obtained recursively via each predecessor block.
875876
* In case of 1 predecessor the value is read recursively from that predecessor.
876877
*/
877-
private Register readVariableRecursive(Symbol.VarSymbol variable, BasicBlock block) {
878+
private Register readVariableRecursive(Register variable, BasicBlock block) {
878879
Register val;
879880
if (!sealedBlocks.get(block.bid)) {
880881
// incomplete CFG
881-
val = function.registerPool.newISSAReg("phi_" + variable.name, variable.type);
882+
val = function.registerPool.newISSAReg("phi_" + variable.name(), variable.type);
882883
Instruction.Phi phi = new Instruction.Phi(val, new ArrayList<>());
883884
recordDef(val, phi);
884885
block.add(0, phi);
@@ -890,7 +891,7 @@ else if (block.predecessors.size() == 1) {
890891
}
891892
else {
892893
// Break potential cycles with operandless phis
893-
val = function.registerPool.newISSAReg("phi_" + variable.name, variable.type);
894+
val = function.registerPool.newISSAReg("phi_" + variable.name(), variable.type);
894895
Instruction.Phi phi = new Instruction.Phi(val, new ArrayList<>());
895896
recordDef(val, phi);
896897
block.add(0, phi);
@@ -904,7 +905,7 @@ else if (block.predecessors.size() == 1) {
904905
/**
905906
* Populate the members of a phi instruction
906907
*/
907-
private Register addPhiOperands(Symbol.VarSymbol variable, Instruction.Phi phi) {
908+
private Register addPhiOperands(Register variable, Instruction.Phi phi) {
908909
// Determine operands from predecessors
909910
for (BasicBlock pred: phi.block.predecessors) {
910911
phi.addInput(readVariable(variable,pred));
@@ -984,34 +985,34 @@ private List<Instruction> getUsesExcept(Instruction.Phi phi) {
984985

985986
@Override
986987
public Operand read(Operand operand) {
987-
// We only consider declared local variables
988-
// because temps are already SSA in this compiler
989-
if (operand instanceof Operand.LocalRegisterOperand localRegisterOperand) {
990-
var reg = readVariable(localRegisterOperand.variable, function.currentBlock);
991-
operand = new Operand.LocalRegisterOperand(reg, localRegisterOperand.variable);
988+
// We have to consider temps too because of boolean expressions
989+
// where temps are not SSA
990+
if (operand instanceof Operand.RegisterOperand localRegisterOperand) {
991+
var reg = readVariable(localRegisterOperand.reg, function.currentBlock);
992+
operand = new Operand.RegisterOperand(reg);
992993
}
993994
return operand;
994995
}
995996
@Override
996997
public Operand write(Operand operand) {
997-
// We only consider declared local variables
998-
// because temps are already SSA in this compiler
999-
if (operand instanceof Operand.LocalRegisterOperand localRegisterOperand) {
1000-
var variable = localRegisterOperand.variable;
998+
// We have to consider temps too because of boolean expressions
999+
// where temps are not SSA
1000+
if (operand instanceof Operand.RegisterOperand localRegisterOperand) {
1001+
var variable = localRegisterOperand.reg;
10011002
Register newValue;
1002-
Integer version = versioned.get(localRegisterOperand.reg.nonSSAId());
1003+
Integer version = versioned.get(variable.nonSSAId());
10031004
// Avoid creating a new value first time because we already
10041005
// have a pre-created register we can use
10051006
if (version == null) {
1006-
newValue = localRegisterOperand.reg;
1007-
versioned.put(localRegisterOperand.reg.nonSSAId(), 1);
1007+
newValue = variable;
1008+
versioned.put(variable.nonSSAId(), 1);
10081009
}
10091010
else {
1010-
versioned.put(localRegisterOperand.reg.nonSSAId(), version + 1);
1011-
newValue = function.registerPool.ssaReg(localRegisterOperand.reg, version);
1011+
versioned.put(variable.nonSSAId(), version + 1);
1012+
newValue = function.registerPool.ssaReg(variable, version);
10121013
}
1013-
writeVariable(localRegisterOperand.variable, function.currentBlock, newValue);
1014-
operand = new Operand.LocalRegisterOperand(newValue,variable);
1014+
writeVariable(variable, function.currentBlock, newValue);
1015+
operand = new Operand.RegisterOperand(newValue);
10151016
}
10161017
return operand;
10171018
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public String name() {
8383
* During SSA form this is not valid for registers that are instances of SSARegister.
8484
*/
8585
public int nonSSAId() {
86+
assert frameSlot >= 0;
8687
return frameSlot;
8788
}
8889
public void updateSlot(int slot) {

optvm/src/test/java/com/compilerprogramming/ezlang/interpreter/TestInterpreter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Value compileAndRun(String src, String mainFunction) {
1313
return compileAndRun(src, mainFunction, Options.NONE);
1414
}
1515
Value compileAndRun(String src, String mainFunction, EnumSet<Options> options) {
16+
//options.add(Options.ISSA);
1617
var compiler = new Compiler();
1718
var typeDict = compiler.compileSrc(src, options);
1819
var compiled = compiler.dumpIR(typeDict);

0 commit comments

Comments
 (0)