diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 44fb8dbb4ce5c..3669ba0c2f5cc 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -152,6 +152,12 @@ pub mod write { (sess.targ_cfg.os == abi::OsMacos && sess.targ_cfg.arch == abi::X86_64); + // OSX has -dead_strip, which doesn't rely on ffunction_sections + // FIXME(#13846) this should be enabled for windows + let ffunction_sections = sess.targ_cfg.os != abi::OsMacos && + sess.targ_cfg.os != abi::OsWin32; + let fdata_sections = ffunction_sections; + let reloc_model = match sess.opts.cg.relocation_model.as_slice() { "pic" => lib::llvm::RelocPIC, "static" => lib::llvm::RelocStatic, @@ -173,9 +179,11 @@ pub mod write { lib::llvm::CodeModelDefault, reloc_model, opt_level, - true, + true /* EnableSegstk */, use_softfp, - no_fp_elim + no_fp_elim, + ffunction_sections, + fdata_sections, ) }) }) @@ -1136,16 +1144,22 @@ fn link_args(sess: &Session, args.push("-nodefaultlibs".to_owned()); } + // If we're building a dylib, we don't use --gc-sections because LLVM has + // already done the best it can do, and we also don't want to eliminate the + // metadata. If we're building an executable, however, --gc-sections drops + // the size of hello world from 1.8MB to 597K, a 67% reduction. + if !dylib && sess.targ_cfg.os != abi::OsMacos { + args.push("-Wl,--gc-sections".to_owned()); + } + if sess.targ_cfg.os == abi::OsLinux { // GNU-style linkers will use this to omit linking to libraries which // don't actually fulfill any relocations, but only for libraries which // follow this flag. Thus, use it before specifying libraries to link to. args.push("-Wl,--as-needed".to_owned()); - // GNU-style linkers support optimization with -O. --gc-sections - // removes metadata and potentially other useful things, so don't - // include it. GNU ld doesn't need a numeric argument, but other linkers - // do. + // GNU-style linkers support optimization with -O. GNU ld doesn't need a + // numeric argument, but other linkers do. if sess.opts.optimize == session::Default || sess.opts.optimize == session::Aggressive { args.push("-Wl,-O1".to_owned()); diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index ba7c50547947e..74e332a8db456 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -1748,7 +1748,9 @@ pub mod llvm { Level: CodeGenOptLevel, EnableSegstk: bool, UseSoftFP: bool, - NoFramePointerElim: bool) -> TargetMachineRef; + NoFramePointerElim: bool, + FunctionSections: bool, + DataSections: bool) -> TargetMachineRef; pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef); pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 021dda4976550..1031f3c1570e9 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -69,7 +69,9 @@ LLVMRustCreateTargetMachine(const char *triple, CodeGenOpt::Level OptLevel, bool EnableSegmentedStacks, bool UseSoftFloat, - bool NoFramePointerElim) { + bool NoFramePointerElim, + bool FunctionSections, + bool DataSections) { std::string Error; Triple Trip(Triple::normalize(triple)); const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(), @@ -97,6 +99,8 @@ LLVMRustCreateTargetMachine(const char *triple, RM, CM, OptLevel); + TM->setDataSections(DataSections); + TM->setFunctionSections(FunctionSections); return wrap(TM); } diff --git a/src/test/debug-info/basic-types-globals-metadata.rs b/src/test/debug-info/basic-types-globals-metadata.rs index efc6fda26e0c0..bf6d63f2ca92f 100644 --- a/src/test/debug-info/basic-types-globals-metadata.rs +++ b/src/test/debug-info/basic-types-globals-metadata.rs @@ -66,6 +66,8 @@ static F64: f64 = 3.5; fn main() { _zzz(); + + let a = (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F32, F64); } fn _zzz() {()} diff --git a/src/test/debug-info/basic-types-globals.rs b/src/test/debug-info/basic-types-globals.rs index 2a620e96892a7..cdc3132ca60b2 100644 --- a/src/test/debug-info/basic-types-globals.rs +++ b/src/test/debug-info/basic-types-globals.rs @@ -70,6 +70,8 @@ static F64: f64 = 3.5; fn main() { _zzz(); + + let a = (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F32, F64); } fn _zzz() {()} diff --git a/src/test/debug-info/basic-types-metadata.rs b/src/test/debug-info/basic-types-metadata.rs index e06af6445ccfb..ae5d3a84b966a 100644 --- a/src/test/debug-info/basic-types-metadata.rs +++ b/src/test/debug-info/basic-types-metadata.rs @@ -67,6 +67,7 @@ fn main() { let f32: f32 = 2.5; let f64: f64 = 3.5; _zzz(); + if 1 == 1 { _yyy(); } } fn _zzz() {()} diff --git a/src/test/debug-info/c-style-enum.rs b/src/test/debug-info/c-style-enum.rs index b570110d8d013..0a207881bd3b3 100644 --- a/src/test/debug-info/c-style-enum.rs +++ b/src/test/debug-info/c-style-enum.rs @@ -121,6 +121,10 @@ fn main() { }; zzz(); + + let a = SINGLE_VARIANT; + let a = unsafe { AUTO_ONE }; + let a = unsafe { MANUAL_ONE }; } fn zzz() {()} diff --git a/src/test/debug-info/limited-debuginfo.rs b/src/test/debug-info/limited-debuginfo.rs index 36ccc91e88b05..51d9aa75e078e 100644 --- a/src/test/debug-info/limited-debuginfo.rs +++ b/src/test/debug-info/limited-debuginfo.rs @@ -38,6 +38,7 @@ struct Struct { fn main() { some_function(101, 202); + some_other_function(1, 2); }