1
Fork 0

Stabilize linker-plugin based LTO.

This commit is contained in:
Michael Woerister 2019-02-01 15:15:43 +01:00
parent a54b5c7a64
commit 04f425d2c3
13 changed files with 61 additions and 59 deletions

View file

@ -96,18 +96,18 @@ pub enum LtoCli {
} }
#[derive(Clone, PartialEq, Hash)] #[derive(Clone, PartialEq, Hash)]
pub enum CrossLangLto { pub enum LinkerPluginLto {
LinkerPlugin(PathBuf), LinkerPlugin(PathBuf),
LinkerPluginAuto, LinkerPluginAuto,
Disabled Disabled
} }
impl CrossLangLto { impl LinkerPluginLto {
pub fn enabled(&self) -> bool { pub fn enabled(&self) -> bool {
match *self { match *self {
CrossLangLto::LinkerPlugin(_) | LinkerPluginLto::LinkerPlugin(_) |
CrossLangLto::LinkerPluginAuto => true, LinkerPluginLto::LinkerPluginAuto => true,
CrossLangLto::Disabled => false, LinkerPluginLto::Disabled => false,
} }
} }
} }
@ -812,7 +812,7 @@ macro_rules! options {
pub const parse_lto: Option<&str> = pub const parse_lto: Option<&str> =
Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \ Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \
`fat`, or omitted"); `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), \ Some("either a boolean (`yes`, `no`, `on`, `off`, etc), \
or the path to the linker plugin"); or the path to the linker plugin");
pub const parse_merge_functions: Option<&str> = pub const parse_merge_functions: Option<&str> =
@ -821,7 +821,7 @@ macro_rules! options {
#[allow(dead_code)] #[allow(dead_code)]
mod $mod_set { 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 rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
@ -1037,22 +1037,22 @@ macro_rules! options {
true 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() { if v.is_some() {
let mut bool_arg = None; let mut bool_arg = None;
if parse_opt_bool(&mut bool_arg, v) { if parse_opt_bool(&mut bool_arg, v) {
*slot = if bool_arg.unwrap() { *slot = if bool_arg.unwrap() {
CrossLangLto::LinkerPluginAuto LinkerPluginLto::LinkerPluginAuto
} else { } else {
CrossLangLto::Disabled LinkerPluginLto::Disabled
}; };
return true return true
} }
} }
*slot = match v { *slot = match v {
None => CrossLangLto::LinkerPluginAuto, None => LinkerPluginLto::LinkerPluginAuto,
Some(path) => CrossLangLto::LinkerPlugin(PathBuf::from(path)), Some(path) => LinkerPluginLto::LinkerPlugin(PathBuf::from(path)),
}; };
true true
} }
@ -1145,6 +1145,10 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
"allow the linker to link its default libraries"), "allow the linker to link its default libraries"),
linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED], linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
"Linker flavor"), "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, options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
@ -1383,8 +1387,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"make the current crate share its generic instantiations"), "make the current crate share its generic instantiations"),
chalk: bool = (false, parse_bool, [TRACKED], chalk: bool = (false, parse_bool, [TRACKED],
"enable the experimental Chalk-based trait solving engine"), "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], no_parallel_llvm: bool = (false, parse_bool, [UNTRACKED],
"don't run LLVM in parallel (while keeping codegen-units and ThinLTO)"), "don't run LLVM in parallel (while keeping codegen-units and ThinLTO)"),
no_leak_check: bool = (false, parse_bool, [UNTRACKED], no_leak_check: bool = (false, parse_bool, [UNTRACKED],
@ -2440,7 +2442,7 @@ mod dep_tracking {
use std::path::PathBuf; use std::path::PathBuf;
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use super::{CrateType, DebugInfo, ErrorOutputType, OptLevel, OutputTypes, use super::{CrateType, DebugInfo, ErrorOutputType, OptLevel, OutputTypes,
Passes, Sanitizer, LtoCli, CrossLangLto}; Passes, Sanitizer, LtoCli, LinkerPluginLto};
use syntax::feature_gate::UnstableFeatures; use syntax::feature_gate::UnstableFeatures;
use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel, TargetTriple}; use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel, TargetTriple};
use syntax::edition::Edition; use syntax::edition::Edition;
@ -2507,7 +2509,7 @@ mod dep_tracking {
impl_dep_tracking_hash_via_hash!(Option<Sanitizer>); impl_dep_tracking_hash_via_hash!(Option<Sanitizer>);
impl_dep_tracking_hash_via_hash!(TargetTriple); impl_dep_tracking_hash_via_hash!(TargetTriple);
impl_dep_tracking_hash_via_hash!(Edition); 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!(String);
impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf); impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
@ -2572,7 +2574,7 @@ mod tests {
use crate::lint; use crate::lint;
use crate::middle::cstore; use crate::middle::cstore;
use crate::session::config::{build_configuration, build_session_options_and_crate_config}; 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::build_session;
use crate::session::search_paths::SearchPath; use crate::session::search_paths::SearchPath;
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
@ -3105,6 +3107,10 @@ mod tests {
opts = reference.clone(); opts = reference.clone();
opts.cg.panic = Some(PanicStrategy::Abort); opts.cg.panic = Some(PanicStrategy::Abort);
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); 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] #[test]
@ -3231,10 +3237,6 @@ mod tests {
opts.debugging_opts.relro_level = Some(RelroLevel::Full); opts.debugging_opts.relro_level = Some(RelroLevel::Full);
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); 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 = reference.clone();
opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled); opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled);
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());

