LICM pass (#87)

* LICM pass

* Uses loop analysis to detect loop tree
* For each loop (starting with the inner ones), create a pre-header and move there loop-invariant instructions
* An instruction is loop invariant if it does not use as argument a value defined earlier in the loop
* File tests to check LICM's correctness
* Optimized pre-header creation
If the loop already has a natural pre-header, we use it instead of creating a new one.
The natural pre-header of a loop is the only predecessor of the header it doesn't dominate.
This commit is contained in:
Denis Merigoux
2017-06-07 11:27:22 -07:00
committed by Jakob Stoklund Olesen
parent 402cb8e1f6
commit e47f4a49fb
10 changed files with 487 additions and 5 deletions

View File

@@ -129,13 +129,13 @@ impl LoopAnalysis {
domtree: &DominatorTree,
layout: &Layout) {
// We traverse the CFg in reverse postorder
for ebb in cfg.postorder_ebbs().iter().rev() {
for &(_, pred_inst) in cfg.get_predecessors(*ebb) {
for &ebb in cfg.postorder_ebbs().iter().rev() {
for &(_, pred_inst) in cfg.get_predecessors(ebb) {
// If the ebb dominates one of its predecessors it is a back edge
if domtree.ebb_dominates(ebb.clone(), pred_inst, layout) {
if domtree.ebb_dominates(ebb, pred_inst, layout) {
// This ebb is a loop header, so we create its associated loop
let lp = self.loops.push(LoopData::new(*ebb, None));
self.ebb_loop_map[*ebb] = lp.into();
let lp = self.loops.push(LoopData::new(ebb, None));
self.ebb_loop_map[ebb] = lp.into();
break;
// We break because we only need one back edge to identify a loop header.
}