diff --git a/cranelift/codegen/src/regalloc/branch_splitting.rs b/cranelift/codegen/src/regalloc/branch_splitting.rs index e44f452296..a3f118b3d6 100644 --- a/cranelift/codegen/src/regalloc/branch_splitting.rs +++ b/cranelift/codegen/src/regalloc/branch_splitting.rs @@ -22,7 +22,6 @@ pub fn run( ) { let mut ctx = Context { has_new_blocks: false, - has_fallthrough_return: None, cur: EncCursor::new(func, isa), domtree, topo, @@ -35,12 +34,6 @@ struct Context<'a> { /// True if new blocks were inserted. has_new_blocks: bool, - /// Record whether newly inserted empty blocks should be inserted last, or before the last, to - /// avoid disturbing the expected control flow of `fallthroug_return` statements. - /// - /// This value is computed when needed. The Option wraps the computed value if any. - has_fallthrough_return: Option, - /// Current instruction as well as reference to function and ISA. cur: EncCursor<'a>, @@ -89,7 +82,13 @@ impl<'a> Context<'a> { // If there are any parameters, split the edge. if self.should_split_edge(target) { // Create the block the branch will jump to. - let new_ebb = self.make_empty_ebb(); + let new_ebb = self.cur.func.dfg.make_ebb(); + + // Insert the new block before the destination, such that it can fallthrough in the + // target block. + assert_ne!(Some(target), self.cur.layout().entry_block()); + self.cur.layout_mut().insert_ebb(new_ebb, target); + self.has_new_blocks = true; // Extract the arguments of the branch instruction, split the Ebb parameters and the // branch arguments @@ -157,28 +156,6 @@ impl<'a> Context<'a> { } } - // A new ebb must be inserted before the last ebb because the last ebb may have a - // fallthrough_return and can't have anything after it. - fn make_empty_ebb(&mut self) -> Ebb { - let last_ebb = self.cur.layout().last_ebb().unwrap(); - if self.has_fallthrough_return == None { - let last_inst = self.cur.layout().last_inst(last_ebb).unwrap(); - self.has_fallthrough_return = - Some(self.cur.func.dfg[last_inst].opcode() == Opcode::FallthroughReturn); - } - let new_ebb = self.cur.func.dfg.make_ebb(); - if self.has_fallthrough_return == Some(true) { - // Insert before the last block which has a fallthrough_return - // instruction. - self.cur.layout_mut().insert_ebb(new_ebb, last_ebb); - } else { - // Insert after the last block. - self.cur.layout_mut().insert_ebb_after(new_ebb, last_ebb); - } - self.has_new_blocks = true; - new_ebb - } - /// Returns whether we should introduce a new branch. fn should_split_edge(&self, target: Ebb) -> bool { // We should split the edge if the target has any parameters. diff --git a/cranelift/filetests/filetests/regalloc/coalesce-bb.clif b/cranelift/filetests/filetests/regalloc/coalesce-bb.clif index 384ef2ca4c..7718df7d17 100644 --- a/cranelift/filetests/filetests/regalloc/coalesce-bb.clif +++ b/cranelift/filetests/filetests/regalloc/coalesce-bb.clif @@ -103,21 +103,21 @@ ebb0(v0: i32): v2 = iconst.i32 2 jump ebb1(v1, v2) + ; check: $(splitEdge=$EBB): + ; check: $(nv11b=$V) = copy.i32 v11 + ; not: copy + ; check: jump ebb1($nv11b, v12) + ebb1(v10: i32, v11: i32): ; v11 needs to be isolated because it interferes with v10. ; check: ebb1(v10: i32 [$LOC], $(nv11a=$V): i32 [$LOC]) ; check: v11 = copy $nv11a v12 = iadd v10, v11 v13 = icmp ult v12, v0 - ; check: brnz v13, $(splitEdge=$EBB) + ; check: brnz v13, $splitEdge brnz v13, ebb1(v11, v12) jump ebb2 - ; check: $splitEdge: - ; check: $(nv11b=$V) = copy.i32 v11 - ; not: copy - ; check: jump ebb1($nv11b, v12) - ebb2: return v12 } diff --git a/cranelift/filetests/filetests/regalloc/reload-208-bb.clif b/cranelift/filetests/filetests/regalloc/reload-208-bb.clif index 47438d7d61..d77e4d8ebc 100644 --- a/cranelift/filetests/filetests/regalloc/reload-208-bb.clif +++ b/cranelift/filetests/filetests/regalloc/reload-208-bb.clif @@ -44,6 +44,11 @@ ebb5: brnz v6, ebb2 jump ebb3(v4) + ; check: ebb5: + ; check: jump ebb3(v4) + ; check: $(splitEdge=$EBB): + ; nextln: jump ebb3(v9) + ebb3(v7: i32): call fn1(v0, v7) v26 = iconst.i32 0x4ffe @@ -61,13 +66,10 @@ ebb6: v8 = iadd v25, v23 v9 = load.i32 v8+56 ; check: v9 = spill - ; check: brnz $V, $(splitEdge=$EBB) + ; check: brnz $V, $splitEdge brnz v9, ebb3(v9) jump ebb4 - ; check: $splitEdge: - ; nextln: jump ebb3(v9) - ebb4: jump ebb2 diff --git a/cranelift/filetests/filetests/regalloc/x86-regres-bb.clif b/cranelift/filetests/filetests/regalloc/x86-regres-bb.clif index 28eba22a64..060164034a 100644 --- a/cranelift/filetests/filetests/regalloc/x86-regres-bb.clif +++ b/cranelift/filetests/filetests/regalloc/x86-regres-bb.clif @@ -19,6 +19,9 @@ ebb0(v0: i32): v3 = iconst.i32 0 jump ebb2(v3, v2, v0) + ; check: $(splitEdge=$EBB): + ; check: jump ebb2($V, $V, v9) + ebb2(v4: i32, v5: i32, v7: i32): ; check: ebb2 v6 = iadd v4, v5 @@ -33,11 +36,9 @@ ebb2(v4: i32, v5: i32, v7: i32): ; ; We should be able to handle this situation without making copies of v9. brnz v9, ebb2(v5, v6, v9) - ; check: brnz v9, $(splitEdge=$EBB) + ; check: brnz v9, $splitEdge jump ebb3 - ; check: $splitEdge: - ; check: jump ebb2($V, $V, v9) ebb3: return v5 } diff --git a/cranelift/filetests/filetests/safepoint/basic-bb.clif b/cranelift/filetests/filetests/safepoint/basic-bb.clif index b2ccedf559..14a43d09a6 100644 --- a/cranelift/filetests/filetests/safepoint/basic-bb.clif +++ b/cranelift/filetests/filetests/safepoint/basic-bb.clif @@ -32,11 +32,20 @@ function %test(i32, r64, r64) -> r64 { ; nextln: v10 = copy v0 ; nextln: jump ebb1(v10) ; nextln: +; nextln: ebb7: +; nextln: regmove.i32 v5, %rcx -> %rax +; nextln: jump ebb1(v5) +; nextln: ; nextln: ebb1(v3: i32 [%rax]): ; nextln: v8 = iconst.i32 1 ; nextln: v4 = isub v8, v3 ; nextln: jump ebb2(v4) ; nextln: +; nextln: ebb8: +; nextln: v9 = copy.i32 v0 +; nextln: regmove v9, %rax -> %rcx +; nextln: jump ebb2(v9) +; nextln: ; nextln: ebb2(v5: i32 [%rcx]): ; nextln: safepoint v1, v2 ; nextln: resumable_trap interrupt @@ -60,13 +69,4 @@ function %test(i32, r64, r64) -> r64 { ; nextln: ebb6: ; nextln: regmove.r64 v2, %rdx -> %rax ; nextln: return v2 -; nextln: -; nextln: ebb7: -; nextln: regmove.i32 v5, %rcx -> %rax -; nextln: jump ebb1(v5) -; nextln: -; nextln: ebb8: -; nextln: v9 = copy.i32 v0 -; nextln: regmove v9, %rax -> %rcx -; nextln: jump ebb2(v9) ; nextln: }