89 lines
2.7 KiB
Java
89 lines
2.7 KiB
Java
package ch.usi.inf.sp.cfg;
|
|
|
|
|
|
import ch.usi.inf.sp.graph.DiGraph;
|
|
|
|
public final class ControlFlowGraph extends DiGraph<BasicBlock, ControlFlowEdge> {
|
|
|
|
private BasicBlock entry;
|
|
private BasicBlock exit;
|
|
|
|
|
|
public ControlFlowGraph() {
|
|
entry = new BasicBlock(-1);
|
|
addNode(entry);
|
|
exit = new BasicBlock(-2);
|
|
addNode(exit);
|
|
}
|
|
|
|
private final void checkContains(BasicBlock block, String name) {
|
|
if (!getNodes().contains(block)) {
|
|
throw new IllegalStateException("Control flow graph does not contain the given " + name + " block.");
|
|
}
|
|
}
|
|
|
|
public ControlFlowEdge addEntryEdge(BasicBlock firstBlock) {
|
|
if (entry.getOutEdges().size() > 0) {
|
|
throw new IllegalStateException("Control flow graph already has an entry edge. It can only have one.");
|
|
}
|
|
checkContains(firstBlock, "firstBlock");
|
|
ControlFlowEdge edge = new ControlFlowEdge("");
|
|
addEdge(edge);
|
|
connect(entry, edge, firstBlock);
|
|
return edge;
|
|
}
|
|
|
|
public ControlFlowEdge addExitEdge(BasicBlock returnBlock) {
|
|
checkContains(returnBlock, "returnBlock");
|
|
ControlFlowEdge edge = new ControlFlowEdge("");
|
|
addEdge(edge);
|
|
connect(returnBlock, edge, exit);
|
|
return edge;
|
|
}
|
|
|
|
public ControlFlowEdge addFallthroughEdge(BasicBlock fromBlock, BasicBlock toBlock) {
|
|
checkContains(fromBlock, "fromBlock");
|
|
checkContains(toBlock, "toBlock");
|
|
ControlFlowEdge edge = new ControlFlowEdge("");
|
|
addEdge(edge);
|
|
connect(fromBlock, edge, toBlock);
|
|
return edge;
|
|
}
|
|
|
|
public ControlFlowEdge addBranchTakenEdge(BasicBlock fromBlock, BasicBlock toBlock) {
|
|
checkContains(fromBlock, "fromBlock");
|
|
checkContains(toBlock, "toBlock");
|
|
ControlFlowEdge edge = new ControlFlowEdge("T");
|
|
addEdge(edge);
|
|
connect(fromBlock, edge, toBlock);
|
|
return edge;
|
|
}
|
|
|
|
public ControlFlowEdge addCaseEdge(BasicBlock fromBlock, BasicBlock toBlock, int key) {
|
|
checkContains(fromBlock, "fromBlock");
|
|
checkContains(toBlock, "toBlock");
|
|
ControlFlowEdge edge = new ControlFlowEdge("" + key);
|
|
addEdge(edge);
|
|
connect(fromBlock, edge, toBlock);
|
|
return edge;
|
|
}
|
|
|
|
public ControlFlowEdge addDefaultEdge(BasicBlock fromBlock, BasicBlock toBlock) {
|
|
checkContains(fromBlock, "fromBlock");
|
|
checkContains(toBlock, "toBlock");
|
|
ControlFlowEdge edge = new ControlFlowEdge("default");
|
|
addEdge(edge);
|
|
connect(fromBlock, edge, toBlock);
|
|
return edge;
|
|
}
|
|
|
|
public BasicBlock getEntry() {
|
|
return entry;
|
|
}
|
|
|
|
public BasicBlock getExit() {
|
|
return exit;
|
|
}
|
|
|
|
}
|