View file

@ -1267,7 +1267,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
// bitcode during ThinLTO. Therefore we disallow dynamic linking on MSVC // bitcode during ThinLTO. Therefore we disallow dynamic linking on MSVC
// when compiling for LLD ThinLTO. This way we can validly just not generate // when compiling for LLD ThinLTO. This way we can validly just not generate
// the `dllimport` attributes and `__imp_` symbols in that case. // 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.opts.cg.prefer_dynamic &&
sess.target.target.options.is_like_msvc { sess.target.target.options.is_like_msvc {
sess.err("Linker plugin based LTO is not supported together with \ sess.err("Linker plugin based LTO is not supported together with \

View file

@ -857,7 +857,7 @@ fn link_args(cmd: &mut dyn Linker,
codegen_results: &CodegenResults) { codegen_results: &CodegenResults) {
// Linker plugins should be specified early in the list of arguments // 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 default library location, we need this to find the runtime.
// The location of crates will be determined as needed. // 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 => { Lto::Thin => {
// If we defer LTO to the linker, we haven't run LTO ourselves, so // If we defer LTO to the linker, we haven't run LTO ourselves, so
// any upstream object files have not been copied yet. // 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::No |
Lto::ThinLocal => false, Lto::ThinLocal => false,

View file

@ -159,7 +159,7 @@ pub(crate) fn run_thin(cgcx: &CodegenContext<LlvmCodegenBackend>,
let symbol_white_list = symbol_white_list.iter() let symbol_white_list = symbol_white_list.iter()
.map(|c| c.as_ptr()) .map(|c| c.as_ptr())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
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 \ unreachable!("We should never reach this case if the LTO step \
is deferred to the linker"); is deferred to the linker");
} }

View file

@ -366,7 +366,7 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
let opt_level = config.opt_level.map(|x| to_llvm_opt_settings(x).0) let opt_level = config.opt_level.map(|x| to_llvm_opt_settings(x).0)
.unwrap_or(llvm::CodeGenOptLevel::None); .unwrap_or(llvm::CodeGenOptLevel::None);
let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal || 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| { with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| {
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm); llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm); llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm);

View file

@ -275,12 +275,12 @@ impl CodegenCx<'ll, 'tcx> {
self.use_dll_storage_attrs && !self.tcx.is_foreign_item(def_id) && 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 // ThinLTO can't handle this workaround in all cases, so we don't
// emit the attrs. Instead we make them unnecessary by disallowing // emit the attrs. Instead we make them unnecessary by disallowing
// dynamic linking when cross-language LTO is enabled. // dynamic linking when linker plugin based LTO is enabled.
!self.tcx.sess.opts.debugging_opts.cross_lang_lto.enabled(); !self.tcx.sess.opts.cg.linker_plugin_lto.enabled();
// If this assertion triggers, there's something wrong with commandline // If this assertion triggers, there's something wrong with commandline
// argument validation. // 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.target.target.options.is_like_msvc &&
self.tcx.sess.opts.cg.prefer_dynamic)); self.tcx.sess.opts.cg.prefer_dynamic));

