about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2017-03-08 20:08:09 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2017-04-12 20:20:53 +0300
commit9b5c577dbd45ff3b11f9d7aab6990cc1ee9194fb (patch)
treecb74473c36b321bf40f13dc1cfd3464ea7790455
parentcb3c4d022a048d9c4d1306eaacd9b72303f1871a (diff)
downloadrust-9b5c577dbd45ff3b11f9d7aab6990cc1ee9194fb.tar.gz
rust-9b5c577dbd45ff3b11f9d7aab6990cc1ee9194fb.zip
rustc_trans: avoid a separate entry BB if START_BLOCK has no backedges.
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs3
-rw-r--r--src/librustc_trans/mir/mod.rs17
-rw-r--r--src/test/codegen/naked-functions.rs47
3 files changed, 49 insertions, 18 deletions
diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs
index ccb693aa41f..2d1c95114eb 100644
--- a/src/librustc_trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/debuginfo/metadata.rs
@@ -784,7 +784,8 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext,
     };
 
     debug!("compile_unit_metadata: {:?}", compile_unit_name);
-    let producer = format!("rustc version {}",
+    // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
+    let producer = format!("clang LLVM (rustc version {})",
                            (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
 
     let compile_unit_name = compile_unit_name.as_ptr();
diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs
index 99d8cd594ec..3d8c5085462 100644
--- a/src/librustc_trans/mir/mod.rs
+++ b/src/librustc_trans/mir/mod.rs
@@ -195,15 +195,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()
             }
@@ -289,9 +291,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
diff --git a/src/test/codegen/naked-functions.rs b/src/test/codegen/naked-functions.rs
index 9de74f72005..9883ca6b35d 100644
--- a/src/test/codegen/naked-functions.rs
+++ b/src/test/codegen/naked-functions.rs
@@ -20,7 +20,8 @@
 #[no_mangle]
 #[naked]
 fn naked_empty() {
-    // CHECK: ret void
+    // CHECK-NEXT: {{.+}}:
+    // CHECK-NEXT: ret void
 }
 
 // CHECK: Function Attrs: naked uwtable
@@ -28,9 +29,10 @@ fn naked_empty() {
 #[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
@@ -38,7 +40,8 @@ fn naked_with_args(a: isize) {
 #[no_mangle]
 #[naked]
 fn naked_with_return() -> isize {
-    // CHECK: ret i{{[0-9]+}} 0
+    // CHECK-NEXT: {{.+}}:
+    // CHECK-NEXT: ret i{{[0-9]+}} 0
     0
 }
 
@@ -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
 }
 
@@ -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
 }