about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2018-08-02 18:10:26 +0200
committerMichael Woerister <michaelwoerister@posteo>2018-08-07 14:48:20 +0200
commitb27a161939620626ca5fdcb9f4dd486a6ed1e827 (patch)
tree97f674eed7b3467f1de86dfefc8838d9601d336d
parentf2969ed6c3c067659b5a160de08e9a57450b1047 (diff)
downloadrust-b27a161939620626ca5fdcb9f4dd486a6ed1e827.tar.gz
rust-b27a161939620626ca5fdcb9f4dd486a6ed1e827.zip
Annotate functions in LLVM with target-cpu, same as Clang does.
-rw-r--r--src/librustc_codegen_llvm/attributes.rs18
-rw-r--r--src/librustc_codegen_llvm/base.rs1
-rw-r--r--src/librustc_codegen_llvm/context.rs3
-rw-r--r--src/test/codegen/target-cpu-on-functions.rs28
4 files changed, 50 insertions, 0 deletions
diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs
index c52f8944108..714e8914e48 100644
--- a/src/librustc_codegen_llvm/attributes.rs
+++ b/src/librustc_codegen_llvm/attributes.rs
@@ -123,6 +123,15 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
         .filter(|l| !l.is_empty())
 }
 
+pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
+    let target_cpu = CString::new(cx.tcx.sess.target_cpu().to_string()).unwrap();
+    llvm::AddFunctionAttrStringValue(
+            llfn,
+            llvm::AttributePlace::Function,
+            cstr("target-cpu\0"),
+            target_cpu.as_c_str());
+}
+
 /// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
 /// attributes.
 pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
@@ -167,6 +176,15 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
         Some(true) | None => {}
     }
 
+    // Always annotate functions with the target-cpu they are compiled for.
+    // Without this, ThinLTO won't inline Rust functions into Clang generated
+    // functions (because Clang annotates functions this way too).
+    // NOTE: For now we just apply this if -Zcross-lang-lto is specified, since
+    //       it introduce a little overhead and isn't really necessary otherwise.
+    if cx.tcx.sess.opts.debugging_opts.cross_lang_lto.enabled() {
+        apply_target_cpu_attr(cx, llfn);
+    }
+
     let features = llvm_target_features(cx.tcx.sess)
         .map(|s| s.to_string())
         .chain(
diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs
index 41336165684..13e8426155a 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -596,6 +596,7 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) {
 
         // `main` should respect same config for frame pointer elimination as rest of code
         attributes::set_frame_pointer_elimination(cx, llfn);
+        attributes::apply_target_cpu_attr(cx, llfn);
 
         let bx = Builder::new_block(cx, llfn, "top");
 
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index 2f557d0b099..7a308bb6e88 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use attributes;
 use common;
 use llvm;
 use rustc::dep_graph::DepGraphSafe;
@@ -381,6 +382,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
                 declare::declare_cfn(self, name, fty)
             }
         };
+        attributes::apply_target_cpu_attr(self, llfn);
         self.eh_personality.set(Some(llfn));
         llfn
     }
@@ -412,6 +414,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
 
         let llfn = declare::declare_fn(self, "rust_eh_unwind_resume", ty);
         attributes::unwind(llfn, true);
+        attributes::apply_target_cpu_attr(self, llfn);
         unwresume.set(Some(llfn));
         llfn
     }
diff --git a/src/test/codegen/target-cpu-on-functions.rs b/src/test/codegen/target-cpu-on-functions.rs
new file mode 100644
index 00000000000..c2765a46caa
--- /dev/null
+++ b/src/test/codegen/target-cpu-on-functions.rs
@@ -0,0 +1,28 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This test makes sure that functions get annotated with the proper
+// "target-cpu" attribute in LLVM.
+
+// only-x86_64
+// compile-flags: -C no-prepopulate-passes -C panic=abort
+
+#![crate_type = "staticlib"]
+
+// CHECK-LABEL: define {{.*}} @exported() {{.*}} #0
+#[no_mangle]
+pub extern fn exported() {
+    not_exported();
+}
+
+// CHECK-LABEL: define {{.*}} @_ZN23target_cpu_on_functions12not_exported{{.*}}() {{.*}} #0
+fn not_exported() {}
+
+// CHECK: attributes #0 = {{.*}} "target-cpu"="x86-64"