diff options
| author | bors <bors@rust-lang.org> | 2017-10-15 20:07:35 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-10-15 20:07:35 +0000 |
| commit | 29ed49fb0aeab444adcfe16ef3d04e5e910fb08d (patch) | |
| tree | 612a8d9d8aab8b4498c7e57d179f63e499f18663 /src | |
| parent | c4f489af912bea9ca9f0fa0378d7c0acacf6c59e (diff) | |
| parent | 2e1c4cd0f51c28b8cfc003fda67f6641bb4335f2 (diff) | |
| download | rust-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.rs | 20 | ||||
| -rw-r--r-- | src/librustc_trans/back/write.rs | 10 | ||||
| -rw-r--r-- | src/rustllvm/PassWrapper.cpp | 13 | ||||
| -rw-r--r-- | src/test/run-pass/thinlto/auxiliary/dylib.rs | 16 | ||||
| -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.rs | 18 | ||||
| -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 |
