Skip to content

Commit 2883784

Browse files
phi vars must also be SSA values
When temps are used for creating arrays and structs ensure they get processed in the same way as all temps.
1 parent 5bdbeba commit 2883784

File tree

1 file changed

+49
-27
lines changed

1 file changed

+49
-27
lines changed

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

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -627,17 +627,30 @@ else if (indexed instanceof Operand.LoadFieldOperand loadFieldOperand) {
627627
}
628628

629629
private void codeNew(Type type) {
630-
var temp = createTemp(type);
631-
if (type instanceof Type.TypeArray typeArray) {
632-
code(new Instruction.NewArray(typeArray, temp));
633-
}
634-
else if (type instanceof Type.TypeStruct typeStruct) {
635-
code(new Instruction.NewStruct(typeStruct, temp));
636-
}
630+
if (type instanceof Type.TypeArray typeArray)
631+
codeNewArray(typeArray);
632+
else if (type instanceof Type.TypeStruct typeStruct)
633+
codeNewStruct(typeStruct);
637634
else
638635
throw new CompilerException("Unexpected type: " + type);
639636
}
640637

638+
private void codeNewArray(Type.TypeArray typeArray) {
639+
var temp = createTemp(typeArray);
640+
var target = (Operand.RegisterOperand) issa.write(temp);
641+
var insn = new Instruction.NewArray(typeArray, target);
642+
issa.recordDef(target, insn);
643+
code(insn);
644+
}
645+
646+
private void codeNewStruct(Type.TypeStruct typeStruct) {
647+
var temp = createTemp(typeStruct);
648+
var target = (Operand.RegisterOperand) issa.write(temp);
649+
var insn = new Instruction.NewStruct(typeStruct, target);
650+
issa.recordDef(target, insn);
651+
code(insn);
652+
}
653+
641654
private void codeStoreAppend() {
642655
var operand = issa.read(pop());
643656
Operand.RegisterOperand arrayOperand = (Operand.RegisterOperand) issa.read(top());
@@ -879,10 +892,8 @@ private Register readVariableRecursive(Register variable, BasicBlock block) {
879892
Register val;
880893
if (!sealedBlocks.get(block.bid)) {
881894
// incomplete CFG
882-
val = function.registerPool.newISSAReg("phi_" + variable.name(), variable.type);
883-
Instruction.Phi phi = new Instruction.Phi(val, new ArrayList<>());
884-
recordDef(val, phi);
885-
block.add(0, phi);
895+
val = makeVersion(variable);
896+
Instruction.Phi phi = makePhi(val, block);
886897
incompletePhis.computeIfAbsent(block, k -> new HashMap<>()).put(variable, phi);
887898
}
888899
else if (block.predecessors.size() == 1) {
@@ -891,17 +902,22 @@ else if (block.predecessors.size() == 1) {
891902
}
892903
else {
893904
// Break potential cycles with operandless phis
894-
val = function.registerPool.newISSAReg("phi_" + variable.name(), variable.type);
895-
Instruction.Phi phi = new Instruction.Phi(val, new ArrayList<>());
896-
recordDef(val, phi);
897-
block.add(0, phi);
905+
val = makeVersion(variable);
906+
Instruction.Phi phi = makePhi(val, block);
898907
writeVariable(variable, block, val);
899908
val = addPhiOperands(variable,phi);
900909
}
901910
writeVariable(variable, block, val);
902911
return val;
903912
}
904913

914+
private Instruction.Phi makePhi(Register val, BasicBlock block) {
915+
Instruction.Phi phi = new Instruction.Phi(val, new ArrayList<>());
916+
recordDef(val, phi);
917+
block.add(0, phi);
918+
return phi;
919+
}
920+
905921
/**
906922
* Populate the members of a phi instruction
907923
*/
@@ -999,23 +1015,29 @@ public Operand write(Operand operand) {
9991015
// where temps are not SSA
10001016
if (operand instanceof Operand.RegisterOperand localRegisterOperand) {
10011017
var variable = localRegisterOperand.reg;
1002-
Register newValue;
1003-
Integer version = versioned.get(variable.nonSSAId());
1004-
// Avoid creating a new value first time because we already
1005-
// have a pre-created register we can use
1006-
if (version == null) {
1007-
newValue = variable;
1008-
versioned.put(variable.nonSSAId(), 1);
1009-
}
1010-
else {
1011-
versioned.put(variable.nonSSAId(), version + 1);
1012-
newValue = function.registerPool.ssaReg(variable, version);
1013-
}
1018+
Register newValue = makeVersion(variable);
10141019
writeVariable(variable, function.currentBlock, newValue);
10151020
operand = new Operand.RegisterOperand(newValue);
10161021
}
10171022
return operand;
10181023
}
1024+
1025+
private Register makeVersion(Register variable) {
1026+
Register newValue;
1027+
Integer version = versioned.get(variable.nonSSAId());
1028+
// Avoid creating a new value first time because we already
1029+
// have a pre-created register we can use
1030+
if (version == null) {
1031+
newValue = variable;
1032+
versioned.put(variable.nonSSAId(), 1);
1033+
}
1034+
else {
1035+
versioned.put(variable.nonSSAId(), version + 1);
1036+
newValue = function.registerPool.ssaReg(variable, version);
1037+
}
1038+
return newValue;
1039+
}
1040+
10191041
@Override
10201042
public void recordUse(Operand operand, Instruction instruction) {
10211043
if (operand instanceof Operand.RegisterOperand registerOperand) {

0 commit comments

Comments
 (0)