diff --git a/lib/cretonne/src/flowgraph.rs b/lib/cretonne/src/flowgraph.rs index d246a1fa3a..d4ec4ca717 100644 --- a/lib/cretonne/src/flowgraph.rs +++ b/lib/cretonne/src/flowgraph.rs @@ -152,7 +152,8 @@ impl ControlFlowGraph { #[cfg(test)] mod tests { use super::*; - use ir::{Function, InstBuilder, Cursor, CursorBase, types}; + use cursor::{Cursor, FuncCursor}; + use ir::{Function, InstBuilder, types}; #[test] fn empty() { @@ -194,16 +195,15 @@ mod tests { let jmp_ebb1_ebb2; { - let dfg = &mut func.dfg; - let cur = &mut Cursor::new(&mut func.layout); + let cur = &mut FuncCursor::new(&mut func); cur.insert_ebb(ebb0); - br_ebb0_ebb2 = dfg.ins(cur).brnz(cond, ebb2, &[]); - jmp_ebb0_ebb1 = dfg.ins(cur).jump(ebb1, &[]); + br_ebb0_ebb2 = cur.ins().brnz(cond, ebb2, &[]); + jmp_ebb0_ebb1 = cur.ins().jump(ebb1, &[]); cur.insert_ebb(ebb1); - br_ebb1_ebb1 = dfg.ins(cur).brnz(cond, ebb1, &[]); - jmp_ebb1_ebb2 = dfg.ins(cur).jump(ebb2, &[]); + br_ebb1_ebb1 = cur.ins().brnz(cond, ebb1, &[]); + jmp_ebb1_ebb2 = cur.ins().jump(ebb2, &[]); cur.insert_ebb(ebb2); } diff --git a/lib/cretonne/src/licm.rs b/lib/cretonne/src/licm.rs index c7b4ff72f6..490e0d8335 100644 --- a/lib/cretonne/src/licm.rs +++ b/lib/cretonne/src/licm.rs @@ -1,6 +1,7 @@ //! A Loop Invariant Code Motion optimization pass -use ir::{Function, Ebb, Inst, Value, Cursor, CursorBase, Type, InstBuilder, Layout}; +use cursor::{Cursor, FuncCursor}; +use ir::{Function, Ebb, Inst, Value, Type, InstBuilder, Layout}; use flowgraph::ControlFlowGraph; use std::collections::HashSet; use dominator_tree::DominatorTree; @@ -33,12 +34,12 @@ pub fn do_licm( None => { let pre_header = create_pre_header(loop_analysis.loop_header(lp), func, cfg, domtree); - pos = Cursor::new(&mut func.layout).at_last_inst(pre_header); + pos = FuncCursor::new(func).at_last_inst(pre_header); } // If there is a natural pre-header we insert new instructions just before the // related jumping instruction (which is not necessarily at the end). Some((_, last_inst)) => { - pos = Cursor::new(&mut func.layout).at_inst(last_inst); + pos = FuncCursor::new(func).at_inst(last_inst); } }; // The last instruction of the pre-header is the termination instruction (usually @@ -80,14 +81,11 @@ fn create_pre_header( } } { - let mut pos = Cursor::new(&mut func.layout).at_top(header); + let mut pos = FuncCursor::new(func).at_top(header); // Inserts the pre-header at the right place in the layout. pos.insert_ebb(pre_header); pos.next_inst(); - func.dfg.ins(&mut pos).jump( - header, - pre_header_args_value.as_slice(pool), - ); + pos.ins().jump(header, pre_header_args_value.as_slice(pool)); } pre_header } @@ -141,17 +139,17 @@ fn remove_loop_invariant_instructions( ) -> Vec { let mut loop_values: HashSet = HashSet::new(); let mut invariant_inst: Vec = Vec::new(); - let mut pos = Cursor::new(&mut func.layout); + let mut pos = FuncCursor::new(func); // We traverse the loop EBB in reverse post-order. for ebb in postorder_ebbs_loop(loop_analysis, cfg, lp).iter().rev() { // Arguments of the EBB are loop values - for val in func.dfg.ebb_args(*ebb) { + for val in pos.func.dfg.ebb_args(*ebb) { loop_values.insert(*val); } pos.goto_top(*ebb); while let Some(inst) = pos.next_inst() { - if func.dfg.has_results(inst) && - func.dfg.inst_args(inst).into_iter().all(|arg| { + if pos.func.dfg.has_results(inst) && + pos.func.dfg.inst_args(inst).into_iter().all(|arg| { !loop_values.contains(arg) }) { @@ -163,7 +161,7 @@ fn remove_loop_invariant_instructions( } else { // If the instruction is not loop-invariant we push its results in the set of // loop values - for out in func.dfg.inst_results(inst) { + for out in pos.func.dfg.inst_results(inst) { loop_values.insert(*out); } } diff --git a/lib/cretonne/src/simple_gvn.rs b/lib/cretonne/src/simple_gvn.rs index c50f70a3fa..b59f6bafd8 100644 --- a/lib/cretonne/src/simple_gvn.rs +++ b/lib/cretonne/src/simple_gvn.rs @@ -1,8 +1,9 @@ //! A simple GVN pass. +use cursor::{Cursor, FuncCursor}; use flowgraph::ControlFlowGraph; use dominator_tree::DominatorTree; -use ir::{Cursor, CursorBase, InstructionData, Function, Inst, Opcode, Type}; +use ir::{InstructionData, Function, Inst, Opcode, Type}; use scoped_hash_map::ScopedHashMap; /// Test whether the given opcode is unsafe to even consider for GVN. @@ -22,13 +23,13 @@ pub fn do_simple_gvn(func: &mut Function, cfg: &mut ControlFlowGraph, domtree: & let mut scope_stack: Vec = Vec::new(); // Visit EBBs in a reverse post-order. - let mut pos = Cursor::new(&mut func.layout); + let mut pos = FuncCursor::new(func); for &ebb in domtree.cfg_postorder().iter().rev() { // Pop any scopes that we just exited. loop { if let Some(current) = scope_stack.last() { - if domtree.dominates(*current, ebb, &pos.layout) { + if domtree.dominates(*current, ebb, &pos.func.layout) { break; } } else { @@ -39,38 +40,38 @@ pub fn do_simple_gvn(func: &mut Function, cfg: &mut ControlFlowGraph, domtree: & } // Push a scope for the current block. - scope_stack.push(pos.layout.first_inst(ebb).unwrap()); + scope_stack.push(pos.func.layout.first_inst(ebb).unwrap()); visible_values.increment_depth(); pos.goto_top(ebb); while let Some(inst) = pos.next_inst() { // Resolve aliases, particularly aliases we created earlier. - func.dfg.resolve_aliases_in_arguments(inst); + pos.func.dfg.resolve_aliases_in_arguments(inst); - let opcode = func.dfg[inst].opcode(); + let opcode = pos.func.dfg[inst].opcode(); if opcode.is_branch() && !opcode.is_terminator() { - scope_stack.push(pos.layout.next_inst(inst).unwrap()); + scope_stack.push(pos.func.layout.next_inst(inst).unwrap()); visible_values.increment_depth(); } if trivially_unsafe_for_gvn(opcode) { continue; } - let ctrl_typevar = func.dfg.ctrl_typevar(inst); - let key = (func.dfg[inst].clone(), ctrl_typevar); + let ctrl_typevar = pos.func.dfg.ctrl_typevar(inst); + let key = (pos.func.dfg[inst].clone(), ctrl_typevar); let entry = visible_values.entry(key); use scoped_hash_map::Entry::*; match entry { Occupied(entry) => { - debug_assert!(domtree.dominates(*entry.get(), inst, pos.layout)); + debug_assert!(domtree.dominates(*entry.get(), inst, &pos.func.layout)); // If the redundant instruction is representing the current // scope, pick a new representative. let old = scope_stack.last_mut().unwrap(); if *old == inst { - *old = pos.layout.next_inst(inst).unwrap(); + *old = pos.func.layout.next_inst(inst).unwrap(); } // Replace the redundant instruction and remove it. - func.dfg.replace_with_aliases(inst, *entry.get()); + pos.func.dfg.replace_with_aliases(inst, *entry.get()); pos.remove_inst_and_step_back(); } Vacant(entry) => {