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 @@ -164,6 +164,28 @@ public static StringBuilder toStr(StringBuilder sb, BasicBlock bb, BitSet visite
}
return sb;
}
private String escapeHtmlChars(String s) {
if (s.contains(">"))
s = s.replaceAll(">", " > ");
if (s.contains(">="))
s = s.replaceAll(">=", " ≥ ");
if (s.contains("<"))
s = s.replaceAll("<", " &lt; ");
if (s.contains("<="))
s = s.replaceAll("<=", " &le; ");
return s;
}
public StringBuilder toDot(StringBuilder sb, boolean verbose) {
sb.append("<TABLE BORDER=\"1\" CELLBORDER=\"0\">\n");
sb.append("<TR><TD><B>L").append(bid).append("</B></TD></TR>\n");
for (Instruction i: instructions) {
sb.append("<TR><TD>");
sb.append(escapeHtmlChars(i.toStr(new StringBuilder()).toString()));
sb.append("</TD></TR>\n");
}
sb.append("</TABLE>");
return sb;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class CompiledFunction {

public BasicBlock entry;
public BasicBlock exit;
private int bid = 0;
private int BID = 0;
public BasicBlock currentBlock;
private BasicBlock currentBreakTarget;
private BasicBlock currentContinueTarget;
Expand All @@ -41,7 +41,7 @@ public CompiledFunction(Symbol.FunctionTypeSymbol functionSymbol) {
this.functionType = (Type.TypeFunction) functionSymbol.type;
this.registerPool = new RegisterPool();
setVirtualRegisters(funcDecl.scope);
this.bid = 0;
this.BID = 0;
this.entry = this.currentBlock = createBlock();
this.exit = createBlock();
this.currentBreakTarget = null;
Expand All @@ -55,7 +55,7 @@ public CompiledFunction(Symbol.FunctionTypeSymbol functionSymbol) {
public CompiledFunction(Type.TypeFunction functionType) {
this.functionType = (Type.TypeFunction) functionType;
this.registerPool = new RegisterPool();
this.bid = 0;
this.BID = 0;
this.entry = this.currentBlock = createBlock();
this.exit = createBlock();
this.currentBreakTarget = null;
Expand Down Expand Up @@ -99,11 +99,11 @@ private void setVirtualRegisters(Scope scope) {
}

public BasicBlock createBlock() {
return new BasicBlock(bid++);
return new BasicBlock(BID++);
}

private BasicBlock createLoopHead() {
return new BasicBlock(bid++, true);
return new BasicBlock(BID++, true);
}

private void compileBlock(AST.BlockStmt block) {
Expand Down Expand Up @@ -574,4 +574,19 @@ public void livenessAnalysis() {
public List<BasicBlock> getBlocks() {
return BBHelper.findAllBlocks(entry);
}

public StringBuilder toDot(StringBuilder sb, boolean verbose) {
sb.append("digraph CompiledFunction {\n");
List<BasicBlock> blocks = getBlocks();
for (BasicBlock block: blocks) {
sb.append("L").append(block.bid).append(" [shape=none, margin=0, label=<");
block.toDot(sb, verbose);
sb.append(">];\n");
for (BasicBlock s: block.successors) {
sb.append("L").append(block.bid).append(" -> ").append("L").append(s.bid).append("\n");
}
}
sb.append("}\n");
return sb;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,6 @@ public SparseConditionalConstantPropagation constantPropagation(CompiledFunction
return this;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Flow edges:\n");
for (var edge : flowEdges.keySet()) {
if (flowEdges.get(edge)) {
sb.append(edge).append("=Executable").append("\n");
}
}
sb.append("Lattices:\n");
for (var register: valueLattice.getRegisters()) {
sb.append(register.name()).append("=").append(valueLattice.get(register)).append("\n");
}
return sb.toString();
}

private void visitBlock(BasicBlock b) {
for (var phi : b.phis()) {
visitInstruction(phi);
Expand Down Expand Up @@ -109,7 +93,10 @@ private void visitInstruction(Instruction instruction) {
SSAEdges.SSADef ssaDef = ssaEdges.get(def);
if (ssaDef != null) {
for (Instruction use : ssaDef.useList) {
instructionWorkList.push(use);
if (visited.get(use.block.bid))
// Don't visit the instruction if block hasn't been
// visited
instructionWorkList.push(use);
}
}
}
Expand Down Expand Up @@ -457,6 +444,25 @@ private static boolean evalArith(LatticeElement cell, LatticeElement left, Latti
return changed;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Flow edges:\n");
for (var edge : flowEdges.keySet()) {
if (flowEdges.get(edge)) {
sb.append(edge).append("=Executable").append("\n");
}
else {
sb.append(edge).append("=NOT Executable").append("\n");
}
}
sb.append("Lattices:\n");
for (var register: valueLattice.getRegisters()) {
sb.append(register.name()).append("=").append(valueLattice.get(register)).append("\n");
}
return sb.toString();
}

/**
* Maintains a Lattice for each SSA variable - i.e register
* Initial value of lattice is TOP/Undefined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ String compileSrc(String src) {
var functionBuilder = (CompiledFunction) f.code();
new EnterSSA(functionBuilder);
BasicBlock.toStr(sb, functionBuilder.entry, new BitSet(), false);
//functionBuilder.toDot(sb, false);
sb.append(new SparseConditionalConstantPropagation().constantPropagation(functionBuilder).toString());
}
}
Expand Down Expand Up @@ -53,14 +54,98 @@ func foo()->Int {
i_1 = 3
goto L4
Flow edges:
L0->L2=NOT Executable
L0->L3=Executable
L4->L1=Executable
L2->L4=NOT Executable
L3->L4=Executable
Lattices:
i_0=1
%t1_0=0
i_1=3
i_3=3
""";
Assert.assertEquals(expected, actual);
}

// 19.4 in MCIC Appel
// Expected results are based on fig 19.13 page 456
@Test
public void test2() {
String src = """
func foo()->Int {
var i = 1
var j = 1
var k = 0
while (k < 100) {
if (j < 20) {
j = i
k = k + 1
}
else {
j = k
k = k + 2
}
}
return j
}
""";
String actual = compileSrc(src);
String expected = """
L0:
i_0 = 1
j_0 = 1
k_0 = 0
goto L2
L2:
k_1 = phi(k_0, k_4)
j_1 = phi(j_0, j_4)
%t3_0 = k_1<100
if %t3_0 goto L3 else goto L4
L3:
%t4_0 = j_1<20
if %t4_0 goto L5 else goto L6
L5:
j_3 = i_0
%t5_0 = k_1+1
k_3 = %t5_0
goto L7
L7:
k_4 = phi(k_3, k_2)
j_4 = phi(j_3, j_2)
goto L2
L6:
j_2 = k_1
%t6_0 = k_1+2
k_2 = %t6_0
goto L7
L4:
ret j_1
goto L1
L1:
Flow edges:
L0->L2=Executable
L4->L1=Executable
L2->L3=Executable
L2->L4=Executable
L3->L5=Executable
L7->L2=Executable
L3->L6=NOT Executable
L5->L7=Executable
L6->L7=NOT Executable
Lattices:
j_3=1
%t5_0=varying
k_3=varying
k_4=varying
j_4=1
i_0=1
j_0=1
k_0=0
k_1=varying
j_1=1
%t3_0=varying
%t4_0=1
""";
Assert.assertEquals(expected, actual);
}
Expand Down
Loading