diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index f01a6514f6eff..8c666e2cb463c 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -996,9 +996,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline( } if (CodeGenOpts.FatLTO) { - MPM.addPass(PB.buildFatLTODefaultPipeline( - Level, PrepareForThinLTO, - PrepareForThinLTO || shouldEmitRegularLTOSummary())); + assert(CodeGenOpts.UnifiedLTO && "FatLTO requires UnifiedLTO"); + MPM.addPass(PB.buildFatLTODefaultPipeline(Level)); } else if (PrepareForThinLTO) { MPM.addPass(PB.buildThinLTOPreLinkDefaultPipeline(Level)); } else if (PrepareForLTO) { @@ -1042,7 +1041,6 @@ void EmitAssemblyHelper::RunOptimizationPipeline( MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists, /*EmitLTOSummary=*/true)); } - } else { // Emit a module summary by default for Regular LTO except for ld64 // targets @@ -1073,7 +1071,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline( if (!TheModule->getModuleFlag("EnableSplitLTOUnit")) TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit", uint32_t(CodeGenOpts.EnableSplitLTOUnit)); - if (CodeGenOpts.UnifiedLTO && !TheModule->getModuleFlag("UnifiedLTO")) + // FatLTO always means UnifiedLTO + if (!TheModule->getModuleFlag("UnifiedLTO")) TheModule->addModuleFlag(llvm::Module::Error, "UnifiedLTO", uint32_t(1)); } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 3c8df8a9037d6..b1ce95be38f88 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4862,7 +4862,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, bool UnifiedLTO = false; if (IsUsingLTO) { UnifiedLTO = Args.hasFlag(options::OPT_funified_lto, - options::OPT_fno_unified_lto, Triple.isPS()); + options::OPT_fno_unified_lto, Triple.isPS()) || + Args.hasFlag(options::OPT_ffat_lto_objects, + options::OPT_fno_fat_lto_objects, false); if (UnifiedLTO) CmdArgs.push_back("-funified-lto"); } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 5a8e4cf9843de..a6188cb45e178 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1861,6 +1861,20 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, if (Args.hasArg(OPT_funified_lto)) Opts.PrepareForThinLTO = true; } + if (Arg *A = Args.getLastArg(options::OPT_ffat_lto_objects, + options::OPT_fno_fat_lto_objects)) { + if (A->getOption().matches(options::OPT_ffat_lto_objects)) { + if (Arg *Uni = Args.getLastArg(options::OPT_funified_lto, + options::OPT_fno_unified_lto)) { + if (Uni->getOption().matches(options::OPT_fno_unified_lto)) + Diags.Report(diag::err_drv_incompatible_options) + << A->getAsString(Args) << "-fno-unified-lto"; + } else + Diags.Report(diag::err_drv_argument_only_allowed_with) + << A->getAsString(Args) << "-funified-lto"; + } + } + if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) { if (IK.getLanguage() != Language::LLVM_IR) Diags.Report(diag::err_drv_argument_only_allowed_with) diff --git a/clang/test/CodeGen/fat-lto-objects.c b/clang/test/CodeGen/fat-lto-objects.c index 2c3a4ef9c6155..95207e77c244c 100644 --- a/clang/test/CodeGen/fat-lto-objects.c +++ b/clang/test/CodeGen/fat-lto-objects.c @@ -1,49 +1,47 @@ // REQUIRES: x86-registered-target -// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -fsplit-lto-unit -emit-llvm < %s | FileCheck %s --check-prefixes=FULL,SPLIT -// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=FULL,SPLIT +// RUN: not %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -fsplit-lto-unit -emit-llvm < %s 2>&1 | FileCheck %s --check-prefixes=NO-UNIFIED -// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -fsplit-lto-unit -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=THIN,SPLIT -// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=THIN,NOSPLIT +// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -funified-lto -ffat-lto-objects -fsplit-lto-unit -emit-llvm < %s | FileCheck %s --check-prefixes=FULL,SPLIT,UNIFIED +// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -funified-lto -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=FULL,NOSPLIT,UNIFIED -// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -fsplit-lto-unit -emit-obj < %s -o %t.full.split.o +// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -funified-lto -fsplit-lto-unit -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=THIN,SPLIT,UNIFIED +// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -funified-lto -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=THIN,NOSPLIT,UNIFIED + +// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -funified-lto -ffat-lto-objects -fsplit-lto-unit -emit-obj < %s -o %t.full.split.o // RUN: llvm-readelf -S %t.full.split.o | FileCheck %s --check-prefixes=ELF // RUN: llvm-objcopy --dump-section=.llvm.lto=%t.full.split.bc %t.full.split.o -// RUN: llvm-dis %t.full.split.bc -o - | FileCheck %s --check-prefixes=FULL,SPLIT,NOUNIFIED +// RUN: llvm-dis %t.full.split.bc -o - | FileCheck %s --check-prefixes=THIN,SPLIT,UNIFIED -// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -emit-obj < %s -o %t.full.nosplit.o +// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -funified-lto -ffat-lto-objects -emit-obj < %s -o %t.full.nosplit.o // RUN: llvm-readelf -S %t.full.nosplit.o | FileCheck %s --check-prefixes=ELF // RUN: llvm-objcopy --dump-section=.llvm.lto=%t.full.nosplit.bc %t.full.nosplit.o -// RUN: llvm-dis %t.full.nosplit.bc -o - | FileCheck %s --check-prefixes=FULL,NOSPLIT,NOUNIFIED +// RUN: llvm-dis %t.full.nosplit.bc -o - | FileCheck %s --check-prefixes=THIN,NOSPLIT,UNIFIED -// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -fsplit-lto-unit -ffat-lto-objects -emit-obj < %s -o %t.thin.split.o +// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -funified-lto -fsplit-lto-unit -ffat-lto-objects -emit-obj < %s -o %t.thin.split.o // RUN: llvm-readelf -S %t.thin.split.o | FileCheck %s --check-prefixes=ELF // RUN: llvm-objcopy --dump-section=.llvm.lto=%t.thin.split.bc %t.thin.split.o -// RUN: llvm-dis %t.thin.split.bc -o - | FileCheck %s --check-prefixes=THIN,SPLIT,NOUNIFIED +// RUN: llvm-dis %t.thin.split.bc -o - | FileCheck %s --check-prefixes=THIN,SPLIT,UNIFIED -// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -ffat-lto-objects -emit-obj < %s -o %t.thin.nosplit.o +// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -funified-lto -ffat-lto-objects -emit-obj < %s -o %t.thin.nosplit.o // RUN: llvm-readelf -S %t.thin.nosplit.o | FileCheck %s --check-prefixes=ELF // RUN: llvm-objcopy --dump-section=.llvm.lto=%t.thin.nosplit.bc %t.thin.nosplit.o -// RUN: llvm-dis %t.thin.nosplit.bc -o - | FileCheck %s --check-prefixes=THIN,NOSPLIT,NOUNIFIED - -// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -funified-lto -ffat-lto-objects -emit-obj < %s -o %t.unified.o -// RUN: llvm-readelf -S %t.unified.o | FileCheck %s --check-prefixes=ELF -// RUN: llvm-objcopy --dump-section=.llvm.lto=%t.unified.bc %t.unified.o -// RUN: llvm-dis %t.unified.bc -o - | FileCheck %s --check-prefixes=THIN,NOSPLIT,UNIFIED +// RUN: llvm-dis %t.thin.nosplit.bc -o - | FileCheck %s --check-prefixes=THIN,NOSPLIT,UNIFIED -// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -fsplit-lto-unit -S < %s -o - \ +// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -funified-lto -ffat-lto-objects -fsplit-lto-unit -S < %s -o - \ // RUN: | FileCheck %s --check-prefixes=ASM -/// Check that the ThinLTO metadata is only set false for full LTO. -// FULL: ![[#]] = !{i32 1, !"ThinLTO", i32 0} -// THIN-NOT: ![[#]] = !{i32 1, !"ThinLTO", i32 0} - /// Be sure we enable split LTO units correctly under -ffat-lto-objects. -// SPLIT: ![[#]] = !{i32 1, !"EnableSplitLTOUnit", i32 1} +// SPLIT: ![[#]] = !{i32 1, !"EnableSplitLTOUnit", i32 1} // NOSPLIT: ![[#]] = !{i32 1, !"EnableSplitLTOUnit", i32 0} -// UNIFIED: ![[#]] = !{i32 1, !"UnifiedLTO", i32 1} -// NOUNIFIED-NOT: ![[#]] = !{i32 1, !"UnifiedLTO", i32 1} +/// Check that the ThinLTO metadata is set true for both full and thin LTO, since FatLTO is based on UnifiedLTO. +// FULL: ![[#]] = !{i32 1, !"ThinLTO", i32 1} +// THIN-NOT: ![[#]] = !{i32 1, !"ThinLTO", i32 0} + +/// FatLTO always uses UnifiedLTO. It's an error if they aren't set together +// UNIFIED: ![[#]] = !{i32 1, !"UnifiedLTO", i32 1} +// NO-UNIFIED: error: invalid argument '-ffat-lto-objects' only allowed with '-funified-lto' // ELF: .llvm.lto diff --git a/clang/test/Driver/fat-lto-objects.c b/clang/test/Driver/fat-lto-objects.c index 887c33fa76d71..e02359db3f0ae 100644 --- a/clang/test/Driver/fat-lto-objects.c +++ b/clang/test/Driver/fat-lto-objects.c @@ -1,5 +1,6 @@ // RUN: %clang --target=x86_64-unknown-linux-gnu -flto -ffat-lto-objects -### %s -c 2>&1 | FileCheck %s -check-prefix=CHECK-CC // CHECK-CC: -cc1 +// CHECK-CC-SAME: -funified-lto // CHECK-CC-SAME: -emit-obj // CHECK-CC-SAME: -ffat-lto-objects @@ -15,6 +16,7 @@ // RUN: %clang --target=x86_64-unknown-linux-gnu -flto -ffat-lto-objects -### %s -S 2>&1 | FileCheck %s -check-prefix=CHECK-CC-S-LTO // RUN: %clang --target=x86_64-unknown-linux-gnu -flto -ffat-lto-objects -### %s -S -emit-llvm 2>&1 | FileCheck %s -check-prefix=CHECK-CC-S-LTO // CHECK-CC-S-LTO: -cc1 +// CHECK-CC-S-LTO-SAME: -funified-lto // CHECK-CC-S-LTO-SAME: -emit-llvm // CHECK-CC-S-LTO-SAME: -ffat-lto-objects @@ -32,3 +34,13 @@ // RUN: -fuse-ld=lld -fno-lto -ffat-lto-objects -### 2>&1 | FileCheck --check-prefix=NOLTO %s // LTO: "--fat-lto-objects" // NOLTO-NOT: "--fat-lto-objects" + +/// Make sure that incompatible options emit the correct diagnostics, since -ffat-lto-objects requires -funified-lto +// RUN: %clang -cc1 -triple=x86_64-unknown-linux-gnu -flto -ffat-lto-objects -funified-lto -emit-llvm-only %s 2>&1 | FileCheck %s -check-prefix=UNIFIED --allow-empty +// UNIFIED-NOT: error: + +// RUN: not %clang -cc1 -triple=x86_64-unknown-linux-gnu -flto -ffat-lto-objects -emit-llvm-only %s 2>&1 | FileCheck %s -check-prefix=MISSING_UNIFIED +// MISSING_UNIFIED: error: invalid argument '-ffat-lto-objects' only allowed with '-funified-lto' + +// RUN: not %clang -cc1 -triple=x86_64-unknown-linux-gnu -flto -fno-unified-lto -ffat-lto-objects -emit-llvm-only %s 2>&1 | FileCheck %s -check-prefix=NO-UNIFIED +// NO-UNIFIED: error: the combination of '-ffat-lto-objects' and '-fno-unified-lto' is incompatible diff --git a/llvm/docs/FatLTO.rst b/llvm/docs/FatLTO.rst index b505bb2a96fe1..21da24504bcdf 100644 --- a/llvm/docs/FatLTO.rst +++ b/llvm/docs/FatLTO.rst @@ -29,30 +29,31 @@ Overview Within LLVM, FatLTO is supported by choosing the ``FatLTODefaultPipeline``. This pipeline will: -#) Clone the IR module. -#) Run the pre-link (Thin)LTO pipeline using the cloned module. +#) Run the pre-link UnifiedLTO pipeline on the current module. #) Embed the pre-link bitcode in a special ``.llvm.lto`` section. -#) Optimize the unmodified copy of the module using the normal compilation pipeline. +#) Finish optimizing the module using the post-link ThinLTO pipeline. #) Emit the object file, including the new ``.llvm.lto`` section. .. NOTE - At the time of writing, we conservatively run independent pipelines to - generate the bitcode section and the object code, which happen to be - identical to those used outside of FatLTO. This results in compiled - artifacts that are identical to those produced by the default and (Thin)LTO - pipelines. However, this is not a guarantee, and we reserve the right to - change this at any time. Explicitly, users should not rely on the produced - bitcode or object code to mach their non-LTO counterparts precisely. They - will exhibit similar performance characteristics, but may not be bit-for-bit - the same. + Previously, we conservatively ran independent pipelines on separate copies + of the LLVM module to generate the bitcode section and the object code, + which happen to be identical to those used outside of FatLTO. While that + resulted in compiled artifacts that were identical to those produced by the + default and (Thin)LTO pipelines, module cloning led to some cases of + miscompilation, and we have moved away from trying to keep bitcode + generation and optimization completely disjoint. + + Bit-for-bit compatibility is not (and never was) a guarantee, and we reserve + the right to change this at any time. Explicitly, users should not rely on + the produced bitcode or object code to match their non-LTO counterparts + precisely. They will exhibit similar performance characteristics, but may + not be bit-for-bit the same. Internally, the ``.llvm.lto`` section is created by running the -``EmbedBitcodePass`` at the start of the ``PerModuleDefaultPipeline``. This -pass is responsible for cloning and optimizing the module with the appropriate -LTO pipeline and emitting the ``.llvm.lto`` section. Afterwards, the -``PerModuleDefaultPipeline`` runs normally and the compiler can emit the fat -object file. +``EmbedBitcodePass`` after the ``ThinLTOPreLinkDefaultPipeline``. This pass is +responsible for emitting the ``.llvm.lto`` section. Afterwards, the +``ThinLTODefaultPipeline`` runs and the compiler can emit the fat object file. Limitations =========== diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h index 23bc891a8f1e9..19ac90842bcb0 100644 --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -246,8 +246,7 @@ class PassBuilder { /// separately to avoid any inconsistencies with an ad-hoc pipeline that tries /// to approximate the PerModuleDefaultPipeline from the pre-link LTO /// pipelines. - ModulePassManager buildFatLTODefaultPipeline(OptimizationLevel Level, - bool ThinLTO, bool EmitSummary); + ModulePassManager buildFatLTODefaultPipeline(OptimizationLevel Level); /// Build a pre-link, ThinLTO-targeting default optimization pipeline to /// a pass manager. diff --git a/llvm/include/llvm/Transforms/IPO/EmbedBitcodePass.h b/llvm/include/llvm/Transforms/IPO/EmbedBitcodePass.h index f323c61483fd3..c35048c91aba2 100644 --- a/llvm/include/llvm/Transforms/IPO/EmbedBitcodePass.h +++ b/llvm/include/llvm/Transforms/IPO/EmbedBitcodePass.h @@ -25,28 +25,13 @@ class Module; class ModulePass; class Pass; -struct EmbedBitcodeOptions { - EmbedBitcodeOptions() : EmbedBitcodeOptions(false, false) {} - EmbedBitcodeOptions(bool IsThinLTO, bool EmitLTOSummary) - : IsThinLTO(IsThinLTO), EmitLTOSummary(EmitLTOSummary) {} - bool IsThinLTO; - bool EmitLTOSummary; -}; - /// Pass embeds a copy of the module optimized with the provided pass pipeline /// into a global variable. class EmbedBitcodePass : public PassInfoMixin { - bool IsThinLTO; - bool EmitLTOSummary; ModulePassManager MPM; public: - EmbedBitcodePass(EmbedBitcodeOptions Opts) - : EmbedBitcodePass(Opts.IsThinLTO, Opts.EmitLTOSummary, - ModulePassManager()) {} - EmbedBitcodePass(bool IsThinLTO, bool EmitLTOSummary, ModulePassManager &&MPM) - : IsThinLTO(IsThinLTO), EmitLTOSummary(EmitLTOSummary), - MPM(std::move(MPM)) {} + EmbedBitcodePass() {} PreservedAnalyses run(Module &M, ModuleAnalysisManager &); diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index aeb9726a186b5..98a679177c23d 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -759,26 +759,6 @@ Expected parseHWASanPassOptions(StringRef Params) { return Result; } -Expected parseEmbedBitcodePassOptions(StringRef Params) { - EmbedBitcodeOptions Result; - while (!Params.empty()) { - StringRef ParamName; - std::tie(ParamName, Params) = Params.split(';'); - - if (ParamName == "thinlto") { - Result.IsThinLTO = true; - } else if (ParamName == "emit-summary") { - Result.EmitLTOSummary = true; - } else { - return make_error( - formatv("invalid EmbedBitcode pass parameter '{0}' ", ParamName) - .str(), - inconvertibleErrorCode()); - } - } - return Result; -} - Expected parseMSanPassOptions(StringRef Params) { MemorySanitizerOptions Result; while (!Params.empty()) { diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp index f3d280316e040..e7f88680655c1 100644 --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -1530,14 +1530,22 @@ PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level, } ModulePassManager -PassBuilder::buildFatLTODefaultPipeline(OptimizationLevel Level, bool ThinLTO, - bool EmitSummary) { +PassBuilder::buildFatLTODefaultPipeline(OptimizationLevel Level) { ModulePassManager MPM; - MPM.addPass(EmbedBitcodePass(ThinLTO, EmitSummary, - ThinLTO - ? buildThinLTOPreLinkDefaultPipeline(Level) - : buildLTOPreLinkDefaultPipeline(Level))); - MPM.addPass(buildPerModuleDefaultPipeline(Level)); + // FatLTO always uses UnifiedLTO, so use the ThinLTOPreLink pipeline + MPM.addPass(buildThinLTOPreLinkDefaultPipeline(Level)); + MPM.addPass(EmbedBitcodePass()); + + // Use the ThinLTO post-link pipeline with sample profiling, other + if (PGOOpt && PGOOpt->Action == PGOOptions::SampleUse) + MPM.addPass(buildThinLTODefaultPipeline(Level, /*ImportSummary=*/nullptr)); + else { + // otherwise, just use module optimization + MPM.addPass( + buildModuleOptimizationPipeline(Level, ThinOrFullLTOPhase::None)); + // Emit annotation remarks. + addAnnotationRemarksPass(MPM); + } return MPM; } diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 1f1bc3222468b..2abc2920264a6 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -58,6 +58,7 @@ MODULE_PASS("dfsan", DataFlowSanitizerPass()) MODULE_PASS("dot-callgraph", CallGraphDOTPrinterPass()) MODULE_PASS("dxil-upgrade", DXILUpgradePass()) MODULE_PASS("elim-avail-extern", EliminateAvailableExternallyPass()) +MODULE_PASS("embed-bitcode", EmbedBitcodePass()) MODULE_PASS("extract-blocks", BlockExtractorPass({}, false)) MODULE_PASS("forceattrs", ForceFunctionAttrsPass()) MODULE_PASS("function-import", FunctionImportPass()) @@ -145,10 +146,6 @@ MODULE_PASS_WITH_PARAMS( "asan", "AddressSanitizerPass", [](AddressSanitizerOptions Opts) { return AddressSanitizerPass(Opts); }, parseASanPassOptions, "kernel") -MODULE_PASS_WITH_PARAMS( - "embed-bitcode", "EmbedBitcodePass", - [](EmbedBitcodeOptions Opts) { return EmbedBitcodePass(Opts); }, - parseEmbedBitcodePassOptions, "thinlto;emit-summary") MODULE_PASS_WITH_PARAMS( "globaldce", "GlobalDCEPass", [](bool InLTOPostLink) { return GlobalDCEPass(InLTOPostLink); }, diff --git a/llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp b/llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp index fa56a5b564ae6..48ef0772e800e 100644 --- a/llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp +++ b/llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp @@ -7,8 +7,6 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO/EmbedBitcodePass.h" -#include "llvm/Bitcode/BitcodeWriter.h" -#include "llvm/Bitcode/BitcodeWriterPass.h" #include "llvm/IR/PassManager.h" #include "llvm/Pass.h" #include "llvm/Support/ErrorHandling.h" @@ -16,10 +14,8 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Triple.h" #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" -#include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/ModuleUtils.h" -#include #include using namespace llvm; @@ -34,19 +30,9 @@ PreservedAnalyses EmbedBitcodePass::run(Module &M, ModuleAnalysisManager &AM) { report_fatal_error( "EmbedBitcode pass currently only supports ELF object format", /*gen_crash_diag=*/false); - - std::unique_ptr NewModule = CloneModule(M); - MPM.run(*NewModule, AM); - std::string Data; raw_string_ostream OS(Data); - if (IsThinLTO) - ThinLTOBitcodeWriterPass(OS, /*ThinLinkOS=*/nullptr).run(*NewModule, AM); - else - BitcodeWriterPass(OS, /*ShouldPreserveUseListOrder=*/false, EmitLTOSummary) - .run(*NewModule, AM); - + ThinLTOBitcodeWriterPass(OS, /*ThinLinkOS=*/nullptr).run(M, AM); embedBufferInModule(M, MemoryBufferRef(Data, "ModuleData"), ".llvm.lto"); - return PreservedAnalyses::all(); } diff --git a/llvm/test/CodeGen/X86/fat-lto-section.ll b/llvm/test/CodeGen/X86/fat-lto-section.ll index 30c56229a0e2a..9a4359bab6b5d 100644 --- a/llvm/test/CodeGen/X86/fat-lto-section.ll +++ b/llvm/test/CodeGen/X86/fat-lto-section.ll @@ -1,5 +1,5 @@ ;; Ensure that the .llvm.lto section has SHT_EXCLUDE set. -; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode" -S \ +; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode" -S \ ; RUN: | llc --mtriple x86_64-unknown-linux-gnu -filetype=obj \ ; RUN: | llvm-readelf - --sections \ ; RUN: | FileCheck %s --check-prefix=EXCLUDE diff --git a/llvm/test/Transforms/EmbedBitcode/embed.ll b/llvm/test/Transforms/EmbedBitcode/embed.ll index dffb5cf755477..734bf5274a5f2 100644 --- a/llvm/test/Transforms/EmbedBitcode/embed.ll +++ b/llvm/test/Transforms/EmbedBitcode/embed.ll @@ -1,7 +1,4 @@ ; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode" -S | FileCheck %s -; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode" -S | FileCheck %s -; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode" -S | FileCheck %s -; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode" -S | FileCheck %s @a = global i32 1