aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/LTO/LTOBackend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/LTO/LTOBackend.cpp')
-rw-r--r--llvm/lib/LTO/LTOBackend.cpp106
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));
}