diff --git a/CHANGELOG.md b/CHANGELOG.md index 95b83b6161..8480e3b27b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # LDC master #### Big news +- Linker-level dead code elimination is enabled by default for Apple, wasm and *all* ELF targets too now. (#4320) #### Platform support diff --git a/driver/linker-gcc.cpp b/driver/linker-gcc.cpp index a53936a9aa..85bd276189 100644 --- a/driver/linker-gcc.cpp +++ b/driver/linker-gcc.cpp @@ -479,6 +479,8 @@ void ArgsBuilder::addSanitizers(const llvm::Triple &triple) { void ArgsBuilder::build(llvm::StringRef outputPath, const std::vector &defaultLibNames) { + const auto &triple = *global.params.targetTriple; + // object files for (auto objfile : global.params.objfiles) { args.push_back(objfile); @@ -494,7 +496,7 @@ void ArgsBuilder::build(llvm::StringRef outputPath, // Link with profile-rt library when generating an instrumented binary. if (opts::isInstrumentingForPGO()) { - addProfileRuntimeLinkFlags(*global.params.targetTriple); + addProfileRuntimeLinkFlags(triple); } if (opts::enableDynamicCompile) { @@ -521,10 +523,10 @@ void ArgsBuilder::build(llvm::StringRef outputPath, args.push_back("-o"); args.push_back(std::string(outputPath)); - addSanitizers(*global.params.targetTriple); + addSanitizers(triple); if (opts::fXRayInstrument) { - addXRayLinkFlags(*global.params.targetTriple); + addXRayLinkFlags(triple); } // Add LTO link flags before adding the user link switches, such that the user @@ -559,16 +561,14 @@ void ArgsBuilder::build(llvm::StringRef outputPath, addLdFlag("-rpath", rpath); } - if (global.params.targetTriple->getOS() == llvm::Triple::Linux || - (global.params.targetTriple->getOS() == llvm::Triple::FreeBSD && - (useInternalLLDForLinking() || - (!opts::linker.empty() && opts::linker != "bfd") || - (opts::linker.empty() && isLldDefaultLinker())))) { - // Make sure we don't do --gc-sections when generating a profile- - // instrumented binary. The runtime relies on magic sections, which - // would be stripped by gc-section on older version of ld, see bug: - // https://sourceware.org/bugzilla/show_bug.cgi?id=19161 - if (!opts::disableLinkerStripDead && !opts::isInstrumentingForPGO()) { + // Make sure we don't do --gc-sections when generating a profile- + // instrumented binary. The runtime relies on magic sections, which + // would be stripped by gc-section on older version of ld, see bug: + // https://sourceware.org/bugzilla/show_bug.cgi?id=19161 + if (!opts::disableLinkerStripDead && !opts::isInstrumentingForPGO()) { + if (triple.isOSBinFormatMachO()) { + addLdFlag("-dead_strip"); + } else { addLdFlag("--gc-sections"); } } diff --git a/driver/targetmachine.cpp b/driver/targetmachine.cpp index 3bd7101d3d..9b45464dae 100644 --- a/driver/targetmachine.cpp +++ b/driver/targetmachine.cpp @@ -492,14 +492,14 @@ createTargetMachine(const std::string targetTriple, const std::string arch, break; } - // Right now, we only support linker-level dead code elimination on Linux - // and FreeBSD using GNU or LLD linkers (based on the --gc-sections flag). - // The Apple ld on OS X supports a similar flag (-dead_strip) that doesn't - // require emitting the symbols into different sections. The MinGW ld doesn't - // seem to support --gc-sections at all. - if (!noLinkerStripDead && (triple.getOS() == llvm::Triple::Linux || - triple.getOS() == llvm::Triple::FreeBSD || - triple.getOS() == llvm::Triple::Win32)) { + // Linker-level dead code elimination for ELF/wasm binaries using GNU or LLD + // linkers (based on the --gc-sections flag) requires a separate section per + // symbol. + // The Apple ld64 on macOS supports a similar flag (-dead_strip) that doesn't + // require emitting the symbols into different sections. + // On Windows, the MSVC link.exe / lld-link.exe has `/REF`; LLD enforces + // separate sections with LTO, so do the same here. + if (!noLinkerStripDead && !triple.isOSBinFormatMachO()) { targetOptions.FunctionSections = true; targetOptions.DataSections = true; }