about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-11-29 23:05:23 +0100
committerNikita Popov <nikita.ppv@gmail.com>2018-11-30 00:52:16 +0100
commitcbf748993f59682f60dfe620eafea24124f737fb (patch)
tree14feb4e1666894a16c5c35c59942a5111bdf941c
parent0c1dc62c1ec3c23dcb5e90500a2b3b25817ad03a (diff)
downloadrust-cbf748993f59682f60dfe620eafea24124f737fb.tar.gz
rust-cbf748993f59682f60dfe620eafea24124f737fb.zip
Enable -mergefunc-use-aliases
If the Rust LLVM fork is used, enable the -mergefunc-use-aliases
flag, which will create aliases for merged functions, rather than
inserting a call from one to the other.

A number of codegen tests needed to be adjusted, because functions
that previously fell below the thunk limit are now being merged.
Merging is prevented either using -C no-prepopulate-passes, or by
making the functions non-identical.

I expect that this is going to break something, somewhere, because
it isn't able to deal with aliases properly, but we won't find out
until we try :)

This fixes #52651.
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs1
-rw-r--r--src/librustc_codegen_llvm/llvm_util.rs3
-rw-r--r--src/rustllvm/PassWrapper.cpp2
-rw-r--r--src/rustllvm/RustWrapper.cpp8
-rw-r--r--src/test/codegen/export-no-mangle.rs2
-rw-r--r--src/test/codegen/external-no-mangle-fns.rs4
-rw-r--r--src/test/codegen/issue-45222.rs4
-rw-r--r--src/test/codegen/match-optimizes-away.rs3
8 files changed, 21 insertions, 6 deletions
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index f1a966d7654..9eefeca70cf 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -1358,6 +1358,7 @@ extern "C" {
     pub fn LLVMRustDebugMetadataVersion() -> u32;
     pub fn LLVMRustVersionMajor() -> u32;
     pub fn LLVMRustVersionMinor() -> u32;
+    pub fn LLVMRustIsRustLLVM() -> bool;
 
     pub fn LLVMRustAddModuleFlag(M: &Module, name: *const c_char, value: u32);
 
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index 267d7e0d54b..fdb6373bea1 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -70,6 +70,9 @@ unsafe fn configure_llvm(sess: &Session) {
         if sess.opts.debugging_opts.disable_instrumentation_preinliner {
             add("-disable-preinline");
         }
+        if llvm::LLVMRustIsRustLLVM() {
+            add("-mergefunc-use-aliases");
+        }
 
         for arg in &sess.opts.cg.llvm_args {
             add(&(*arg));
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 06de0d6509b..aa420bf6100 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -284,7 +284,7 @@ static Optional<Reloc::Model> fromRust(LLVMRustRelocMode RustReloc) {
   report_fatal_error("Bad RelocModel.");
 }
 
-#if LLVM_RUSTLLVM
+#ifdef LLVM_RUSTLLVM
 /// getLongestEntryLength - Return the length of the longest entry in the table.
 ///
 static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index b6e07942f86..6dcd32fe4d7 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -533,6 +533,14 @@ extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
 
 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
 
+extern "C" bool LLVMRustIsRustLLVM() {
+#ifdef LLVM_RUSTLLVM
+  return 1;
+#else
+  return 0;
+#endif
+}
+
 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
                                       uint32_t Value) {
   unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
diff --git a/src/test/codegen/export-no-mangle.rs b/src/test/codegen/export-no-mangle.rs
index 3546284f9a3..95587d9d84c 100644
--- a/src/test/codegen/export-no-mangle.rs
+++ b/src/test/codegen/export-no-mangle.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -C no-prepopulate-passes
+
 #![crate_type = "lib"]
 
 mod private {
diff --git a/src/test/codegen/external-no-mangle-fns.rs b/src/test/codegen/external-no-mangle-fns.rs
index 3f092b802f9..58232852596 100644
--- a/src/test/codegen/external-no-mangle-fns.rs
+++ b/src/test/codegen/external-no-mangle-fns.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -O
+// compile-flags: -C no-prepopulate-passes
 // `#[no_mangle]`d functions always have external linkage, i.e. no `internal` in their `define`s
 
 #![crate_type = "lib"]
@@ -43,7 +43,7 @@ const HIDDEN: () = {
 };
 
 // The surrounding item should not accidentally become external
-// CHECK: define internal {{.*}} void @_ZN22external_no_mangle_fns1x
+// CHECK: define internal{{.*}} void @_ZN22external_no_mangle_fns1x
 #[inline(never)]
 fn x() {
     // CHECK: define void @g()
diff --git a/src/test/codegen/issue-45222.rs b/src/test/codegen/issue-45222.rs
index 30a03243f01..3544786e2e6 100644
--- a/src/test/codegen/issue-45222.rs
+++ b/src/test/codegen/issue-45222.rs
@@ -69,6 +69,6 @@ fn foo3r(n: u64) -> u64 {
 // CHECK-LABEL: @check_foo3r
 #[no_mangle]
 pub fn check_foo3r() -> u64 {
-    // CHECK: ret i64 500005000000000
-    foo3r(100000)
+    // CHECK: ret i64 500050000000
+    foo3r(10000)
 }
diff --git a/src/test/codegen/match-optimizes-away.rs b/src/test/codegen/match-optimizes-away.rs
index d7b77937431..2136b176eac 100644
--- a/src/test/codegen/match-optimizes-away.rs
+++ b/src/test/codegen/match-optimizes-away.rs
@@ -14,6 +14,7 @@
 
 pub enum Three { A, B, C }
 
+#[repr(u16)]
 pub enum Four { A, B, C, D }
 
 #[no_mangle]
@@ -32,7 +33,7 @@ pub fn three_valued(x: Three) -> Three {
 pub fn four_valued(x: Four) -> Four {
     // CHECK-LABEL: @four_valued
     // CHECK-NEXT: {{^.*:$}}
-    // CHECK-NEXT: ret i8 %0
+    // CHECK-NEXT: ret i16 %0
     match x {
         Four::A => Four::A,
         Four::B => Four::B,