62 lines
1.5 KiB
Java
62 lines
1.5 KiB
Java
package cd.ir;
|
|
|
|
import cd.ir.Ast.Expr;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Represents the control flow graph of a single method.
|
|
*/
|
|
public class ControlFlowGraph {
|
|
public BasicBlock start, end;
|
|
public final List<BasicBlock> allBlocks = new ArrayList<BasicBlock>();
|
|
|
|
public int count() {
|
|
return allBlocks.size();
|
|
}
|
|
|
|
public BasicBlock newBlock() {
|
|
BasicBlock blk = new BasicBlock(count());
|
|
allBlocks.add(blk);
|
|
return blk;
|
|
}
|
|
|
|
/**
|
|
* Given a list of basic blocks that do not yet have successors,
|
|
* merges their control flows into a single successor and returns
|
|
* the new successor.
|
|
*/
|
|
public BasicBlock join(BasicBlock... pred) {
|
|
BasicBlock result = newBlock();
|
|
for (BasicBlock p : pred) {
|
|
assert p.condition == null;
|
|
assert p.successors.size() == 0;
|
|
p.successors.add(result);
|
|
result.predecessors.add(p);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Terminates {@code blk} so that it evaluates {@code cond},
|
|
* and creates two new basic blocks, one for the case where
|
|
* the result is true, and one for the case where the result is
|
|
* false.
|
|
*/
|
|
public void terminateInCondition(BasicBlock blk, Expr cond) {
|
|
assert blk.condition == null;
|
|
assert blk.successors.size() == 0;
|
|
blk.condition = cond;
|
|
blk.successors.add(newBlock());
|
|
blk.successors.add(newBlock());
|
|
blk.trueSuccessor().predecessors.add(blk);
|
|
blk.falseSuccessor().predecessors.add(blk);
|
|
}
|
|
|
|
public void connect(BasicBlock from, BasicBlock to) {
|
|
to.predecessors.add(from);
|
|
from.successors.add(to);
|
|
}
|
|
}
|