Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ public void deleteInstruction(Instruction instruction) {
instructions.remove(instruction);
}
public void addSuccessor(BasicBlock successor) {
assert successors.contains(successor) == false;
successors.add(successor);
assert successor.predecessors.contains(this) == false;
successor.predecessors.add(this);
if (!successors.contains(successor)) {
successors.add(successor);
successor.predecessors.add(this);
}
}
public void removeSuccessor(BasicBlock successor) {
successors.remove(successor);
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ private void compile(TypeDictionary typeDictionary, EnumSet<Options> options) {
for (Symbol symbol: typeDictionary.getLocalSymbols()) {
if (symbol instanceof Symbol.FunctionTypeSymbol functionSymbol) {
Type.TypeFunction functionType = (Type.TypeFunction) functionSymbol.type;
var function = new CompiledFunction(functionSymbol, typeDictionary);
var function = new CompiledFunction(functionSymbol, typeDictionary, options);
if (options.contains(Options.DUMP_INITIAL_IR))
function.dumpIR(false, "Initial IR");
functionType.code = function;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,6 @@ public ConditionalBranch(BasicBlock currentBlock, Operand condition, BasicBlock
super(I_CBR, (Operand.RegisterOperand) null, condition);
this.trueBlock = trueBlock;
this.falseBlock = falseBlock;
currentBlock.addSuccessor(trueBlock);
currentBlock.addSuccessor(falseBlock);
}
public Operand condition() { return uses[0]; }
@Override
Expand Down Expand Up @@ -426,6 +424,22 @@ public StringBuilder toStr(StringBuilder sb) {
sb.append(")");
return sb;
}
public void addInput(Register register) {
var newUses = new Operand[uses.length + 1];
System.arraycopy(uses, 0, newUses, 0, uses.length);
newUses[newUses.length-1] = new Operand.RegisterOperand(register);
this.uses = newUses;
}
public void replaceInput(Register oldReg, Register newReg) {
for (int i = 0; i < numInputs(); i++) {
if (isRegisterInput(i)) {
Register in = inputAsRegister(i);
if (in.equals(oldReg)) {
replaceInput(i, newReg);
}
}
}
}
}

public static class ArgInstruction extends Instruction {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.types.Symbol;
import com.compilerprogramming.ezlang.types.Type;

public class Operand {
Expand Down Expand Up @@ -35,7 +36,7 @@ protected RegisterOperand(Register reg) {
if (reg == null)
throw new NullPointerException();
}
public int frameSlot() { return reg.nonSSAId(); }
public int frameSlot() { return reg.frameSlot(); }

public RegisterOperand copy(Register register) {
return new RegisterOperand(register);
Expand All @@ -48,12 +49,14 @@ public String toString() {
}

public static class LocalRegisterOperand extends RegisterOperand {
public LocalRegisterOperand(Register reg) {
Symbol.VarSymbol variable;
public LocalRegisterOperand(Register reg, Symbol.VarSymbol variable) {
super(reg);
this.variable = variable;
}
@Override
public RegisterOperand copy(Register register) {
return new LocalRegisterOperand(register);
return new LocalRegisterOperand(register, variable);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ public class Optimizer {

public void optimize(CompiledFunction function, EnumSet<Options> options) {
if (options.contains(Options.OPTIMIZE)) {
new EnterSSA(function, options);
if (!function.isSSA)
new EnterSSA(function, options);
if (options.contains(Options.SCCP)) {
new SparseConditionalConstantPropagation().constantPropagation(function).apply(options);
if (new ConstantComparisonPropagation(function).apply(options)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.EnumSet;

public enum Options {
ISSA, // Incremental SSA
OPTIMIZE,
SCCP,
CCP, // constant comparison propagation
Expand All @@ -22,5 +23,6 @@ public enum Options {

public static final EnumSet<Options> NONE = EnumSet.noneOf(Options.class);
public static final EnumSet<Options> OPT = EnumSet.of(Options.OPTIMIZE,Options.SCCP,Options.CCP,Options.REGALLOC);
public static final EnumSet<Options> OPT_VERBOSE = EnumSet.allOf(Options.class);
public static final EnumSet<Options> VERBOSE = EnumSet.range(DUMP_INITIAL_IR, DUMP_POST_CHAITIN_IR);
public static final EnumSet<Options> OPT_VERBOSE = EnumSet.range(OPTIMIZE, DUMP_POST_CHAITIN_IR);
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,13 @@ public String name() {
* During SSA form this is not valid for registers that are instances of SSARegister.
*/
public int nonSSAId() {
//assert frameSlot >= 0; // assert inteferes with verbose display
return frameSlot;
}
public void updateSlot(int slot) {
this.frameSlot = slot;
}
public int frameSlot() { return frameSlot; }

/**
* An SSA Register retains a reference to the original
Expand All @@ -106,4 +108,6 @@ public int nonSSAId() {
return originalRegNumber;
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public int numRegisters() {
}
public void toStr(StringBuilder sb) {
for (Register reg : registers) {
sb.append("Reg #").append(reg.id).append(" ").append(reg.name()).append("\n");
sb.append("Reg #").append(reg.id).append(" ").append(reg.name()).append(" ").append(reg.nonSSAId()).append("\n");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,16 @@ private static void recordUses(CompiledFunction function, Map<Register, SSADef>

private static void recordUses(Map<Register, SSADef> defUseChains, Register[] inputs, BasicBlock block, Instruction instruction) {
for (Register register : inputs) {
SSADef def = defUseChains.get(register);
def.useList.add(instruction);
recordUse(defUseChains, instruction, register);
}
}

private static void recordDef(Map<Register, SSADef> defUseChains, Register value, Instruction instruction) {
public static void recordUse(Map<Register, SSADef> defUseChains, Instruction instruction, Register register) {
SSADef def = defUseChains.get(register);
def.useList.add(instruction);
}

public static void recordDef(Map<Register, SSADef> defUseChains, Register value, Instruction instruction) {
if (defUseChains.containsKey(value))
throw new CompilerException("Register already defined, invalid multiple definition in SSA");
defUseChains.put(value, new SSADef(instruction));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package com.compilerprogramming.ezlang.compiler;

import org.junit.Test;

import java.util.EnumSet;

public class TestIncrementalSSA {
String compileSrc(String src) {
var compiler = new Compiler();
var typeDict = compiler.compileSrc(src, EnumSet.of(Options.ISSA,Options.DUMP_SSA_IR));
return compiler.dumpIR(typeDict,true);
}

@Test
public void test1() {
String src = """
func foo(d: Int) {
var a = 42;
var b = a;
var c = a + b;
a = c + 23;
c = a + d;
}
""";
String result = compileSrc(src);
System.out.println(result);
}

@Test
public void test2() {
String src = """
func foo(d: Int)->Int {
var a = 42
if (d)
{
a = a + 1
}
else
{
a = a - 1
}
return a
}
""";
String result = compileSrc(src);
System.out.println(result);
}

@Test
public void test3() {
String src = """
func factorial(num: Int)->Int {
var result = 1
while (num > 1)
{
result = result * num
num = num - 1
}
return result
}
""";
String result = compileSrc(src);
System.out.println(result);
}


@Test
public void test4() {
String src = """
func print(a: Int, b: Int, c:Int, d:Int) {}
func example14_66(p: Int, q: Int, r: Int, s: Int, t: Int) {
var i = 1
var j = 1
var k = 1
var l = 1
while (1) {
if (p) {
j = i
if (q) {
l = 2
}
else {
l = 3
}
k = k + 1
}
else {
k = k + 2
}
print(i,j,k,l)
while (1) {
if (r) {
l = l + 4
}
if (!s)
break
}
i = i + 6
if (!t)
break
}
}
""";
String result = compileSrc(src);
System.out.println(result);
}

@Test
public void test5() {
String src = """
func fib(n: Int)->Int {
var i: Int;
var temp: Int;
var f1=1;
var f2=1;
i=n;
while( i>1 ){
temp = f1+f2;
f1=f2;
f2=temp;
i=i-1;
}
return f2;
}
func foo()->Int {
return fib(10);
}
""";
String result = compileSrc(src);
System.out.println(result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ public class TestInterferenceGraph {
private CompiledFunction buildTest1() {
TypeDictionary typeDictionary = new TypeDictionary();
Type.TypeFunction functionType = new Type.TypeFunction("foo");
functionType.addArg(new Symbol.ParameterSymbol("a", typeDictionary.INT));
var argSymbol = new Symbol.ParameterSymbol("a", typeDictionary.INT);
functionType.addArg(argSymbol);
functionType.setReturnType(typeDictionary.INT);
CompiledFunction function = new CompiledFunction(functionType, typeDictionary);
RegisterPool regPool = function.registerPool;
Register a = regPool.newReg("a", typeDictionary.INT);
Register b = regPool.newReg("b", typeDictionary.INT);
Register c = regPool.newReg("c", typeDictionary.INT);
Register d = regPool.newReg("d", typeDictionary.INT);
function.code(new Instruction.ArgInstruction(new Operand.LocalRegisterOperand(a)));
function.code(new Instruction.ArgInstruction(new Operand.LocalRegisterOperand(a, argSymbol)));
function.code(new Instruction.Binary(
"+",
new Operand.RegisterOperand(a),
Expand Down Expand Up @@ -100,6 +101,8 @@ private CompiledFunction buildTest2() {
function.currentBlock,
new Operand.RegisterOperand(a),
b1, b2));
function.currentBlock.addSuccessor(b1);
function.currentBlock.addSuccessor(b2);
function.startBlock(b1);
function.code(new Instruction.Move(
new Operand.ConstantOperand(2, typeDictionary.INT),
Expand Down
Loading