diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 1a92f2c0f7aa1..2130314b5eae6 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -96,18 +96,18 @@ pub enum LtoCli { } #[derive(Clone, PartialEq, Hash)] -pub enum CrossLangLto { +pub enum LinkerPluginLto { LinkerPlugin(PathBuf), LinkerPluginAuto, Disabled } -impl CrossLangLto { +impl LinkerPluginLto { pub fn enabled(&self) -> bool { match *self { - CrossLangLto::LinkerPlugin(_) | - CrossLangLto::LinkerPluginAuto => true, - CrossLangLto::Disabled => false, + LinkerPluginLto::LinkerPlugin(_) | + LinkerPluginLto::LinkerPluginAuto => true, + LinkerPluginLto::Disabled => false, } } } @@ -812,7 +812,7 @@ macro_rules! options { pub const parse_lto: Option<&str> = Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \ `fat`, or omitted"); - pub const parse_cross_lang_lto: Option<&str> = + pub const parse_linker_plugin_lto: Option<&str> = Some("either a boolean (`yes`, `no`, `on`, `off`, etc), \ or the path to the linker plugin"); pub const parse_merge_functions: Option<&str> = @@ -821,7 +821,7 @@ macro_rules! options { #[allow(dead_code)] mod $mod_set { - use super::{$struct_name, Passes, Sanitizer, LtoCli, CrossLangLto}; + use super::{$struct_name, Passes, Sanitizer, LtoCli, LinkerPluginLto}; use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel}; use std::path::PathBuf; use std::str::FromStr; @@ -1037,22 +1037,22 @@ macro_rules! options { true } - fn parse_cross_lang_lto(slot: &mut CrossLangLto, v: Option<&str>) -> bool { + fn parse_linker_plugin_lto(slot: &mut LinkerPluginLto, v: Option<&str>) -> bool { if v.is_some() { let mut bool_arg = None; if parse_opt_bool(&mut bool_arg, v) { *slot = if bool_arg.unwrap() { - CrossLangLto::LinkerPluginAuto + LinkerPluginLto::LinkerPluginAuto } else { - CrossLangLto::Disabled + LinkerPluginLto::Disabled }; return true } } *slot = match v { - None => CrossLangLto::LinkerPluginAuto, - Some(path) => CrossLangLto::LinkerPlugin(PathBuf::from(path)), + None => LinkerPluginLto::LinkerPluginAuto, + Some(path) => LinkerPluginLto::LinkerPlugin(PathBuf::from(path)), }; true } @@ -1145,6 +1145,10 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, "allow the linker to link its default libraries"), linker_flavor: Option = (None, parse_linker_flavor, [UNTRACKED], "Linker flavor"), + linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled, + parse_linker_plugin_lto, [TRACKED], + "generate build artifacts that are compatible with linker-based LTO."), + } options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, @@ -1383,8 +1387,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "make the current crate share its generic instantiations"), chalk: bool = (false, parse_bool, [TRACKED], "enable the experimental Chalk-based trait solving engine"), - cross_lang_lto: CrossLangLto = (CrossLangLto::Disabled, parse_cross_lang_lto, [TRACKED], - "generate build artifacts that are compatible with linker-based LTO."), no_parallel_llvm: bool = (false, parse_bool, [UNTRACKED], "don't run LLVM in parallel (while keeping codegen-units and ThinLTO)"), no_leak_check: bool = (false, parse_bool, [UNTRACKED], @@ -2440,7 +2442,7 @@ mod dep_tracking { use std::path::PathBuf; use std::collections::hash_map::DefaultHasher; use super::{CrateType, DebugInfo, ErrorOutputType, OptLevel, OutputTypes, - Passes, Sanitizer, LtoCli, CrossLangLto}; + Passes, Sanitizer, LtoCli, LinkerPluginLto}; use syntax::feature_gate::UnstableFeatures; use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel, TargetTriple}; use syntax::edition::Edition; @@ -2507,7 +2509,7 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(TargetTriple); impl_dep_tracking_hash_via_hash!(Edition); - impl_dep_tracking_hash_via_hash!(CrossLangLto); + impl_dep_tracking_hash_via_hash!(LinkerPluginLto); impl_dep_tracking_hash_for_sortable_vec_of!(String); impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf); @@ -2572,7 +2574,7 @@ mod tests { use crate::lint; use crate::middle::cstore; use crate::session::config::{build_configuration, build_session_options_and_crate_config}; - use crate::session::config::{LtoCli, CrossLangLto}; + use crate::session::config::{LtoCli, LinkerPluginLto}; use crate::session::build_session; use crate::session::search_paths::SearchPath; use std::collections::{BTreeMap, BTreeSet}; @@ -3105,6 +3107,10 @@ mod tests { opts = reference.clone(); opts.cg.panic = Some(PanicStrategy::Abort); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); + + opts = reference.clone(); + opts.cg.linker_plugin_lto = LinkerPluginLto::LinkerPluginAuto; + assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); } #[test] @@ -3231,10 +3237,6 @@ mod tests { opts.debugging_opts.relro_level = Some(RelroLevel::Full); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); - opts = reference.clone(); - opts.debugging_opts.cross_lang_lto = CrossLangLto::LinkerPluginAuto; - assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); - opts = reference.clone(); opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 9f387e1eab1ef..e4b293558e592 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -1267,7 +1267,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) { // bitcode during ThinLTO. Therefore we disallow dynamic linking on MSVC // when compiling for LLD ThinLTO. This way we can validly just not generate // the `dllimport` attributes and `__imp_` symbols in that case. - if sess.opts.debugging_opts.cross_lang_lto.enabled() && + if sess.opts.cg.linker_plugin_lto.enabled() && sess.opts.cg.prefer_dynamic && sess.target.target.options.is_like_msvc { sess.err("Linker plugin based LTO is not supported together with \ diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs index fc744201a332c..8bb985ecc25fa 100644 --- a/src/librustc_codegen_llvm/back/link.rs +++ b/src/librustc_codegen_llvm/back/link.rs @@ -857,7 +857,7 @@ fn link_args(cmd: &mut dyn Linker, codegen_results: &CodegenResults) { // Linker plugins should be specified early in the list of arguments - cmd.cross_lang_lto(); + cmd.linker_plugin_lto(); // The default library location, we need this to find the runtime. // The location of crates will be determined as needed. @@ -1491,7 +1491,7 @@ fn are_upstream_rust_objects_already_included(sess: &Session) -> bool { Lto::Thin => { // If we defer LTO to the linker, we haven't run LTO ourselves, so // any upstream object files have not been copied yet. - !sess.opts.debugging_opts.cross_lang_lto.enabled() + !sess.opts.cg.linker_plugin_lto.enabled() } Lto::No | Lto::ThinLocal => false, diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 3e51078dc6436..b6b880c7ec4ac 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -159,7 +159,7 @@ pub(crate) fn run_thin(cgcx: &CodegenContext, let symbol_white_list = symbol_white_list.iter() .map(|c| c.as_ptr()) .collect::>(); - if cgcx.opts.debugging_opts.cross_lang_lto.enabled() { + if cgcx.opts.cg.linker_plugin_lto.enabled() { unreachable!("We should never reach this case if the LTO step \ is deferred to the linker"); } diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 47637f3c5d705..e78715319727b 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -366,7 +366,7 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext, let opt_level = config.opt_level.map(|x| to_llvm_opt_settings(x).0) .unwrap_or(llvm::CodeGenOptLevel::None); let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal || - (cgcx.lto != Lto::Fat && cgcx.opts.debugging_opts.cross_lang_lto.enabled()); + (cgcx.lto != Lto::Fat && cgcx.opts.cg.linker_plugin_lto.enabled()); with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| { llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm); llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm); diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index b7a9382c338bd..ca9e2c87be237 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -275,12 +275,12 @@ impl CodegenCx<'ll, 'tcx> { self.use_dll_storage_attrs && !self.tcx.is_foreign_item(def_id) && // ThinLTO can't handle this workaround in all cases, so we don't // emit the attrs. Instead we make them unnecessary by disallowing - // dynamic linking when cross-language LTO is enabled. - !self.tcx.sess.opts.debugging_opts.cross_lang_lto.enabled(); + // dynamic linking when linker plugin based LTO is enabled. + !self.tcx.sess.opts.cg.linker_plugin_lto.enabled(); // If this assertion triggers, there's something wrong with commandline // argument validation. - debug_assert!(!(self.tcx.sess.opts.debugging_opts.cross_lang_lto.enabled() && + debug_assert!(!(self.tcx.sess.opts.cg.linker_plugin_lto.enabled() && self.tcx.sess.target.target.options.is_like_msvc && self.tcx.sess.opts.cg.prefer_dynamic)); diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 249715a7b6e26..4b34bf704d588 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -13,7 +13,7 @@ use rustc::hir::def_id::{LOCAL_CRATE, CrateNum}; use rustc::middle::dependency_format::Linkage; use rustc::session::Session; use rustc::session::config::{self, CrateType, OptLevel, DebugInfo, - CrossLangLto, Lto}; + LinkerPluginLto, Lto}; use rustc::ty::TyCtxt; use rustc_target::spec::{LinkerFlavor, LldFlavor}; use serialize::{json, Encoder}; @@ -127,7 +127,7 @@ pub trait Linker { fn subsystem(&mut self, subsystem: &str); fn group_start(&mut self); fn group_end(&mut self); - fn cross_lang_lto(&mut self); + fn linker_plugin_lto(&mut self); // Should have been finalize(self), but we don't support self-by-value on trait objects (yet?). fn finalize(&mut self) -> Command; } @@ -183,7 +183,7 @@ impl<'a> GccLinker<'a> { } } - fn push_cross_lang_lto_args(&mut self, plugin_path: Option<&OsStr>) { + fn push_linker_plugin_lto_args(&mut self, plugin_path: Option<&OsStr>) { if let Some(plugin_path) = plugin_path { let mut arg = OsString::from("-plugin="); arg.push(plugin_path); @@ -454,16 +454,16 @@ impl<'a> Linker for GccLinker<'a> { } } - fn cross_lang_lto(&mut self) { - match self.sess.opts.debugging_opts.cross_lang_lto { - CrossLangLto::Disabled => { + fn linker_plugin_lto(&mut self) { + match self.sess.opts.cg.linker_plugin_lto { + LinkerPluginLto::Disabled => { // Nothing to do } - CrossLangLto::LinkerPluginAuto => { - self.push_cross_lang_lto_args(None); + LinkerPluginLto::LinkerPluginAuto => { + self.push_linker_plugin_lto_args(None); } - CrossLangLto::LinkerPlugin(ref path) => { - self.push_cross_lang_lto_args(Some(path.as_os_str())); + LinkerPluginLto::LinkerPlugin(ref path) => { + self.push_linker_plugin_lto_args(Some(path.as_os_str())); } } } @@ -697,7 +697,7 @@ impl<'a> Linker for MsvcLinker<'a> { fn group_start(&mut self) {} fn group_end(&mut self) {} - fn cross_lang_lto(&mut self) { + fn linker_plugin_lto(&mut self) { // Do nothing } } @@ -865,7 +865,7 @@ impl<'a> Linker for EmLinker<'a> { fn group_start(&mut self) {} fn group_end(&mut self) {} - fn cross_lang_lto(&mut self) { + fn linker_plugin_lto(&mut self) { // Do nothing } } @@ -1047,7 +1047,7 @@ impl<'a> Linker for WasmLd<'a> { fn group_start(&mut self) {} fn group_end(&mut self) {} - fn cross_lang_lto(&mut self) { + fn linker_plugin_lto(&mut self) { // Do nothing for now } } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index eeb191b09e249..81952c9c820b0 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -126,7 +126,7 @@ impl ModuleConfig { self.time_passes = sess.time_passes(); self.inline_threshold = sess.opts.cg.inline_threshold; self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode || - sess.opts.debugging_opts.cross_lang_lto.enabled(); + sess.opts.cg.linker_plugin_lto.enabled(); let embed_bitcode = sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode; if embed_bitcode { @@ -737,7 +737,7 @@ fn execute_optimize_work_item( // If the linker does LTO, we don't have to do it. Note that we // keep doing full LTO, if it is requested, as not to break the // assumption that the output will be a single module. - let linker_does_lto = cgcx.opts.debugging_opts.cross_lang_lto.enabled(); + let linker_does_lto = cgcx.opts.cg.linker_plugin_lto.enabled(); // When we're automatically doing ThinLTO for multi-codegen-unit // builds we don't actually want to LTO the allocator modules if @@ -1883,7 +1883,7 @@ pub fn pre_lto_bitcode_filename(module_name: &str) -> String { fn msvc_imps_needed(tcx: TyCtxt) -> bool { // This should never be true (because it's not supported). If it is true, // something is wrong with commandline arg validation. - assert!(!(tcx.sess.opts.debugging_opts.cross_lang_lto.enabled() && + assert!(!(tcx.sess.opts.cg.linker_plugin_lto.enabled() && tcx.sess.target.target.options.is_like_msvc && tcx.sess.opts.cg.prefer_dynamic)); @@ -1891,6 +1891,6 @@ fn msvc_imps_needed(tcx: TyCtxt) -> bool { tcx.sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateType::Rlib) && // ThinLTO can't handle this workaround in all cases, so we don't // emit the `__imp_` symbols. Instead we make them unnecessary by disallowing - // dynamic linking when cross-language LTO is enabled. - !tcx.sess.opts.debugging_opts.cross_lang_lto.enabled() + // dynamic linking when linker plugin LTO is enabled. + !tcx.sess.opts.cg.linker_plugin_lto.enabled() } diff --git a/src/test/codegen/no-dllimport-w-cross-lang-lto.rs b/src/test/codegen/no-dllimport-w-cross-lang-lto.rs index c1c1ef6ede2cb..33fc2bc1540d3 100644 --- a/src/test/codegen/no-dllimport-w-cross-lang-lto.rs +++ b/src/test/codegen/no-dllimport-w-cross-lang-lto.rs @@ -3,7 +3,7 @@ // no-prefer-dynamic // only-msvc -// compile-flags: -Z cross-lang-lto +// compile-flags: -C linker-plugin-lto #![crate_type = "rlib"] diff --git a/src/test/codegen/target-cpu-on-functions.rs b/src/test/codegen/target-cpu-on-functions.rs index 5692dca1df5a2..3fdf6ab6d002f 100644 --- a/src/test/codegen/target-cpu-on-functions.rs +++ b/src/test/codegen/target-cpu-on-functions.rs @@ -3,7 +3,7 @@ // no-prefer-dynamic // ignore-tidy-linelength -// compile-flags: -C no-prepopulate-passes -C panic=abort -Z cross-lang-lto -Cpasses=name-anon-globals +// compile-flags: -C no-prepopulate-passes -C panic=abort -C linker-plugin-lto -Cpasses=name-anon-globals #![crate_type = "staticlib"] diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile index cf687070bc2ed..b3c5fb2d79647 100644 --- a/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile @@ -8,7 +8,7 @@ all: cpp-executable rust-executable cpp-executable: - $(RUSTC) -Zcross-lang-lto=on -o $(TMPDIR)/librustlib-xlto.a -Copt-level=2 -Ccodegen-units=1 ./rustlib.rs + $(RUSTC) -Clinker-plugin-lto=on -o $(TMPDIR)/librustlib-xlto.a -Copt-level=2 -Ccodegen-units=1 ./rustlib.rs $(CLANG) -flto=thin -fuse-ld=lld -L $(TMPDIR) -lrustlib-xlto -o $(TMPDIR)/cmain ./cmain.c -O3 # Make sure we don't find a call instruction to the function we expect to # always be inlined. @@ -20,6 +20,6 @@ cpp-executable: rust-executable: $(CLANG) ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2 (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o) - $(RUSTC) -Zcross-lang-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=$(CLANG) -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain + $(RUSTC) -Clinker-plugin-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=$(CLANG) -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -e "call.*c_never_inlined" llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -v -e "call.*c_always_inlined" diff --git a/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile index 4f33b1c59e084..c9da06ff93f86 100644 --- a/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile +++ b/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile @@ -5,13 +5,13 @@ ifndef IS_WINDOWS # This test makes sure that we don't loose upstream object files when compiling -# staticlibs with -Zcross-lang-lto +# staticlibs with -C linker-plugin-lto all: staticlib.rs upstream.rs - $(RUSTC) upstream.rs -Z cross-lang-lto -Ccodegen-units=1 + $(RUSTC) upstream.rs -C linker-plugin-lto -Ccodegen-units=1 # Check No LTO - $(RUSTC) staticlib.rs -Z cross-lang-lto -Ccodegen-units=1 -L. -o $(TMPDIR)/staticlib.a + $(RUSTC) staticlib.rs -C linker-plugin-lto -Ccodegen-units=1 -L. -o $(TMPDIR)/staticlib.a (cd $(TMPDIR); $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-ar x ./staticlib.a) # Make sure the upstream object file was included ls $(TMPDIR)/upstream.*.rcgu.o @@ -20,8 +20,8 @@ all: staticlib.rs upstream.rs rm $(TMPDIR)/* # Check ThinLTO - $(RUSTC) upstream.rs -Z cross-lang-lto -Ccodegen-units=1 -Clto=thin - $(RUSTC) staticlib.rs -Z cross-lang-lto -Ccodegen-units=1 -Clto=thin -L. -o $(TMPDIR)/staticlib.a + $(RUSTC) upstream.rs -C linker-plugin-lto -Ccodegen-units=1 -Clto=thin + $(RUSTC) staticlib.rs -C linker-plugin-lto -Ccodegen-units=1 -Clto=thin -L. -o $(TMPDIR)/staticlib.a (cd $(TMPDIR); $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-ar x ./staticlib.a) ls $(TMPDIR)/upstream.*.rcgu.o diff --git a/src/test/run-make-fulldeps/cross-lang-lto/Makefile b/src/test/run-make-fulldeps/cross-lang-lto/Makefile index 57a19a0ccb037..43bd05a73592c 100644 --- a/src/test/run-make-fulldeps/cross-lang-lto/Makefile +++ b/src/test/run-make-fulldeps/cross-lang-lto/Makefile @@ -7,14 +7,14 @@ ifndef IS_WINDOWS # This test makes sure that the object files we generate are actually # LLVM bitcode files (as used by linker LTO plugins) when compiling with -# -Z cross-lang-lto. +# -Clinker-plugin-lto. # this only succeeds for bitcode files ASSERT_IS_BITCODE_OBJ=($(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-bcanalyzer $(1)) EXTRACT_OBJS=(cd $(TMPDIR); rm -f ./*.o; $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-ar x $(1)) -BUILD_LIB=$(RUSTC) lib.rs -Copt-level=2 -Z cross-lang-lto=on -Ccodegen-units=1 -BUILD_EXE=$(RUSTC) main.rs -Copt-level=2 -Z cross-lang-lto=on -Ccodegen-units=1 --emit=obj +BUILD_LIB=$(RUSTC) lib.rs -Copt-level=2 -Clinker-plugin-lto -Ccodegen-units=1 +BUILD_EXE=$(RUSTC) main.rs -Copt-level=2 -Clinker-plugin-lto -Ccodegen-units=1 --emit=obj all: staticlib staticlib-fat-lto staticlib-thin-lto rlib exe cdylib rdylib