Clean up the CFG representation.

This commit is contained in:
Morgan Phillips
2016-07-31 21:31:18 -07:00
parent dae349371f
commit a8beb542a5
2 changed files with 15 additions and 30 deletions

View File

@@ -26,13 +26,13 @@ use ir::Function;
use ir::entities::{Inst, Ebb};
use ir::instructions::BranchInfo;
use entity_map::EntityMap;
use std::collections::{HashSet, BTreeMap};
use std::collections::HashSet;
/// A basic block denoted by its enclosing Ebb and last instruction.
pub type BasicBlock = (Ebb, Inst);
/// A container for the successors and predecessors of some Ebb.
#[derive(Debug)]
#[derive(Debug, Clone, Default)]
pub struct CFGNode {
pub successors: Vec<Ebb>,
pub predecessors: Vec<BasicBlock>,
@@ -62,27 +62,19 @@ impl ControlFlowGraph {
pub fn new(func: &Function) -> ControlFlowGraph {
let mut cfg = ControlFlowGraph {
data: EntityMap::new(),
data: EntityMap::with_capacity(func.dfg.num_ebbs()),
entry_block: func.layout.entry_block(),
};
// Even ebbs without predecessors should show up in the CFG, albeit
// with no entires.
for _ in &func.layout {
cfg.push_ebb();
}
for ebb in &func.layout {
for inst in func.layout.ebb_insts(ebb) {
match func.dfg[inst].analyze_branch() {
BranchInfo::SingleDest(dest, _) => {
cfg.add_successor(ebb, dest);
cfg.add_predecessor(dest, (ebb, inst));
cfg.add_edge((ebb, inst), dest);
}
BranchInfo::Table(jt) => {
for (_, dest) in func.jump_tables[jt].entries() {
cfg.add_successor(ebb, dest);
cfg.add_predecessor(dest, (ebb, inst));
cfg.add_edge((ebb, inst), dest);
}
}
BranchInfo::NotABranch => {}
@@ -92,19 +84,12 @@ impl ControlFlowGraph {
cfg
}
pub fn push_ebb(&mut self) {
self.data.push(CFGNode::new());
fn add_edge(&mut self, from: BasicBlock, to: Ebb) {
self.data[from.0].successors.push(to);
self.data[to].predecessors.push(from);
}
pub fn add_successor(&mut self, from: Ebb, to: Ebb) {
self.data[from].successors.push(to);
}
pub fn add_predecessor(&mut self, ebb: Ebb, predecessor: BasicBlock) {
self.data[ebb].predecessors.push(predecessor);
}
pub fn get_predecessors(&self, ebb: Ebb) -> &Vec<BasicBlock> {
fn get_predecessors(&self, ebb: Ebb) -> &Vec<BasicBlock> {
&self.data[ebb].predecessors
}
@@ -114,10 +99,10 @@ impl ControlFlowGraph {
/// Return ebbs in reverse postorder along with a mapping of
/// the ebb to its [post]order of visitation.
pub fn reverse_postorder_ebbs(&self) -> BTreeMap<Ebb, usize> {
pub fn reverse_postorder_ebbs(&self) -> EntityMap<Ebb, usize> {
let entry_block = match self.entry_block {
None => {
return BTreeMap::new();
return EntityMap::new();
}
Some(eb) => eb,
};
@@ -146,10 +131,10 @@ impl ControlFlowGraph {
}
postorder.reverse();
let mut result = BTreeMap::new();
let mut result = EntityMap::with_capacity(postorder.len());
for (offset, ebb) in postorder.iter().enumerate() {
let i = postorder.len() - offset;
result.insert(ebb.clone(), i);
result[ebb.clone()] = i;
}
result
}

View File

@@ -14,8 +14,8 @@ fn test_reverse_postorder_traversal(function_source: &str, ebb_order: Vec<u32>)
let reverse_postorder_ebbs = cfg.reverse_postorder_ebbs();
assert_eq!(reverse_postorder_ebbs.len(), ebbs.len());
for (ebb, key) in reverse_postorder_ebbs {
assert_eq!(ebb, ebbs[ebbs.len() - key]);
for ebb in reverse_postorder_ebbs.keys() {
assert_eq!(ebb, ebbs[ebbs.len() - reverse_postorder_ebbs[ebb]]);
}
}