Skip to content

Commit e166579

Browse files
Merge pull request #32 from CompilerProgramming/ssabraun
Implement Incremental SSA construction using Braun's method
2 parents 59a83eb + 02edd46 commit e166579

File tree

15 files changed

+724
-109
lines changed

15 files changed

+724
-109
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,10 @@ public void deleteInstruction(Instruction instruction) {
111111
instructions.remove(instruction);
112112
}
113113
public void addSuccessor(BasicBlock successor) {
114-
assert successors.contains(successor) == false;
115-
successors.add(successor);
116-
assert successor.predecessors.contains(this) == false;
117-
successor.predecessors.add(this);
114+
if (!successors.contains(successor)) {
115+
successors.add(successor);
116+
successor.predecessors.add(this);
117+
}
118118
}
119119
public void removeSuccessor(BasicBlock successor) {
120120
successors.remove(successor);

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

Lines changed: 497 additions & 56 deletions
Large diffs are not rendered by default.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ private void compile(TypeDictionary typeDictionary, EnumSet<Options> options) {
1616
for (Symbol symbol: typeDictionary.getLocalSymbols()) {
1717
if (symbol instanceof Symbol.FunctionTypeSymbol functionSymbol) {
1818
Type.TypeFunction functionType = (Type.TypeFunction) functionSymbol.type;
19-
var function = new CompiledFunction(functionSymbol, typeDictionary);
19+
var function = new CompiledFunction(functionSymbol, typeDictionary, options);
2020
if (options.contains(Options.DUMP_INITIAL_IR))
2121
function.dumpIR(false, "Initial IR");
2222
functionType.code = function;

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,6 @@ public ConditionalBranch(BasicBlock currentBlock, Operand condition, BasicBlock
290290
super(I_CBR, (Operand.RegisterOperand) null, condition);
291291
this.trueBlock = trueBlock;
292292
this.falseBlock = falseBlock;
293-
currentBlock.addSuccessor(trueBlock);
294-
currentBlock.addSuccessor(falseBlock);
295293
}
296294
public Operand condition() { return uses[0]; }
297295
@Override
@@ -426,6 +424,22 @@ public StringBuilder toStr(StringBuilder sb) {
426424
sb.append(")");
427425
return sb;
428426
}
427+
public void addInput(Register register) {
428+
var newUses = new Operand[uses.length + 1];
429+
System.arraycopy(uses, 0, newUses, 0, uses.length);
430+
newUses[newUses.length-1] = new Operand.RegisterOperand(register);
431+
this.uses = newUses;
432+
}
433+
public void replaceInput(Register oldReg, Register newReg) {
434+
for (int i = 0; i < numInputs(); i++) {
435+
if (isRegisterInput(i)) {
436+
Register in = inputAsRegister(i);
437+
if (in.equals(oldReg)) {
438+
replaceInput(i, newReg);
439+
}
440+
}
441+
}
442+
}
429443
}
430444

431445
public static class ArgInstruction extends Instruction {

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.compilerprogramming.ezlang.compiler;
22

3+
import com.compilerprogramming.ezlang.types.Symbol;
34
import com.compilerprogramming.ezlang.types.Type;
45

56
public class Operand {
@@ -35,7 +36,7 @@ protected RegisterOperand(Register reg) {
3536
if (reg == null)
3637
throw new NullPointerException();
3738
}
38-
public int frameSlot() { return reg.nonSSAId(); }
39+
public int frameSlot() { return reg.frameSlot(); }
3940

4041
public RegisterOperand copy(Register register) {
4142
return new RegisterOperand(register);
@@ -48,12 +49,14 @@ public String toString() {
4849
}
4950

5051
public static class LocalRegisterOperand extends RegisterOperand {
51-
public LocalRegisterOperand(Register reg) {
52+
Symbol.VarSymbol variable;
53+
public LocalRegisterOperand(Register reg, Symbol.VarSymbol variable) {
5254
super(reg);
55+
this.variable = variable;
5356
}
5457
@Override
5558
public RegisterOperand copy(Register register) {
56-
return new LocalRegisterOperand(register);
59+
return new LocalRegisterOperand(register, variable);
5760
}
5861
}
5962

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ public class Optimizer {
66

77
public void optimize(CompiledFunction function, EnumSet<Options> options) {
88
if (options.contains(Options.OPTIMIZE)) {
9-
new EnterSSA(function, options);
9+
if (!function.isSSA)
10+
new EnterSSA(function, options);
1011
if (options.contains(Options.SCCP)) {
1112
new SparseConditionalConstantPropagation().constantPropagation(function).apply(options);
1213
if (new ConstantComparisonPropagation(function).apply(options)) {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.EnumSet;
44

55
public enum Options {
6+
ISSA, // Incremental SSA
67
OPTIMIZE,
78
SCCP,
89
CCP, // constant comparison propagation
@@ -22,5 +23,6 @@ public enum Options {
2223

2324
public static final EnumSet<Options> NONE = EnumSet.noneOf(Options.class);
2425
public static final EnumSet<Options> OPT = EnumSet.of(Options.OPTIMIZE,Options.SCCP,Options.CCP,Options.REGALLOC);
25-
public static final EnumSet<Options> OPT_VERBOSE = EnumSet.allOf(Options.class);
26+
public static final EnumSet<Options> VERBOSE = EnumSet.range(DUMP_INITIAL_IR, DUMP_POST_CHAITIN_IR);
27+
public static final EnumSet<Options> OPT_VERBOSE = EnumSet.range(OPTIMIZE, DUMP_POST_CHAITIN_IR);
2628
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,13 @@ 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; // assert inteferes with verbose display
8687
return frameSlot;
8788
}
8889
public void updateSlot(int slot) {
8990
this.frameSlot = slot;
9091
}
92+
public int frameSlot() { return frameSlot; }
9193

9294
/**
9395
* An SSA Register retains a reference to the original
@@ -106,4 +108,6 @@ public int nonSSAId() {
106108
return originalRegNumber;
107109
}
108110
}
111+
112+
109113
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public int numRegisters() {
4949
}
5050
public void toStr(StringBuilder sb) {
5151
for (Register reg : registers) {
52-
sb.append("Reg #").append(reg.id).append(" ").append(reg.name()).append("\n");
52+
sb.append("Reg #").append(reg.id).append(" ").append(reg.name()).append(" ").append(reg.nonSSAId()).append("\n");
5353
}
5454
}
5555
}

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,16 @@ private static void recordUses(CompiledFunction function, Map<Register, SSADef>
8383

8484
private static void recordUses(Map<Register, SSADef> defUseChains, Register[] inputs, BasicBlock block, Instruction instruction) {
8585
for (Register register : inputs) {
86-
SSADef def = defUseChains.get(register);
87-
def.useList.add(instruction);
86+
recordUse(defUseChains, instruction, register);
8887
}
8988
}
9089

91-
private static void recordDef(Map<Register, SSADef> defUseChains, Register value, Instruction instruction) {
90+
public static void recordUse(Map<Register, SSADef> defUseChains, Instruction instruction, Register register) {
91+
SSADef def = defUseChains.get(register);
92+
def.useList.add(instruction);
93+
}
94+
95+
public static void recordDef(Map<Register, SSADef> defUseChains, Register value, Instruction instruction) {
9296
if (defUseChains.containsKey(value))
9397
throw new CompilerException("Register already defined, invalid multiple definition in SSA");
9498
defUseChains.put(value, new SSADef(instruction));

0 commit comments

Comments
 (0)