diff --git a/lib/cretonne/src/ir/layout.rs b/lib/cretonne/src/ir/layout.rs index 5c908812cf..b92a6d7336 100644 --- a/lib/cretonne/src/ir/layout.rs +++ b/lib/cretonne/src/ir/layout.rs @@ -788,10 +788,27 @@ pub trait CursorBase { self.set_position(CursorPosition::At(inst)); } + /// Go to the position for inserting instructions at the beginning of `ebb`, + /// which unlike `goto_first_inst` doesn't assume that any instructions have + /// been inserted into `ebb` yet. + fn goto_first_insertion_point(&mut self, ebb: Ebb) { + if let Some(inst) = self.layout().ebbs[ebb].first_inst.expand() { + self.goto_inst(inst); + } else { + self.goto_bottom(ebb); + } + } + /// Go to the first instruction in `ebb`. fn goto_first_inst(&mut self, ebb: Ebb) { let inst = self.layout().ebbs[ebb].first_inst.expect("Empty EBB"); - self.set_position(CursorPosition::At(inst)); + self.goto_inst(inst); + } + + /// Go to the last instruction in `ebb`. + fn goto_last_inst(&mut self, ebb: Ebb) { + let inst = self.layout().ebbs[ebb].last_inst.expect("Empty EBB"); + self.goto_inst(inst); } /// Go to the top of `ebb` which must be inserted into the layout. diff --git a/lib/cretonne/src/legalizer/boundary.rs b/lib/cretonne/src/legalizer/boundary.rs index 2e16627efe..a95ec2cfba 100644 --- a/lib/cretonne/src/legalizer/boundary.rs +++ b/lib/cretonne/src/legalizer/boundary.rs @@ -63,8 +63,7 @@ fn legalize_entry_arguments(func: &mut Function, entry: Ebb) { // We want to insert instructions before the first instruction in the entry block. // If the entry block is empty, append instructions to it instead. let mut pos = Cursor::new(&mut func.layout); - pos.goto_top(entry); - pos.next_inst(); + pos.goto_first_inst(entry); // Keep track of the argument types in the ABI-legalized signature. let abi_types = &func.signature.argument_types; diff --git a/lib/cretonne/src/legalizer/split.rs b/lib/cretonne/src/legalizer/split.rs index b225586842..23c0e02bcd 100644 --- a/lib/cretonne/src/legalizer/split.rs +++ b/lib/cretonne/src/legalizer/split.rs @@ -235,8 +235,7 @@ fn split_value( // // Note that it is safe to move `pos` here since `reuse` was set above, so we don't // need to insert a split instruction before returning. - pos.goto_top(ebb); - pos.next_inst(); + pos.goto_first_inst(ebb); dfg.ins(pos).with_result(value).Binary( concat, split_type, diff --git a/lib/cretonne/src/licm.rs b/lib/cretonne/src/licm.rs index 58ea3733e9..0a739f8f2d 100644 --- a/lib/cretonne/src/licm.rs +++ b/lib/cretonne/src/licm.rs @@ -34,8 +34,7 @@ pub fn do_licm( let pre_header = create_pre_header(loop_analysis.loop_header(lp), func, cfg, domtree); pos = Cursor::new(&mut func.layout); - pos.goto_bottom(pre_header); - pos.prev_inst(); + pos.goto_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). diff --git a/lib/frontend/src/ssa.rs b/lib/frontend/src/ssa.rs index ed2847c93e..73d10e0494 100644 --- a/lib/frontend/src/ssa.rs +++ b/lib/frontend/src/ssa.rs @@ -445,8 +445,7 @@ where layout.append_ebb(dest_ebb) }; let mut cur = Cursor::new(layout); - cur.goto_top(dest_ebb); - cur.next_inst(); + cur.goto_first_insertion_point(dest_ebb); let ty = dfg.value_type(temp_arg_val); let val = if ty.is_int() { dfg.ins(&mut cur).iconst(ty, 0)