about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-10-15 20:07:35 +0000
committerbors <bors@rust-lang.org>2017-10-15 20:07:35 +0000
commit29ed49fb0aeab444adcfe16ef3d04e5e910fb08d (patch)
tree612a8d9d8aab8b4498c7e57d179f63e499f18663 /src
parentc4f489af912bea9ca9f0fa0378d7c0acacf6c59e (diff)
parent2e1c4cd0f51c28b8cfc003fda67f6641bb4335f2 (diff)
downloadrust-29ed49fb0aeab444adcfe16ef3d04e5e910fb08d.tar.gz
rust-29ed49fb0aeab444adcfe16ef3d04e5e910fb08d.zip
Auto merge of #45215 - alexcrichton:thin-lto-reference-more, r=michaelwoerister
rustc: Fix some ThinLTO internalization

First the `addPreservedGUID` function forgot to take care of "alias" summaries.
I'm not 100% sure what this is but the current code now matches upstream. Next
the `computeDeadSymbols` return value wasn't actually being used, but it needed
to be used! Together these should...

Closes #45195
Diffstat (limited to 'src')
-rw-r--r--src/librustc_trans/back/lto.rs20
-rw-r--r--src/librustc_trans/back/write.rs10
-rw-r--r--src/rustllvm/PassWrapper.cpp13
-rw-r--r--src/test/run-pass/thinlto/auxiliary/dylib.rs16
-rw-r--r--src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs (renamed from src/test/run-pass/auxiliary/thin-lto-inlines-aux.rs)0
-rw-r--r--src/test/run-pass/thinlto/dylib-works.rs18
-rw-r--r--src/test/run-pass/thinlto/thin-lto-inlines.rs (renamed from src/test/run-pass/thin-lto-inlines.rs)0
-rw-r--r--src/test/run-pass/thinlto/thin-lto-inlines2.rs (renamed from src/test/run-pass/thin-lto-inlines2.rs)0
8 files changed, 67 insertions, 10 deletions
diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs
index 8f75b891a30..01d3d656dfe 100644
--- a/src/librustc_trans/back/lto.rs
+++ b/src/librustc_trans/back/lto.rs
@@ -130,6 +130,7 @@ pub fn run(cgcx: &CodegenContext,
         .filter_map(symbol_filter)
         .collect::<Vec<CString>>();
     timeline.record("whitelist");
+    info!("{} symbols to preserve in this crate", symbol_white_list.len());
 
     // If we're performing LTO for the entire crate graph, then for each of our
     // upstream dependencies, find the corresponding rlib and load the bitcode
@@ -437,7 +438,24 @@ fn run_pass_manager(cgcx: &CodegenContext,
         assert!(!pass.is_null());
         llvm::LLVMRustAddPass(pm, pass);
 
-        with_llvm_pmb(llmod, config, &mut |b| {
+        // When optimizing for LTO we don't actually pass in `-O0`, but we force
+        // it to always happen at least with `-O1`.
+        //
+        // With ThinLTO we mess around a lot with symbol visibility in a way
+        // that will actually cause linking failures if we optimize at O0 which
+        // notable is lacking in dead code elimination. To ensure we at least
+        // get some optimizations and correctly link we forcibly switch to `-O1`
+        // to get dead code elimination.
+        //
+        // Note that in general this shouldn't matter too much as you typically
+        // only turn on ThinLTO when you're compiling with optimizations
+        // otherwise.
+        let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
+        let opt_level = match opt_level {
+            llvm::CodeGenOptLevel::None => llvm::CodeGenOptLevel::Less,
+            level => level,
+        };
+        with_llvm_pmb(llmod, config, opt_level, &mut |b| {
             if thin {
                 if !llvm::LLVMRustPassManagerBuilderPopulateThinLTOPassManager(b, pm) {
                     panic!("this version of LLVM does not support ThinLTO");
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 9d914243ec6..f7e0ad029af 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -217,7 +217,7 @@ pub struct ModuleConfig {
     passes: Vec<String>,
     /// Some(level) to optimize at a certain level, or None to run
     /// absolutely no optimizations (used for the metadata module).
-    opt_level: Option<llvm::CodeGenOptLevel>,
+    pub opt_level: Option<llvm::CodeGenOptLevel>,
 
     /// Some(level) to optimize binary size, or None to not affect program size.
     opt_size: Option<llvm::CodeGenOptSize>,
@@ -507,7 +507,8 @@ unsafe fn optimize(cgcx: &CodegenContext,
         if !config.no_prepopulate_passes {
             llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
             llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
-            with_llvm_pmb(llmod, &config, &mut |b| {
+            let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
+            with_llvm_pmb(llmod, &config, opt_level, &mut |b| {
                 llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
                 llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm);
             })
@@ -1842,16 +1843,17 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
 
 pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
                             config: &ModuleConfig,
+                            opt_level: llvm::CodeGenOptLevel,
                             f: &mut FnMut(llvm::PassManagerBuilderRef)) {
     // Create the PassManagerBuilder for LLVM. We configure it with
     // reasonable defaults and prepare it to actually populate the pass
     // manager.
     let builder = llvm::LLVMPassManagerBuilderCreate();
-    let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
     let opt_size = config.opt_size.unwrap_or(llvm::CodeGenOptSizeNone);
     let inline_threshold = config.inline_threshold;
 
-    llvm::LLVMRustConfigurePassManagerBuilder(builder, opt_level,
+    llvm::LLVMRustConfigurePassManagerBuilder(builder,
+                                              opt_level,
                                               config.merge_functions,
                                               config.vectorize_slp,
                                               config.vectorize_loop);
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index e37f048dd47..1287b94159a 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -901,9 +901,7 @@ addPreservedGUID(const ModuleSummaryIndex &Index,
       }
     }
 
-    GlobalValueSummary *GVSummary = Summary.get();
-    if (isa<FunctionSummary>(GVSummary)) {
-      FunctionSummary *FS = cast<FunctionSummary>(GVSummary);
+    if (auto *FS = dyn_cast<FunctionSummary>(Summary.get())) {
       for (auto &Call: FS->calls()) {
         if (Call.first.isGUID()) {
           addPreservedGUID(Index, Preserved, Call.first.getGUID());
@@ -916,6 +914,10 @@ addPreservedGUID(const ModuleSummaryIndex &Index,
         addPreservedGUID(Index, Preserved, GUID);
       }
     }
+    if (auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
+      auto GUID = AS->getAliasee().getOriginalName();
+      addPreservedGUID(Index, Preserved, GUID);
+    }
   }
 }
 
@@ -963,12 +965,13 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
   // combined index
   //
   // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`
-  computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols);
+  auto DeadSymbols = computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols);
   ComputeCrossModuleImport(
     Ret->Index,
     Ret->ModuleToDefinedGVSummaries,
     Ret->ImportLists,
-    Ret->ExportLists
+    Ret->ExportLists,
+    &DeadSymbols
   );
 
   // Resolve LinkOnce/Weak symbols, this has to be computed early be cause it
diff --git a/src/test/run-pass/thinlto/auxiliary/dylib.rs b/src/test/run-pass/thinlto/auxiliary/dylib.rs
new file mode 100644
index 00000000000..cdb3f49cae8
--- /dev/null
+++ b/src/test/run-pass/thinlto/auxiliary/dylib.rs
@@ -0,0 +1,16 @@
+// Copyright 2017 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.
+
+// compile-flags: -Z thinlto -C codegen-units=8
+
+#[inline]
+pub fn foo(b: u8) {
+    b.to_string();
+}
diff --git a/src/test/run-pass/auxiliary/thin-lto-inlines-aux.rs b/src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs
index ccbb0e7a718..ccbb0e7a718 100644
--- a/src/test/run-pass/auxiliary/thin-lto-inlines-aux.rs
+++ b/src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs
diff --git a/src/test/run-pass/thinlto/dylib-works.rs b/src/test/run-pass/thinlto/dylib-works.rs
new file mode 100644
index 00000000000..3f54519d0d8
--- /dev/null
+++ b/src/test/run-pass/thinlto/dylib-works.rs
@@ -0,0 +1,18 @@
+// Copyright 2017 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.
+
+// aux-build:dylib.rs
+// min-llvm-version 4.0
+
+extern crate dylib;
+
+fn main() {
+    dylib::foo(1);
+}
diff --git a/src/test/run-pass/thin-lto-inlines.rs b/src/test/run-pass/thinlto/thin-lto-inlines.rs
index 3135a682d86..3135a682d86 100644
--- a/src/test/run-pass/thin-lto-inlines.rs
+++ b/src/test/run-pass/thinlto/thin-lto-inlines.rs
diff --git a/src/test/run-pass/thin-lto-inlines2.rs b/src/test/run-pass/thinlto/thin-lto-inlines2.rs
index ed899d2b115..ed899d2b115 100644
--- a/src/test/run-pass/thin-lto-inlines2.rs
+++ b/src/test/run-pass/thinlto/thin-lto-inlines2.rs