View file

@ -13,7 +13,7 @@ use rustc::hir::def_id::{LOCAL_CRATE, CrateNum};
use rustc::middle::dependency_format::Linkage; use rustc::middle::dependency_format::Linkage;
use rustc::session::Session; use rustc::session::Session;
use rustc::session::config::{self, CrateType, OptLevel, DebugInfo, use rustc::session::config::{self, CrateType, OptLevel, DebugInfo,
CrossLangLto, Lto}; LinkerPluginLto, Lto};
use rustc::ty::TyCtxt; use rustc::ty::TyCtxt;
use rustc_target::spec::{LinkerFlavor, LldFlavor}; use rustc_target::spec::{LinkerFlavor, LldFlavor};
use serialize::{json, Encoder}; use serialize::{json, Encoder};
@ -127,7 +127,7 @@ pub trait Linker {
fn subsystem(&mut self, subsystem: &str); fn subsystem(&mut self, subsystem: &str);
fn group_start(&mut self); fn group_start(&mut self);
fn group_end(&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?). // Should have been finalize(self), but we don't support self-by-value on trait objects (yet?).
fn finalize(&mut self) -> Command; 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 { if let Some(plugin_path) = plugin_path {
let mut arg = OsString::from("-plugin="); let mut arg = OsString::from("-plugin=");
arg.push(plugin_path); arg.push(plugin_path);
@ -454,16 +454,16 @@ impl<'a> Linker for GccLinker<'a> {
} }
} }
fn cross_lang_lto(&mut self) { fn linker_plugin_lto(&mut self) {
match self.sess.opts.debugging_opts.cross_lang_lto { match self.sess.opts.cg.linker_plugin_lto {
CrossLangLto::Disabled => { LinkerPluginLto::Disabled => {
// Nothing to do // Nothing to do
} }
CrossLangLto::LinkerPluginAuto => { LinkerPluginLto::LinkerPluginAuto => {
self.push_cross_lang_lto_args(None); self.push_linker_plugin_lto_args(None);
} }
CrossLangLto::LinkerPlugin(ref path) => { LinkerPluginLto::LinkerPlugin(ref path) => {
self.push_cross_lang_lto_args(Some(path.as_os_str())); 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_start(&mut self) {}
fn group_end(&mut self) {} fn group_end(&mut self) {}
fn cross_lang_lto(&mut self) { fn linker_plugin_lto(&mut self) {
// Do nothing // Do nothing
} }
} }
@ -865,7 +865,7 @@ impl<'a> Linker for EmLinker<'a> {
fn group_start(&mut self) {} fn group_start(&mut self) {}
fn group_end(&mut self) {} fn group_end(&mut self) {}
fn cross_lang_lto(&mut self) { fn linker_plugin_lto(&mut self) {
// Do nothing // Do nothing
} }
} }
@ -1047,7 +1047,7 @@ impl<'a> Linker for WasmLd<'a> {
fn group_start(&mut self) {} fn group_start(&mut self) {}
fn group_end(&mut self) {} fn group_end(&mut self) {}
fn cross_lang_lto(&mut self) { fn linker_plugin_lto(&mut self) {
// Do nothing for now // Do nothing for now
} }
} }

View file

@ -126,7 +126,7 @@ impl ModuleConfig {
self.time_passes = sess.time_passes(); self.time_passes = sess.time_passes();
self.inline_threshold = sess.opts.cg.inline_threshold; self.inline_threshold = sess.opts.cg.inline_threshold;
self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode || 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 || let embed_bitcode = sess.target.target.options.embed_bitcode ||
sess.opts.debugging_opts.embed_bitcode; sess.opts.debugging_opts.embed_bitcode;
if embed_bitcode { if embed_bitcode {
@ -737,7 +737,7 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
// If the linker does LTO, we don't have to do it. Note that we // 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 // keep doing full LTO, if it is requested, as not to break the
// assumption that the output will be a single module. // 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 // When we're automatically doing ThinLTO for multi-codegen-unit
// builds we don't actually want to LTO the allocator modules if // 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 { fn msvc_imps_needed(tcx: TyCtxt) -> bool {
// This should never be true (because it's not supported). If it is true, // This should never be true (because it's not supported). If it is true,
// something is wrong with commandline arg validation. // 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.target.target.options.is_like_msvc &&
tcx.sess.opts.cg.prefer_dynamic)); 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) && 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 // ThinLTO can't handle this workaround in all cases, so we don't
// emit the `__imp_` symbols. Instead we make them unnecessary by disallowing // emit the `__imp_` symbols. Instead we make them unnecessary by disallowing
// dynamic linking when cross-language LTO is enabled. // dynamic linking when linker plugin LTO is enabled.
!tcx.sess.opts.debugging_opts.cross_lang_lto.enabled() !tcx.sess.opts.cg.linker_plugin_lto.enabled()
} }

