From 7aef6bd535eee62d7a1c827e4476f3cd04e2c0bd Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 14 Oct 2016 14:01:49 -0700 Subject: [PATCH] Add Cursor::insert_ebb() method. Insert an EBB at the current position and switch to inserting instructions there. Call the relevant Layout methods to do so. --- cranelift/src/libcretonne/ir/layout.rs | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/cranelift/src/libcretonne/ir/layout.rs b/cranelift/src/libcretonne/ir/layout.rs index b1263a5b47..c6543a88e0 100644 --- a/cranelift/src/libcretonne/ir/layout.rs +++ b/cranelift/src/libcretonne/ir/layout.rs @@ -614,6 +614,36 @@ impl<'a> Cursor<'a> { After(ebb) => self.layout.append_inst(inst, ebb), } } + + /// Insert an EBB at the current position and switch to it. + /// + /// As far as possible, this method behaves as if the EBB header were an instruction inserted + /// at the current position. + /// + /// - If the cursor is pointing at an existing instruction, *the current EBB is split in two* + /// and the current instruction becomes the first instruction in the inserted EBB. + /// - If the cursor points at the bottom of an EBB, the new EBB is inserted after the current + /// one, and moved to the bottom of the new EBB where instructions can be appended. + /// - If the cursor points to the top of an EBB, the new EBB is inserted above the current one. + /// - If the cursor is not pointing at anything, the new EBB is placed last in the layout. + /// + /// This means that is is always valid to call this method, and it always leaves the cursor in + /// a state that will insert instructions into the new EBB. + pub fn insert_ebb(&mut self, new_ebb: Ebb) { + use self::CursorPosition::*; + match self.pos { + At(inst) => { + self.layout.split_ebb(new_ebb, inst); + // All other cases move to `After(ebb)`, but in this case we we'll stay `At(inst)`. + return; + } + Nowhere => self.layout.append_ebb(new_ebb), + Before(ebb) => self.layout.insert_ebb(new_ebb, ebb), + After(ebb) => self.layout.insert_ebb_after(new_ebb, ebb), + } + // For everything but `At(inst)` we end up appending to the new EBB. + self.pos = After(new_ebb); + } }