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 28a5f007c4
commit 8d93fe9685
2 changed files with 47 additions and 9 deletions

View File

@@ -344,6 +344,42 @@ impl InstructionData {
}
}
/// Analyzing an instruction.
///
/// Avoid large matches on instruction formats by using the methods efined here to examine
/// instructions.
impl InstructionData {
/// Return information about the destination of a branch or jump instruction.
///
/// Any instruction that can transfer control to another EBB reveals its possible destinations
/// here.
pub fn analyze_branch<'a>(&'a self) -> BranchInfo<'a> {
match self {
&InstructionData::Jump { ref data, .. } => {
BranchInfo::SingleDest(data.destination, &data.arguments)
}
&InstructionData::Branch { ref data, .. } => {
BranchInfo::SingleDest(data.destination, &data.arguments)
}
&InstructionData::BranchTable { table, .. } => BranchInfo::Table(table),
_ => BranchInfo::NotABranch,
}
}
}
/// Information about branch and jump instructions.
pub enum BranchInfo<'a> {
/// This is not a branch or jump instruction.
/// This instruction will not transfer control to another EBB in the function, but it may still
/// affect control flow by returning or trapping.
NotABranch,
/// This is a branch or jump to a single destination EBB, possibly taking value arguments.
SingleDest(Ebb, &'a [Value]),
/// This is a jump table branch which can have many destination EBBs.
Table(JumpTable),
}
/// Value type constraints for a given opcode.
///