View file

@ -3,7 +3,7 @@
// no-prefer-dynamic // no-prefer-dynamic
// only-msvc // only-msvc
// compile-flags: -Z cross-lang-lto // compile-flags: -C linker-plugin-lto
#![crate_type = "rlib"] #![crate_type = "rlib"]

View file

@ -3,7 +3,7 @@
// no-prefer-dynamic // no-prefer-dynamic
// ignore-tidy-linelength // 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"] #![crate_type = "staticlib"]

View file

@ -8,7 +8,7 @@
all: cpp-executable rust-executable all: cpp-executable rust-executable
cpp-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 $(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 # Make sure we don't find a call instruction to the function we expect to
# always be inlined. # always be inlined.
@ -20,6 +20,6 @@ cpp-executable:
rust-executable: rust-executable:
$(CLANG) ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2 $(CLANG) ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2
(cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o) (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) -e "call.*c_never_inlined"
llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -v -e "call.*c_always_inlined" llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -v -e "call.*c_always_inlined"

View file

@ -5,13 +5,13 @@
ifndef IS_WINDOWS ifndef IS_WINDOWS
# This test makes sure that we don't loose upstream object files when compiling # 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 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 # 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) (cd $(TMPDIR); $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-ar x ./staticlib.a)
# Make sure the upstream object file was included # Make sure the upstream object file was included
ls $(TMPDIR)/upstream.*.rcgu.o ls $(TMPDIR)/upstream.*.rcgu.o
@ -20,8 +20,8 @@ all: staticlib.rs upstream.rs
rm $(TMPDIR)/* rm $(TMPDIR)/*
# Check ThinLTO # Check ThinLTO
$(RUSTC) upstream.rs -Z cross-lang-lto -Ccodegen-units=1 -Clto=thin $(RUSTC) upstream.rs -C linker-plugin-lto -Ccodegen-units=1 -Clto=thin
$(RUSTC) staticlib.rs -Z cross-lang-lto -Ccodegen-units=1 -Clto=thin -L. -o $(TMPDIR)/staticlib.a $(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) (cd $(TMPDIR); $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-ar x ./staticlib.a)
ls $(TMPDIR)/upstream.*.rcgu.o ls $(TMPDIR)/upstream.*.rcgu.o

View file

@ -7,14 +7,14 @@ ifndef IS_WINDOWS
# This test makes sure that the object files we generate are actually # This test makes sure that the object files we generate are actually
# LLVM bitcode files (as used by linker LTO plugins) when compiling with # 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 # this only succeeds for bitcode files
ASSERT_IS_BITCODE_OBJ=($(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-bcanalyzer $(1)) 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)) 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_LIB=$(RUSTC) lib.rs -Copt-level=2 -Clinker-plugin-lto -Ccodegen-units=1
BUILD_EXE=$(RUSTC) main.rs -Copt-level=2 -Z cross-lang-lto=on -Ccodegen-units=1 --emit=obj 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 all: staticlib staticlib-fat-lto staticlib-thin-lto rlib exe cdylib rdylib