Add an analyze_branch method to InstructionData.

Rather than switching on instruction formats to discover the destination of a
branch, use the analyze_branch method which returns a BranchInfo enum with just
the relevant information.

This makes CFG algorithms independent of future instruction formats for
branches. Only analyze_branch needs to be updated when adding a new format.
This commit is contained in:
Jakob Stoklund Olesen
2016-07-22 15:38:53 -07:00
parent 20fc675fc0
commit ae98edf8cc
2 changed files with 47 additions and 9 deletions

View File

@@ -24,7 +24,7 @@
use ir::Function;
use ir::entities::{Inst, Ebb};
use ir::instructions::InstructionData;
use ir::instructions::BranchInfo;
use entity_map::EntityMap;
/// A basic block denoted by its enclosing Ebb and last instruction.
@@ -68,16 +68,18 @@ impl ControlFlowGraph {
for ebb in &func.layout {
for inst in func.layout.ebb_insts(ebb) {
match func.dfg[inst] {
InstructionData::Branch { ty: _, opcode: _, ref data } => {
cfg.add_successor(ebb, data.destination);
cfg.add_predecessor(data.destination, (ebb, inst));
match func.dfg[inst].analyze_branch() {
BranchInfo::SingleDest(dest, _) => {
cfg.add_successor(ebb, dest);
cfg.add_predecessor(dest, (ebb, inst));
}
InstructionData::Jump { ty: _, opcode: _, ref data } => {
cfg.add_successor(ebb, data.destination);
cfg.add_predecessor(data.destination, (ebb, inst));
BranchInfo::Table(jt) => {
for (_, dest) in func.jump_tables[jt].entries() {
cfg.add_successor(ebb, dest);
cfg.add_predecessor(dest, (ebb, inst));
}
}
_ => (),
BranchInfo::NotABranch => {}
}
}
}