sp-04/src/ch/usi/inf/sp/cfg/ControlFlowGraph.java

111 lines
3.5 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;
}
public String toString() {
final StringBuffer sb = new StringBuffer("digraph CFG {\n");
for (final BasicBlock node : getNodes()) {
if (node==entry) {
sb.append(" " + node + " [shape=circle,style=filled,label=e]\n");
} else if (node==exit) {
sb.append(" " + node + " [shape=circle,style=filled,label=x]\n");
} else {
sb.append(" " + node + " [shape=rectangle]\n");
}
}
for (final ControlFlowEdge edge : getEdges()) {
if (edge.getLabel().length()>0) {
sb.append(" " + edge + " [label=" + edge.getLabel() + "]\n");
} else {
sb.append(" " + edge + "\n");
}
}
sb.append("}\n");
return sb.toString();
}
}