diff options
Diffstat (limited to 'llvm/lib/LTO/LTOBackend.cpp')
-rw-r--r-- | llvm/lib/LTO/LTOBackend.cpp | 106 |
1 files changed, 73 insertions, 33 deletions
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index dcde7277b820..0c395f9bbf28 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -16,18 +16,20 @@ #include "llvm/LTO/LTOBackend.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CGSCCPassManager.h" +#include "llvm/Analysis/ModuleSummaryAnalysis.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Bitcode/BitcodeWriter.h" +#include "llvm/IR/LLVMRemarkStreamer.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/PassManager.h" -#include "llvm/IR/RemarkStreamer.h" #include "llvm/IR/Verifier.h" #include "llvm/LTO/LTO.h" #include "llvm/MC/SubtargetFeature.h" #include "llvm/Object/ModuleSymbolTable.h" #include "llvm/Passes/PassBuilder.h" +#include "llvm/Passes/PassPlugin.h" #include "llvm/Passes/StandardInstrumentations.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" @@ -61,8 +63,10 @@ Error Config::addSaveTemps(std::string OutputFileName, std::error_code EC; ResolutionFile = std::make_unique<raw_fd_ostream>( OutputFileName + "resolution.txt", EC, sys::fs::OpenFlags::OF_Text); - if (EC) + if (EC) { + ResolutionFile.reset(); return errorCodeToError(EC); + } auto setHook = [&](std::string PathSuffix, ModuleHookFn &Hook) { // Keep track of the hook provided by the linker, which also needs to run. @@ -125,6 +129,29 @@ Error Config::addSaveTemps(std::string OutputFileName, return Error::success(); } +#define HANDLE_EXTENSION(Ext) \ + llvm::PassPluginLibraryInfo get##Ext##PluginInfo(); +#include "llvm/Support/Extension.def" + +static void RegisterPassPlugins(ArrayRef<std::string> PassPlugins, + PassBuilder &PB) { +#define HANDLE_EXTENSION(Ext) \ + get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB); +#include "llvm/Support/Extension.def" + + // Load requested pass plugins and let them register pass builder callbacks + for (auto &PluginFN : PassPlugins) { + auto PassPlugin = PassPlugin::Load(PluginFN); + if (!PassPlugin) { + errs() << "Failed to load passes from '" << PluginFN + << "'. Request ignored.\n"; + continue; + } + + PassPlugin->registerPassBuilderCallbacks(PB); + } +} + namespace { std::unique_ptr<TargetMachine> @@ -179,6 +206,8 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, if (auto Err = PB.parseAAPipeline(AA, "default")) report_fatal_error("Error parsing default AA pipeline"); + RegisterPassPlugins(Conf.PassPlugins, PB); + LoopAnalysisManager LAM(Conf.DebugPassManager); FunctionAnalysisManager FAM(Conf.DebugPassManager); CGSCCAnalysisManager CGAM(Conf.DebugPassManager); @@ -203,16 +232,16 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, default: llvm_unreachable("Invalid optimization level"); case 0: - OL = PassBuilder::O0; + OL = PassBuilder::OptimizationLevel::O0; break; case 1: - OL = PassBuilder::O1; + OL = PassBuilder::OptimizationLevel::O1; break; case 2: - OL = PassBuilder::O2; + OL = PassBuilder::OptimizationLevel::O2; break; case 3: - OL = PassBuilder::O3; + OL = PassBuilder::OptimizationLevel::O3; break; } @@ -226,8 +255,8 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, // FIXME (davide): verify the output. } -static void runNewPMCustomPasses(Module &Mod, TargetMachine *TM, - std::string PipelineDesc, +static void runNewPMCustomPasses(const Config &Conf, Module &Mod, + TargetMachine *TM, std::string PipelineDesc, std::string AAPipelineDesc, bool DisableVerify) { PassBuilder PB(TM); @@ -239,6 +268,8 @@ static void runNewPMCustomPasses(Module &Mod, TargetMachine *TM, report_fatal_error("unable to parse AA pipeline description '" + AAPipelineDesc + "': " + toString(std::move(Err))); + RegisterPassPlugins(Conf.PassPlugins, PB); + LoopAnalysisManager LAM; FunctionAnalysisManager FAM; CGSCCAnalysisManager CGAM; @@ -305,7 +336,7 @@ bool opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod, const ModuleSummaryIndex *ImportSummary) { // FIXME: Plumb the combined index into the new pass manager. if (!Conf.OptPipeline.empty()) - runNewPMCustomPasses(Mod, TM, Conf.OptPipeline, Conf.AAPipeline, + runNewPMCustomPasses(Conf, Mod, TM, Conf.OptPipeline, Conf.AAPipeline, Conf.DisableVerify); else if (Conf.UseNewPM) runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO, ExportSummary, @@ -333,7 +364,8 @@ static void EmitBitcodeSection(Module &M, const Config &Conf) { } void codegen(const Config &Conf, TargetMachine *TM, AddStreamFn AddStream, - unsigned Task, Module &Mod) { + unsigned Task, Module &Mod, + const ModuleSummaryIndex &CombinedIndex) { if (Conf.PreCodeGenModuleHook && !Conf.PreCodeGenModuleHook(Task, Mod)) return; @@ -349,7 +381,7 @@ void codegen(const Config &Conf, TargetMachine *TM, AddStreamFn AddStream, DwoFile = Conf.DwoDir; sys::path::append(DwoFile, std::to_string(Task) + ".dwo"); - TM->Options.MCOptions.SplitDwarfFile = DwoFile.str().str(); + TM->Options.MCOptions.SplitDwarfFile = std::string(DwoFile); } else TM->Options.MCOptions.SplitDwarfFile = Conf.SplitDwarfFile; @@ -362,6 +394,8 @@ void codegen(const Config &Conf, TargetMachine *TM, AddStreamFn AddStream, auto Stream = AddStream(Task); legacy::PassManager CodeGenPasses; + CodeGenPasses.add( + createImmutableModuleSummaryIndexWrapperPass(&CombinedIndex)); if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS, DwoOut ? &DwoOut->os() : nullptr, Conf.CGFileType)) @@ -374,8 +408,10 @@ void codegen(const Config &Conf, TargetMachine *TM, AddStreamFn AddStream, void splitCodeGen(const Config &C, TargetMachine *TM, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, - std::unique_ptr<Module> Mod) { - ThreadPool CodegenThreadPool(ParallelCodeGenParallelismLevel); + std::unique_ptr<Module> Mod, + const ModuleSummaryIndex &CombinedIndex) { + ThreadPool CodegenThreadPool( + heavyweight_hardware_concurrency(ParallelCodeGenParallelismLevel)); unsigned ThreadCount = 0; const Target *T = &TM->getTarget(); @@ -406,7 +442,8 @@ void splitCodeGen(const Config &C, TargetMachine *TM, AddStreamFn AddStream, std::unique_ptr<TargetMachine> TM = createTargetMachine(C, T, *MPartInCtx); - codegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx); + codegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx, + CombinedIndex); }, // Pass BC using std::move to ensure that it get moved rather than // copied into the thread's context. @@ -434,8 +471,8 @@ Expected<const Target *> initAndLookupTarget(const Config &C, Module &Mod) { } } -static Error -finalizeOptimizationRemarks(std::unique_ptr<ToolOutputFile> DiagOutputFile) { +Error lto::finalizeOptimizationRemarks( + std::unique_ptr<ToolOutputFile> DiagOutputFile) { // Make sure we flush the diagnostic remarks file in case the linker doesn't // call the global destructors before exiting. if (!DiagOutputFile) @@ -455,27 +492,19 @@ Error lto::backend(const Config &C, AddStreamFn AddStream, std::unique_ptr<TargetMachine> TM = createTargetMachine(C, *TOrErr, *Mod); - // Setup optimization remarks. - auto DiagFileOrErr = lto::setupOptimizationRemarks( - Mod->getContext(), C.RemarksFilename, C.RemarksPasses, C.RemarksFormat, - C.RemarksWithHotness); - if (!DiagFileOrErr) - return DiagFileOrErr.takeError(); - auto DiagnosticOutputFile = std::move(*DiagFileOrErr); - if (!C.CodeGenOnly) { if (!opt(C, TM.get(), 0, *Mod, /*IsThinLTO=*/false, /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr)) - return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); + return Error::success(); } if (ParallelCodeGenParallelismLevel == 1) { - codegen(C, TM.get(), AddStream, 0, *Mod); + codegen(C, TM.get(), AddStream, 0, *Mod, CombinedIndex); } else { splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLevel, - std::move(Mod)); + std::move(Mod), CombinedIndex); } - return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); + return Error::success(); } static void dropDeadSymbols(Module &Mod, const GVSummaryMapTy &DefinedGlobals, @@ -511,22 +540,32 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream, std::unique_ptr<TargetMachine> TM = createTargetMachine(Conf, *TOrErr, Mod); // Setup optimization remarks. - auto DiagFileOrErr = lto::setupOptimizationRemarks( + auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks( Mod.getContext(), Conf.RemarksFilename, Conf.RemarksPasses, Conf.RemarksFormat, Conf.RemarksWithHotness, Task); if (!DiagFileOrErr) return DiagFileOrErr.takeError(); auto DiagnosticOutputFile = std::move(*DiagFileOrErr); + // Set the partial sample profile ratio in the profile summary module flag of + // the module, if applicable. + Mod.setPartialSampleProfileRatio(CombinedIndex); + if (Conf.CodeGenOnly) { - codegen(Conf, TM.get(), AddStream, Task, Mod); + codegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex); return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); } if (Conf.PreOptModuleHook && !Conf.PreOptModuleHook(Task, Mod)) return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); - renameModuleForThinLTO(Mod, CombinedIndex); + // When linking an ELF shared object, dso_local should be dropped. We + // conservatively do this for -fpic. + bool ClearDSOLocalOnDeclarations = + TM->getTargetTriple().isOSBinFormatELF() && + TM->getRelocationModel() != Reloc::Static && + Mod.getPIELevel() == PIELevel::Default; + renameModuleForThinLTO(Mod, CombinedIndex, ClearDSOLocalOnDeclarations); dropDeadSymbols(Mod, DefinedGlobals, CombinedIndex); @@ -552,7 +591,8 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream, /*IsImporting*/ true); }; - FunctionImporter Importer(CombinedIndex, ModuleLoader); + FunctionImporter Importer(CombinedIndex, ModuleLoader, + ClearDSOLocalOnDeclarations); if (Error Err = Importer.importFunctions(Mod, ImportList).takeError()) return Err; @@ -563,6 +603,6 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream, /*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex)) return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); - codegen(Conf, TM.get(), AddStream, Task, Mod); + codegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex); return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); } |