forked from OSchip/llvm-project
CodeGen: Replace ThinLTO backend implementation with a client of LTO/Resolution.
Summary: This changes clang to use the llvm::lto::thinBackend function instead of its own less comprehensive ThinLTO backend implementation. Patch by Peter Collingbourne Reviewers: tejohnson, mehdi_amini Subscribers: cfe-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D21545 llvm-svn: 278541
This commit is contained in:
parent
ad9a5951d9
commit
9e3f4746d5
|
@ -29,9 +29,11 @@
|
|||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/LTO/LTOBackend.h"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
|
@ -74,8 +76,7 @@ private:
|
|||
/// Set LLVM command line options passed through -backend-option.
|
||||
void setCommandLineOpts();
|
||||
|
||||
void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM,
|
||||
ModuleSummaryIndex *ModuleSummary);
|
||||
void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM);
|
||||
|
||||
/// Generates the TargetMachine.
|
||||
/// Leaves TM unchanged if it is unable to create the target machine.
|
||||
|
@ -284,8 +285,7 @@ static void addSymbolRewriterPass(const CodeGenOptions &Opts,
|
|||
}
|
||||
|
||||
void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
|
||||
legacy::FunctionPassManager &FPM,
|
||||
ModuleSummaryIndex *ModuleSummary) {
|
||||
legacy::FunctionPassManager &FPM) {
|
||||
if (CodeGenOpts.DisableLLVMPasses)
|
||||
return;
|
||||
|
||||
|
@ -336,14 +336,6 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
|
|||
PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO;
|
||||
PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
|
||||
|
||||
// If we are performing a ThinLTO importing compile, invoke the LTO
|
||||
// pipeline and pass down the in-memory module summary index.
|
||||
if (ModuleSummary) {
|
||||
PMBuilder.ModuleSummary = ModuleSummary;
|
||||
PMBuilder.populateThinLTOPassManager(MPM);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add target-specific passes that need to run as early as possible.
|
||||
if (TM)
|
||||
PMBuilder.addExtension(
|
||||
|
@ -670,26 +662,6 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
|
|||
if (TM)
|
||||
TheModule->setDataLayout(TM->createDataLayout());
|
||||
|
||||
// If we are performing a ThinLTO importing compile, load the function
|
||||
// index into memory and pass it into CreatePasses, which will add it
|
||||
// to the PassManagerBuilder and invoke LTO passes.
|
||||
std::unique_ptr<ModuleSummaryIndex> ModuleSummary;
|
||||
if (!CodeGenOpts.ThinLTOIndexFile.empty()) {
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
|
||||
llvm::getModuleSummaryIndexForFile(
|
||||
CodeGenOpts.ThinLTOIndexFile, [&](const DiagnosticInfo &DI) {
|
||||
TheModule->getContext().diagnose(DI);
|
||||
});
|
||||
if (std::error_code EC = IndexOrErr.getError()) {
|
||||
std::string Error = EC.message();
|
||||
errs() << "Error loading index file '" << CodeGenOpts.ThinLTOIndexFile
|
||||
<< "': " << Error << "\n";
|
||||
return;
|
||||
}
|
||||
ModuleSummary = std::move(IndexOrErr.get());
|
||||
assert(ModuleSummary && "Expected non-empty module summary index");
|
||||
}
|
||||
|
||||
legacy::PassManager PerModulePasses;
|
||||
PerModulePasses.add(
|
||||
createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
|
||||
|
@ -698,7 +670,7 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
|
|||
PerFunctionPasses.add(
|
||||
createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
|
||||
|
||||
CreatePasses(PerModulePasses, PerFunctionPasses, ModuleSummary.get());
|
||||
CreatePasses(PerModulePasses, PerFunctionPasses);
|
||||
|
||||
legacy::PassManager CodeGenPasses;
|
||||
CodeGenPasses.add(
|
||||
|
@ -751,12 +723,71 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
|
|||
}
|
||||
}
|
||||
|
||||
static void runThinLTOBackend(const CodeGenOptions &CGOpts, Module *M,
|
||||
std::unique_ptr<raw_pwrite_stream> OS) {
|
||||
// If we are performing a ThinLTO importing compile, load the function index
|
||||
// into memory and pass it into thinBackend, which will run the function
|
||||
// importer and invoke LTO passes.
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
|
||||
llvm::getModuleSummaryIndexForFile(
|
||||
CGOpts.ThinLTOIndexFile,
|
||||
[&](const DiagnosticInfo &DI) { M->getContext().diagnose(DI); });
|
||||
if (std::error_code EC = IndexOrErr.getError()) {
|
||||
std::string Error = EC.message();
|
||||
errs() << "Error loading index file '" << CGOpts.ThinLTOIndexFile
|
||||
<< "': " << Error << "\n";
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<ModuleSummaryIndex> CombinedIndex = std::move(*IndexOrErr);
|
||||
|
||||
auto AddStream = [&](size_t Task) { return std::move(OS); };
|
||||
|
||||
StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>>
|
||||
ModuleToDefinedGVSummaries;
|
||||
CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
|
||||
|
||||
// FIXME: We could simply import the modules mentioned in the combined index
|
||||
// here.
|
||||
FunctionImporter::ImportMapTy ImportList;
|
||||
ComputeCrossModuleImportForModule(M->getModuleIdentifier(), *CombinedIndex,
|
||||
ImportList);
|
||||
|
||||
std::vector<std::unique_ptr<llvm::MemoryBuffer>> OwnedImports;
|
||||
MapVector<llvm::StringRef, llvm::MemoryBufferRef> ModuleMap;
|
||||
|
||||
for (auto &I : ImportList) {
|
||||
ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MBOrErr =
|
||||
llvm::MemoryBuffer::getFile(I.first());
|
||||
if (!MBOrErr) {
|
||||
errs() << "Error loading imported file '" << I.first()
|
||||
<< "': " << MBOrErr.getError().message() << "\n";
|
||||
return;
|
||||
}
|
||||
ModuleMap[I.first()] = (*MBOrErr)->getMemBufferRef();
|
||||
OwnedImports.push_back(std::move(*MBOrErr));
|
||||
}
|
||||
|
||||
lto::Config Conf;
|
||||
if (Error E = thinBackend(
|
||||
Conf, 0, AddStream, *M, *CombinedIndex, ImportList,
|
||||
ModuleToDefinedGVSummaries[M->getModuleIdentifier()], ModuleMap)) {
|
||||
handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
|
||||
errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
|
||||
const CodeGenOptions &CGOpts,
|
||||
const clang::TargetOptions &TOpts,
|
||||
const LangOptions &LOpts, const llvm::DataLayout &TDesc,
|
||||
Module *M, BackendAction Action,
|
||||
std::unique_ptr<raw_pwrite_stream> OS) {
|
||||
if (!CGOpts.ThinLTOIndexFile.empty()) {
|
||||
runThinLTOBackend(CGOpts, M, std::move(OS));
|
||||
return;
|
||||
}
|
||||
|
||||
EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
|
||||
|
||||
AsmHelper.EmitAssembly(Action, std::move(OS));
|
||||
|
|
|
@ -8,6 +8,7 @@ set(LLVM_LINK_COMPONENTS
|
|||
IRReader
|
||||
InstCombine
|
||||
Instrumentation
|
||||
LTO
|
||||
Linker
|
||||
MC
|
||||
ObjCARCOpts
|
||||
|
|
Loading…
Reference in New Issue