Skip to content

Commit

Permalink
rustc_trans: avoid a separate entry BB if START_BLOCK has no backedges.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Mar 8, 2017
1 parent c4275c2 commit df60044
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 17 deletions.
17 changes: 10 additions & 7 deletions src/librustc_trans/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,17 @@ pub fn trans_mir<'a, 'tcx: 'a>(
debug!("fn_ty: {:?}", fn_ty);
let debug_context =
debuginfo::create_function_debug_context(ccx, instance, sig, llfn, mir);
let bcx = Builder::new_block(ccx, llfn, "entry-block");
let bcx = Builder::new_block(ccx, llfn, "start");

let cleanup_kinds = analyze::cleanup_kinds(&mir);

// Allocate a `Block` for every basic block
// Allocate a `Block` for every basic block, except
// the start block, if nothing loops back to it.
let reentrant_start_block = !mir.predecessors_for(mir::START_BLOCK).is_empty();
let block_bcxs: IndexVec<mir::BasicBlock, BasicBlockRef> =
mir.basic_blocks().indices().map(|bb| {
if bb == mir::START_BLOCK {
bcx.build_sibling_block("start").llbb()
if bb == mir::START_BLOCK && !reentrant_start_block {
bcx.llbb()
} else {
bcx.build_sibling_block(&format!("{:?}", bb)).llbb()
}
Expand Down Expand Up @@ -294,9 +296,10 @@ pub fn trans_mir<'a, 'tcx: 'a>(
.collect()
};

// Branch to the START block
let start_bcx = mircx.blocks[mir::START_BLOCK];
bcx.br(start_bcx);
// Branch to the START block, if it's not the entry block.
if reentrant_start_block {
bcx.br(mircx.blocks[mir::START_BLOCK]);
}

// Up until here, IR instructions for this function have explicitly not been annotated with
// source code location, so we don't step into call setup code. From here on, source location
Expand Down
47 changes: 37 additions & 10 deletions src/test/codegen/naked-functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,28 @@
#[no_mangle]
#[naked]
fn naked_empty() {
// CHECK: ret void
// CHECK-NEXT: {{.+}}:
// CHECK-NEXT: ret void
}

// CHECK: Function Attrs: naked uwtable
#[no_mangle]
#[naked]
// CHECK-NEXT: define internal void @naked_with_args(i{{[0-9]+}})
fn naked_with_args(a: isize) {
// CHECK: %a = alloca i{{[0-9]+}}
// CHECK: ret void
// CHECK-NEXT: {{.+}}:
// CHECK-NEXT: %a = alloca i{{[0-9]+}}
&a; // keep variable in an alloca
// CHECK: ret void
}

// CHECK: Function Attrs: naked uwtable
// CHECK-NEXT: define internal i{{[0-9]+}} @naked_with_return()
#[no_mangle]
#[naked]
fn naked_with_return() -> isize {
// CHECK: ret i{{[0-9]+}} 0
// CHECK-NEXT: {{.+}}:
// CHECK-NEXT: ret i{{[0-9]+}} 0
0
}

Expand All @@ -47,9 +50,10 @@ fn naked_with_return() -> isize {
#[no_mangle]
#[naked]
fn naked_with_args_and_return(a: isize) -> isize {
// CHECK: %a = alloca i{{[0-9]+}}
// CHECK: ret i{{[0-9]+}} %{{[0-9]+}}
// CHECK-NEXT: {{.+}}:
// CHECK-NEXT: %a = alloca i{{[0-9]+}}
&a; // keep variable in an alloca
// CHECK: ret i{{[0-9]+}} %{{[0-9]+}}
a
}

Expand All @@ -58,14 +62,37 @@ fn naked_with_args_and_return(a: isize) -> isize {
#[no_mangle]
#[naked]
fn naked_recursive() {
// CHECK: call void @naked_empty()
// CHECK-NEXT: {{.+}}:
// CHECK-NEXT: call void @naked_empty()

// FIXME(#39685) Avoid one block per call.
// CHECK-NEXT: br label %bb1
// CHECK: bb1:

naked_empty();
// CHECK: %{{[0-9]+}} = call i{{[0-9]+}} @naked_with_return()

// CHECK-NEXT: %{{[0-9]+}} = call i{{[0-9]+}} @naked_with_return()

// FIXME(#39685) Avoid one block per call.
// CHECK-NEXT: br label %bb2
// CHECK: bb2:

// CHECK-NEXT: %{{[0-9]+}} = call i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+}} %{{[0-9]+}})

// FIXME(#39685) Avoid one block per call.
// CHECK-NEXT: br label %bb3
// CHECK: bb3:

// CHECK-NEXT: call void @naked_with_args(i{{[0-9]+}} %{{[0-9]+}})

// FIXME(#39685) Avoid one block per call.
// CHECK-NEXT: br label %bb4
// CHECK: bb4:

naked_with_args(
// CHECK: %{{[0-9]+}} = call i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+}} %{{[0-9]+}})
naked_with_args_and_return(
// CHECK: call void @naked_with_args(i{{[0-9]+}} %{{[0-9]+}})
naked_with_return()
)
);
// CHECK-NEXT: ret void
}

0 comments on commit df60044

Please sign in to comment.