Avoid the CFG get_successors() when computing a post-order.

The control flow graph does not guarantee any particular ordering for
its successor lists, and the post-order we are computing for building
the dominator tree needs to be "split-invariant".

See #146 for details.

- Discover EBB successors directly from the EBB instruction sequence to
  guarantee that the post-order we compute is canonical/split-invariant.
- Use an alternative graph DFS algorithm which doesn't require indexing
  into a slice of successors.

This changes cfg_postorder in some cases because the edge pruning when
converting the (DAG) CFG to a tree for the DFT is different.
This commit is contained in:
Jakob Stoklund Olesen
2017-11-21 09:45:52 -08:00
parent 2e0b931590
commit cf45afa1e7
3 changed files with 206 additions and 31 deletions

View File

@@ -326,16 +326,16 @@ mod test {
let loops = loop_analysis.loops().collect::<Vec<Loop>>();
assert_eq!(loops.len(), 3);
assert_eq!(loop_analysis.loop_header(loops[0]), ebb0);
assert_eq!(loop_analysis.loop_header(loops[1]), ebb3);
assert_eq!(loop_analysis.loop_header(loops[2]), ebb1);
assert_eq!(loop_analysis.loop_header(loops[1]), ebb1);
assert_eq!(loop_analysis.loop_header(loops[2]), ebb3);
assert_eq!(loop_analysis.loop_parent(loops[1]), Some(loops[0]));
assert_eq!(loop_analysis.loop_parent(loops[2]), Some(loops[0]));
assert_eq!(loop_analysis.loop_parent(loops[0]), None);
assert_eq!(loop_analysis.is_in_loop(ebb0, loops[0]), true);
assert_eq!(loop_analysis.is_in_loop(ebb3, loops[1]), true);
assert_eq!(loop_analysis.is_in_loop(ebb4, loops[1]), true);
assert_eq!(loop_analysis.is_in_loop(ebb1, loops[2]), true);
assert_eq!(loop_analysis.is_in_loop(ebb2, loops[2]), true);
assert_eq!(loop_analysis.is_in_loop(ebb1, loops[1]), true);
assert_eq!(loop_analysis.is_in_loop(ebb2, loops[1]), true);
assert_eq!(loop_analysis.is_in_loop(ebb3, loops[2]), true);
assert_eq!(loop_analysis.is_in_loop(ebb4, loops[2]), true);
assert_eq!(loop_analysis.is_in_loop(ebb5, loops[0]), true);
}
}