Skip to content

Commit

Permalink
1. Caching edge links during CFG construction to avoid duplicate edge…
Browse files Browse the repository at this point in the history
…s between the same blocks.

2. Constructing the CFG from the LinearIRBuilder blocks instead of the full program. This allows finer grained CFG construction.

3. Adding a helper method to LinearIRBlock to return jump entry blocks for conditional and unconditional jumps.

4. Updating the CFG visualization to reflect the code logic of control flow.
  • Loading branch information
whtoo committed Nov 23, 2023
1 parent 72bd985 commit 8d0ff96
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 44 deletions.
33 changes: 17 additions & 16 deletions ep18/src/main/resources/t.vm
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,43 @@
load 0
iconst 1
isub
br L2
L2:
br L1
L1:
ret
.def main: args=0 ,locals=1
iconst 10
store 0
br L5
L5:
br L4
L4:
load 0
iconst 0
igt
brf L7
L6:
brf L6
L5:
load 0
iconst 5
igt
brf L9
L8:
brf L8
L7:
load 0
print
load 0
iconst 7
ieq
brf L9
L10:
iconst 7
br L4
brf L10
L9:
iconst 7
br L3
L10:
L8:
sconst "break"
print
load 0
call dec1()
store 0
br L5
L7:
iconst 0
br L4
L4:
L6:
iconst 0
br L3
L3:
halt
4 changes: 2 additions & 2 deletions ep20/src/main/java/org/teachfx/antlr4/ep20/Compiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ public static void main(String[] args) throws IOException {

astRoot.accept(irBuilder);

var cfg = irBuilder.getCFG();
var cfg = irBuilder.getCFG(irBuilder.prog.blockList);
logger.info("CFG:\n" + cfg.toString());

var assembler = new CymbolAssembler();
irBuilder.prog.accept(assembler);
// saveToEp18Res(assembler.getAsmInfo());
saveToEp18Res(assembler.getAsmInfo());
logger.info("\n%s".formatted(assembler.getAsmInfo()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import org.apache.commons.lang3.tuple.Pair;
import org.teachfx.antlr4.ep20.ir.IRNode;

import java.util.ArrayList;
import java.util.List;
import java.util.*;

public class CFGBuilder {
private CFG<IRNode> cfg;
Expand All @@ -19,10 +18,26 @@ public CFGBuilder(List<LinearIRBlock> blockList){
cfg = new CFG<>(basicBlocks, edges);
}

private static final Set<String> cachedEdgeLinks = new HashSet<>();

private void build(LinearIRBlock block){

basicBlocks.add(BasicBlock.buildFromLinearBlock(block));
block.getJumpEntries().ifPresent(entries -> {
for(var dest : entries){
var key = "%d-%d".formatted(block.getOrd(), dest);
if (!cachedEdgeLinks.contains(key)) {
edges.add(Pair.of(block.getOrd(), dest));
cachedEdgeLinks.add("%d-%d".formatted(block.getOrd(), dest));
}
}
});
for(var successor : block.getSuccessors()){
edges.add(Pair.of(block.getOrd(), successor.getOrd()));
var key = "%d-%d".formatted(block.getOrd(), successor.getOrd());
if (!cachedEdgeLinks.contains(key)) {
cachedEdgeLinks.add(key);
edges.add(Pair.of(block.getOrd(), successor.getOrd()));
}
build(successor);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
import org.teachfx.antlr4.ep20.symtab.scope.Scope;
import org.teachfx.antlr4.ep20.utils.Kind;

import java.util.ArrayList;
import java.util.List;
import java.util.*;

public class LinearIRBlock {

Expand Down Expand Up @@ -153,5 +152,27 @@ public Label getLabel() {
return new Label(toString(),scope);
}

public Optional<TreeSet<Integer>> getJumpEntries() {
var entries = new TreeSet<Integer>();
switch (kind) {
case END_BY_CJMP -> {
CJMP cjmp = (CJMP) getStmts().getLast();
var tid = cjmp.getThenBlock().getOrd();
var eid = cjmp.getElseBlock().getOrd();
entries.add(tid);
entries.add(eid);
return Optional.of(entries);
}
case END_BY_JMP -> {
JMP cjmp = (JMP) getStmts().getLast();
var tid = cjmp.next.getOrd();
entries.add(tid);
return Optional.of(entries);
}
default -> {
return Optional.empty();
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.teachfx.antlr4.ep20.symtab.symbol.MethodSymbol;
import org.teachfx.antlr4.ep20.symtab.symbol.VariableSymbol;

import java.util.List;
import java.util.Optional;
import java.util.Stack;

Expand Down Expand Up @@ -421,12 +422,12 @@ protected VarSlot peekEvalOperand() {
return evalExprStack.peek();
}

public CFG<IRNode> getCFG() {
for (var func : prog.blockList){
public CFG<IRNode> getCFG(List<LinearIRBlock> blocks) {
for (var func : blocks){
insertBlockLabel(func);
}

var cfgBuilder = new CFGBuilder(prog.blockList);
var cfgBuilder = new CFGBuilder(blocks);
return cfgBuilder.getCFG();
}

Expand Down
89 changes: 71 additions & 18 deletions ep21/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,75 @@ graph LR
## DONE

```mermaid
graph TD;
A[基本块1] --> B[基本块2]
B --> C[基本块3]
C -->|条件跳转| D[基本块6]
C -->|否则| E[基本块4]
E -->|条件跳转| F[基本块7]
F --> B
E -->|否则| G[基本块5]
G -->|条件跳转| F
G -->|否则| H[基本块8]
H --> I[基本块9]
D --> I
subgraph dec1
A
end
subgraph main
B --> C --> D --> E --> F --> G --> H --> I
end
graph TD
subgraph L0
Q0["t0 = @0;"]
Q1["t1 = 1 ;"]
Q2["t0 SUB t1;"]
Q3["jmp L1;"]
end
subgraph L1
Q4["ret;"]
end
subgraph L2
Q5["t0 = 10 ;"]
Q6["@0 = t0;"]
Q7["jmp L4;"]
end
subgraph L4
Q8["t0 = @0;"]
Q9["t1 = 0 ;"]
Q10["t0 GT t1;"]
Q11["jmpIf t0,L5,L6;"]
end
subgraph L5
Q12["t0 = @0;"]
Q13["t1 = 5 ;"]
Q14["t0 GT t1;"]
Q15["jmpIf t0,L7,L8;"]
end
subgraph L7
Q16["t0 = @0;"]
Q17["call print(args:1);"]
Q18["t0 = @0;"]
Q19["t1 = 7 ;"]
Q20["t0 EQ t1;"]
Q21["jmpIf t0,L9,L10;"]
end
subgraph L9
Q22["t0 = 7 ;"]
Q23["jmp L3;"]
end
subgraph L10
end
subgraph L8
Q24["t0 = 'break' ;"]
Q25["call print(args:1);"]
Q26["t0 = @0;"]
Q27["call dec1(args:1);"]
Q28["@0 = t0;"]
Q29["jmp L4;"]
end
subgraph L6
Q30["t0 = 0 ;"]
Q31["jmp L3;"]
end
subgraph L3
Q32["halt;"]
end
L0 --> L1
L2 --> L4
L4 --> L5
L4 --> L6
L5 --> L7
L5 --> L8
L7 --> L9
L7 --> L10
L9 --> L3
L9 --> L10
L10 --> L8
L8 --> L4
L8 --> L6
L6 --> L3
```

0 comments on commit 8d0ff96

Please sign in to comment.