forked from OSchip/llvm-project
Recommit "[LTO] Use lto::backend for code generation."
This version of the patch includes a fix for the cfi failures. (undoes the revert commit7db390cc77
) It also undoes reverts of follow-up patches that also needed reverting originally: * [LTO] Add option enable NewPM with LTOCodeGenerator. (undoes revert commit0a17664b47
) * [LTOCodeGenerator] Use lto::Config for options (NFC)." (undoes revert commitb0a8e41cff
)
This commit is contained in:
parent
0b55ecce45
commit
c70737ba1d
|
@ -41,6 +41,8 @@
|
|||
#include "llvm/ADT/StringSet.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/LTO/Config.h"
|
||||
#include "llvm/LTO/LTO.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/ToolOutputFile.h"
|
||||
|
@ -86,14 +88,16 @@ struct LTOCodeGenerator {
|
|||
void setAsmUndefinedRefs(struct LTOModule *);
|
||||
void setTargetOptions(const TargetOptions &Options);
|
||||
void setDebugInfo(lto_debug_model);
|
||||
void setCodePICModel(Optional<Reloc::Model> Model) { RelocModel = Model; }
|
||||
void setCodePICModel(Optional<Reloc::Model> Model) {
|
||||
Config.RelocModel = Model;
|
||||
}
|
||||
|
||||
/// Set the file type to be emitted (assembly or object code).
|
||||
/// The default is CGFT_ObjectFile.
|
||||
void setFileType(CodeGenFileType FT) { FileType = FT; }
|
||||
void setFileType(CodeGenFileType FT) { Config.CGFileType = FT; }
|
||||
|
||||
void setCpu(StringRef MCpu) { this->MCpu = std::string(MCpu); }
|
||||
void setAttrs(std::vector<std::string> MAttrs) { this->MAttrs = MAttrs; }
|
||||
void setCpu(StringRef MCpu) { Config.CPU = std::string(MCpu); }
|
||||
void setAttrs(std::vector<std::string> MAttrs) { Config.MAttrs = MAttrs; }
|
||||
void setOptLevel(unsigned OptLevel);
|
||||
|
||||
void setShouldInternalize(bool Value) { ShouldInternalize = Value; }
|
||||
|
@ -165,20 +169,22 @@ struct LTOCodeGenerator {
|
|||
/// if the compilation was not successful.
|
||||
std::unique_ptr<MemoryBuffer> compileOptimized();
|
||||
|
||||
/// Compile the merged optimized module into out.size() output files each
|
||||
/// Compile the merged optimized module \p ParallelismLevel output files each
|
||||
/// representing a linkable partition of the module. If out contains more
|
||||
/// than one element, code generation is done in parallel with out.size()
|
||||
/// threads. Output files will be written to members of out. Returns true on
|
||||
/// success.
|
||||
/// than one element, code generation is done in parallel with \p
|
||||
/// ParallelismLevel threads. Output files will be written to the streams
|
||||
/// created using the \p AddStream callback. Returns true on success.
|
||||
///
|
||||
/// Calls \a verifyMergedModuleOnce().
|
||||
bool compileOptimized(ArrayRef<raw_pwrite_stream *> Out);
|
||||
bool compileOptimized(lto::AddStreamFn AddStream, unsigned ParallelismLevel);
|
||||
|
||||
/// Enable the Freestanding mode: indicate that the optimizer should not
|
||||
/// assume builtins are present on the target.
|
||||
void setFreestanding(bool Enabled) { Freestanding = Enabled; }
|
||||
void setFreestanding(bool Enabled) { Config.Freestanding = Enabled; }
|
||||
|
||||
void setDisableVerify(bool Value) { DisableVerify = Value; }
|
||||
void setDisableVerify(bool Value) { Config.DisableVerify = Value; }
|
||||
|
||||
void setUseNewPM(bool Value) { Config.UseNewPM = Value; }
|
||||
|
||||
void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
|
||||
|
||||
|
@ -188,8 +194,6 @@ struct LTOCodeGenerator {
|
|||
void DiagnosticHandler(const DiagnosticInfo &DI);
|
||||
|
||||
private:
|
||||
void initializeLTOPasses();
|
||||
|
||||
/// Verify the merged module on first call.
|
||||
///
|
||||
/// Sets \a HasVerifiedInput on first call and doesn't run again on the same
|
||||
|
@ -218,30 +222,23 @@ private:
|
|||
bool EmitDwarfDebugInfo = false;
|
||||
bool ScopeRestrictionsDone = false;
|
||||
bool HasVerifiedInput = false;
|
||||
Optional<Reloc::Model> RelocModel;
|
||||
StringSet<> MustPreserveSymbols;
|
||||
StringSet<> AsmUndefinedRefs;
|
||||
StringMap<GlobalValue::LinkageTypes> ExternalSymbols;
|
||||
std::vector<std::string> CodegenOptions;
|
||||
std::string FeatureStr;
|
||||
std::string MCpu;
|
||||
std::vector<std::string> MAttrs;
|
||||
std::string NativeObjectPath;
|
||||
TargetOptions Options;
|
||||
CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default;
|
||||
const Target *MArch = nullptr;
|
||||
std::string TripleStr;
|
||||
unsigned OptLevel = 2;
|
||||
lto_diagnostic_handler_t DiagHandler = nullptr;
|
||||
void *DiagContext = nullptr;
|
||||
bool ShouldInternalize = EnableLTOInternalization;
|
||||
bool ShouldEmbedUselists = false;
|
||||
bool ShouldRestoreGlobalsLinkage = false;
|
||||
CodeGenFileType FileType = CGFT_ObjectFile;
|
||||
std::unique_ptr<ToolOutputFile> DiagnosticOutputFile;
|
||||
bool Freestanding = false;
|
||||
std::unique_ptr<ToolOutputFile> StatsFile = nullptr;
|
||||
bool DisableVerify = false;
|
||||
|
||||
lto::Config Config;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "llvm/LTO/LTO.h"
|
||||
#include "llvm/LTO/LTOBackend.h"
|
||||
#include "llvm/LTO/legacy/LTOModule.h"
|
||||
#include "llvm/LTO/legacy/UpdateCompilerUsed.h"
|
||||
#include "llvm/Linker/Linker.h"
|
||||
|
@ -123,43 +124,16 @@ LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
|
|||
TheLinker(new Linker(*MergedModule)) {
|
||||
Context.setDiscardValueNames(LTODiscardValueNames);
|
||||
Context.enableDebugTypeODRUniquing();
|
||||
initializeLTOPasses();
|
||||
|
||||
Config.CodeModel = None;
|
||||
Config.StatsFile = LTOStatsFile;
|
||||
Config.PreCodeGenPassesHook = [](legacy::PassManager &PM) {
|
||||
PM.add(createObjCARCContractPass());
|
||||
};
|
||||
}
|
||||
|
||||
LTOCodeGenerator::~LTOCodeGenerator() {}
|
||||
|
||||
// Initialize LTO passes. Please keep this function in sync with
|
||||
// PassManagerBuilder::populateLTOPassManager(), and make sure all LTO
|
||||
// passes are initialized.
|
||||
void LTOCodeGenerator::initializeLTOPasses() {
|
||||
PassRegistry &R = *PassRegistry::getPassRegistry();
|
||||
|
||||
initializeInternalizeLegacyPassPass(R);
|
||||
initializeIPSCCPLegacyPassPass(R);
|
||||
initializeGlobalOptLegacyPassPass(R);
|
||||
initializeConstantMergeLegacyPassPass(R);
|
||||
initializeDAHPass(R);
|
||||
initializeInstructionCombiningPassPass(R);
|
||||
initializeSimpleInlinerPass(R);
|
||||
initializePruneEHPass(R);
|
||||
initializeGlobalDCELegacyPassPass(R);
|
||||
initializeOpenMPOptLegacyPassPass(R);
|
||||
initializeArgPromotionPass(R);
|
||||
initializeJumpThreadingPass(R);
|
||||
initializeSROALegacyPassPass(R);
|
||||
initializeAttributorLegacyPassPass(R);
|
||||
initializeAttributorCGSCCLegacyPassPass(R);
|
||||
initializePostOrderFunctionAttrsLegacyPassPass(R);
|
||||
initializeReversePostOrderFunctionAttrsLegacyPassPass(R);
|
||||
initializeGlobalsAAWrapperPassPass(R);
|
||||
initializeLegacyLICMPassPass(R);
|
||||
initializeMergedLoadStoreMotionLegacyPassPass(R);
|
||||
initializeGVNLegacyPassPass(R);
|
||||
initializeMemCpyOptLegacyPassPass(R);
|
||||
initializeDCELegacyPassPass(R);
|
||||
initializeCFGSimplifyPassPass(R);
|
||||
}
|
||||
|
||||
void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) {
|
||||
const std::vector<StringRef> &undefs = Mod->getAsmUndefinedRefs();
|
||||
for (int i = 0, e = undefs.size(); i != e; ++i)
|
||||
|
@ -194,7 +168,7 @@ void LTOCodeGenerator::setModule(std::unique_ptr<LTOModule> Mod) {
|
|||
}
|
||||
|
||||
void LTOCodeGenerator::setTargetOptions(const TargetOptions &Options) {
|
||||
this->Options = Options;
|
||||
Config.Options = Options;
|
||||
}
|
||||
|
||||
void LTOCodeGenerator::setDebugInfo(lto_debug_model Debug) {
|
||||
|
@ -211,19 +185,21 @@ void LTOCodeGenerator::setDebugInfo(lto_debug_model Debug) {
|
|||
}
|
||||
|
||||
void LTOCodeGenerator::setOptLevel(unsigned Level) {
|
||||
OptLevel = Level;
|
||||
switch (OptLevel) {
|
||||
Config.OptLevel = Level;
|
||||
Config.PTO.LoopVectorization = Config.OptLevel > 1;
|
||||
Config.PTO.SLPVectorization = Config.OptLevel > 1;
|
||||
switch (Config.OptLevel) {
|
||||
case 0:
|
||||
CGOptLevel = CodeGenOpt::None;
|
||||
Config.CGOptLevel = CodeGenOpt::None;
|
||||
return;
|
||||
case 1:
|
||||
CGOptLevel = CodeGenOpt::Less;
|
||||
Config.CGOptLevel = CodeGenOpt::Less;
|
||||
return;
|
||||
case 2:
|
||||
CGOptLevel = CodeGenOpt::Default;
|
||||
Config.CGOptLevel = CodeGenOpt::Default;
|
||||
return;
|
||||
case 3:
|
||||
CGOptLevel = CodeGenOpt::Aggressive;
|
||||
Config.CGOptLevel = CodeGenOpt::Aggressive;
|
||||
return;
|
||||
}
|
||||
llvm_unreachable("Unknown optimization level!");
|
||||
|
@ -268,38 +244,35 @@ bool LTOCodeGenerator::writeMergedModules(StringRef Path) {
|
|||
bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) {
|
||||
// make unique temp output file to put generated code
|
||||
SmallString<128> Filename;
|
||||
int FD;
|
||||
|
||||
StringRef Extension
|
||||
(FileType == CGFT_AssemblyFile ? "s" : "o");
|
||||
auto AddStream =
|
||||
[&](size_t Task) -> std::unique_ptr<lto::NativeObjectStream> {
|
||||
StringRef Extension(Config.CGFileType == CGFT_AssemblyFile ? "s" : "o");
|
||||
|
||||
std::error_code EC =
|
||||
sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename);
|
||||
if (EC) {
|
||||
emitError(EC.message());
|
||||
return false;
|
||||
}
|
||||
int FD;
|
||||
std::error_code EC =
|
||||
sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename);
|
||||
if (EC)
|
||||
emitError(EC.message());
|
||||
|
||||
// generate object file
|
||||
ToolOutputFile objFile(Filename, FD);
|
||||
return std::make_unique<lto::NativeObjectStream>(
|
||||
std::make_unique<llvm::raw_fd_ostream>(FD, true));
|
||||
};
|
||||
|
||||
bool genResult = compileOptimized(&objFile.os());
|
||||
objFile.os().close();
|
||||
if (objFile.os().has_error()) {
|
||||
emitError((Twine("could not write object file: ") + Filename + ": " +
|
||||
objFile.os().error().message())
|
||||
.str());
|
||||
objFile.os().clear_error();
|
||||
sys::fs::remove(Twine(Filename));
|
||||
return false;
|
||||
}
|
||||
bool genResult = compileOptimized(AddStream, 1);
|
||||
|
||||
objFile.keep();
|
||||
if (!genResult) {
|
||||
sys::fs::remove(Twine(Filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
// If statistics were requested, save them to the specified file or
|
||||
// print them out after codegen.
|
||||
if (StatsFile)
|
||||
PrintStatisticsJSON(StatsFile->os());
|
||||
else if (AreStatisticsEnabled())
|
||||
PrintStatistics();
|
||||
|
||||
NativeObjectPath = Filename.c_str();
|
||||
*Name = NativeObjectPath.c_str();
|
||||
return true;
|
||||
|
@ -361,20 +334,20 @@ bool LTOCodeGenerator::determineTarget() {
|
|||
|
||||
// Construct LTOModule, hand over ownership of module and target. Use MAttr as
|
||||
// the default set of features.
|
||||
SubtargetFeatures Features(join(MAttrs, ""));
|
||||
SubtargetFeatures Features(join(Config.MAttrs, ""));
|
||||
Features.getDefaultSubtargetFeatures(Triple);
|
||||
FeatureStr = Features.getString();
|
||||
// Set a default CPU for Darwin triples.
|
||||
if (MCpu.empty() && Triple.isOSDarwin()) {
|
||||
if (Config.CPU.empty() && Triple.isOSDarwin()) {
|
||||
if (Triple.getArch() == llvm::Triple::x86_64)
|
||||
MCpu = "core2";
|
||||
Config.CPU = "core2";
|
||||
else if (Triple.getArch() == llvm::Triple::x86)
|
||||
MCpu = "yonah";
|
||||
Config.CPU = "yonah";
|
||||
else if (Triple.isArm64e())
|
||||
MCpu = "apple-a12";
|
||||
Config.CPU = "apple-a12";
|
||||
else if (Triple.getArch() == llvm::Triple::aarch64 ||
|
||||
Triple.getArch() == llvm::Triple::aarch64_32)
|
||||
MCpu = "cyclone";
|
||||
Config.CPU = "cyclone";
|
||||
}
|
||||
|
||||
TargetMach = createTargetMachine();
|
||||
|
@ -386,7 +359,8 @@ bool LTOCodeGenerator::determineTarget() {
|
|||
std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() {
|
||||
assert(MArch && "MArch is not set!");
|
||||
return std::unique_ptr<TargetMachine>(MArch->createTargetMachine(
|
||||
TripleStr, MCpu, FeatureStr, Options, RelocModel, None, CGOptLevel));
|
||||
TripleStr, Config.CPU, FeatureStr, Config.Options, Config.RelocModel,
|
||||
None, Config.CGOptLevel));
|
||||
}
|
||||
|
||||
// If a linkonce global is present in the MustPreserveSymbols, we need to make
|
||||
|
@ -568,36 +542,23 @@ bool LTOCodeGenerator::optimize() {
|
|||
// Write LTOPostLink flag for passes that require all the modules.
|
||||
MergedModule->addModuleFlag(Module::Error, "LTOPostLink", 1);
|
||||
|
||||
// Instantiate the pass manager to organize the passes.
|
||||
legacy::PassManager passes;
|
||||
|
||||
// Add an appropriate DataLayout instance for this module...
|
||||
MergedModule->setDataLayout(TargetMach->createDataLayout());
|
||||
|
||||
passes.add(
|
||||
createTargetTransformInfoWrapperPass(TargetMach->getTargetIRAnalysis()));
|
||||
|
||||
Triple TargetTriple(TargetMach->getTargetTriple());
|
||||
PassManagerBuilder PMB;
|
||||
PMB.LoopVectorize = true;
|
||||
PMB.SLPVectorize = true;
|
||||
PMB.Inliner = createFunctionInliningPass();
|
||||
PMB.LibraryInfo = new TargetLibraryInfoImpl(TargetTriple);
|
||||
if (Freestanding)
|
||||
PMB.LibraryInfo->disableAllFunctions();
|
||||
PMB.OptLevel = OptLevel;
|
||||
PMB.VerifyInput = !DisableVerify;
|
||||
PMB.VerifyOutput = !DisableVerify;
|
||||
|
||||
PMB.populateLTOPassManager(passes);
|
||||
|
||||
// Run our queue of passes all at once now, efficiently.
|
||||
passes.run(*MergedModule);
|
||||
ModuleSummaryIndex CombinedIndex(false);
|
||||
TargetMach = createTargetMachine();
|
||||
if (!opt(Config, TargetMach.get(), 0, *MergedModule, /*IsThinLTO=*/false,
|
||||
/*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
|
||||
/*CmdArgs*/ std::vector<uint8_t>())) {
|
||||
emitError("LTO middle-end optimizations failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LTOCodeGenerator::compileOptimized(ArrayRef<raw_pwrite_stream *> Out) {
|
||||
bool LTOCodeGenerator::compileOptimized(lto::AddStreamFn AddStream,
|
||||
unsigned ParallelismLevel) {
|
||||
if (!this->determineTarget())
|
||||
return false;
|
||||
|
||||
|
@ -605,20 +566,17 @@ bool LTOCodeGenerator::compileOptimized(ArrayRef<raw_pwrite_stream *> Out) {
|
|||
// been called in optimize(), this call will return early.
|
||||
verifyMergedModuleOnce();
|
||||
|
||||
legacy::PassManager preCodeGenPasses;
|
||||
|
||||
// If the bitcode files contain ARC code and were compiled with optimization,
|
||||
// the ObjCARCContractPass must be run, so do it unconditionally here.
|
||||
preCodeGenPasses.add(createObjCARCContractPass());
|
||||
preCodeGenPasses.run(*MergedModule);
|
||||
|
||||
// Re-externalize globals that may have been internalized to increase scope
|
||||
// for splitting
|
||||
restoreLinkageForExternals();
|
||||
|
||||
splitCodeGen(
|
||||
*MergedModule, Out, {}, [&]() { return createTargetMachine(); }, FileType,
|
||||
ShouldRestoreGlobalsLinkage);
|
||||
ModuleSummaryIndex CombinedIndex(false);
|
||||
|
||||
Config.CodeGenOnly = true;
|
||||
Error Err = backend(Config, AddStream, ParallelismLevel, *MergedModule,
|
||||
CombinedIndex);
|
||||
assert(!Err && "unexpected code-generation failure");
|
||||
(void)Err;
|
||||
|
||||
// If statistics were requested, save them to the specified file or
|
||||
// print them out after codegen.
|
||||
|
|
|
@ -1,35 +1,41 @@
|
|||
; RUN: llvm-as < %s >%t.bc
|
||||
; PR21108: Diagnostic handlers get pass remarks, even if they're not enabled.
|
||||
|
||||
; FIXME: Update checks for new pass manager.
|
||||
|
||||
; Confirm that there are -pass-remarks.
|
||||
; RUN: llvm-lto -pass-remarks=inline \
|
||||
; RUN: llvm-lto -use-new-pm=false \
|
||||
; RUN: -pass-remarks=inline \
|
||||
; RUN: -exported-symbol _func2 -pass-remarks-analysis=loop-vectorize \
|
||||
; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \
|
||||
; RUN: FileCheck %s -allow-empty -check-prefix=REMARKS
|
||||
; RUN: llvm-nm %t.o | FileCheck %s -check-prefix NM
|
||||
|
||||
; RUN: llvm-lto -pass-remarks=inline -use-diagnostic-handler \
|
||||
; RUN: llvm-lto -use-new-pm=false \
|
||||
; RUN: -pass-remarks=inline -use-diagnostic-handler \
|
||||
; RUN: -exported-symbol _func2 -pass-remarks-analysis=loop-vectorize \
|
||||
; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \
|
||||
; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \
|
||||
; RUN: FileCheck %s -allow-empty -check-prefix=REMARKS_DH
|
||||
; RUN: llvm-nm %t.o | FileCheck %s -check-prefix NM
|
||||
|
||||
; Confirm that -pass-remarks are not printed by default.
|
||||
; RUN: llvm-lto \
|
||||
; RUN: llvm-lto -use-new-pm=false \
|
||||
; RUN: -exported-symbol _func2 \
|
||||
; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \
|
||||
; RUN: FileCheck %s -allow-empty
|
||||
; RUN: llvm-nm %t.o | FileCheck %s -check-prefix NM
|
||||
|
||||
; RUN: llvm-lto -use-diagnostic-handler \
|
||||
; RUN: -exported-symbol _func2 \
|
||||
; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \
|
||||
; RUN: llvm-lto -use-new-pm=false \
|
||||
; RUN: -use-diagnostic-handler \
|
||||
; RUN: -exported-symbol _func2 \
|
||||
; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \
|
||||
; RUN: FileCheck %s -allow-empty
|
||||
; RUN: llvm-nm %t.o | FileCheck %s -check-prefix NM
|
||||
|
||||
; Optimization records are collected regardless of the diagnostic handler
|
||||
; RUN: rm -f %t.yaml
|
||||
; RUN: llvm-lto -lto-pass-remarks-output=%t.yaml \
|
||||
; RUN: llvm-lto -use-new-pm=false \
|
||||
; RUN: -lto-pass-remarks-output=%t.yaml \
|
||||
; RUN: -exported-symbol _func2 \
|
||||
; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \
|
||||
; RUN: FileCheck %s -allow-empty
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
; RUN: llvm-as < %s >%t.bc
|
||||
; RUN: llvm-lto -debug-pass=Arguments -exported-symbol=_f -o /dev/null %t.bc 2>&1 -disable-verify | FileCheck %s
|
||||
; RUN: llvm-lto -debug-pass=Arguments -exported-symbol=_f -o /dev/null %t.bc 2>&1 | FileCheck %s -check-prefix=VERIFY
|
||||
; RUN: llvm-lto -use-new-pm=false -debug-pass=Arguments -exported-symbol=_f -o /dev/null %t.bc 2>&1 -disable-verify | FileCheck %s
|
||||
; RUN: llvm-lto -use-new-pm=false -debug-pass=Arguments -exported-symbol=_f -o /dev/null %t.bc 2>&1 | FileCheck %s -check-prefix=VERIFY
|
||||
|
||||
; FIXME: Update checks for new pass manager.
|
||||
|
||||
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-apple-macosx10.10.0"
|
||||
|
||||
; -disable-verify should disable verification from the optimization pipeline.
|
||||
; CHECK: Pass Arguments:
|
||||
; CHECK-NOT: -verify
|
||||
; CHECK-NOT: -verify {{.*}} -verify
|
||||
|
||||
; VERIFY: Pass Arguments: {{.*}} -verify {{.*}} -verify
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
; RUN: opt -module-summary %s -o %t.bc
|
||||
; RUN: llvm-lto -hot-cold-split=true -thinlto-action=run %t.bc -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=OLDPM-ANYLTO-POSTLINK-Os
|
||||
; RUN: llvm-lto -hot-cold-split=true %t.bc -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=OLDPM-ANYLTO-POSTLINK-Os
|
||||
; RUN: llvm-lto -use-new-pm=false -hot-cold-split=true \
|
||||
; RUN: -thinlto-action=run %t.bc -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=OLDPM-ANYLTO-POSTLINK-Os
|
||||
; RUN: llvm-lto -use-new-pm=false -hot-cold-split=true \
|
||||
; RUN: %t.bc -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=OLDPM-ANYLTO-POSTLINK-Os
|
||||
|
||||
; FIXME: Update checks for new pass manager.
|
||||
|
||||
; REQUIRES: asserts
|
||||
|
||||
|
|
|
@ -5,5 +5,12 @@
|
|||
|
||||
target triple = "x86_64-apple-macosx10.8.0"
|
||||
|
||||
define i32 @test(i32 %a) {
|
||||
%r = add i32 %a, 1
|
||||
%r.1 = add i32 1, %a
|
||||
%r.2 = add i32 %r, %r.1
|
||||
ret i32 %r.2
|
||||
}
|
||||
|
||||
; STATS: Statistics Collected
|
||||
; NO_STATS-NOT: Statistics Collected
|
||||
|
|
|
@ -222,6 +222,11 @@ static cl::opt<bool> PrintMachOCPUOnly(
|
|||
"print-macho-cpu-only", cl::init(false),
|
||||
cl::desc("Instead of running LTO, print the mach-o cpu in each IR file"));
|
||||
|
||||
static cl::opt<bool>
|
||||
UseNewPM("use-new-pm",
|
||||
cl::desc("Run LTO passes using the new pass manager"),
|
||||
cl::init(LLVM_ENABLE_NEW_PASS_MANAGER), cl::Hidden);
|
||||
|
||||
namespace {
|
||||
|
||||
struct ModuleInfo {
|
||||
|
@ -1014,6 +1019,8 @@ int main(int argc, char **argv) {
|
|||
CodeGen.setOptLevel(OptLevel - '0');
|
||||
CodeGen.setAttrs(codegen::getMAttrs());
|
||||
|
||||
CodeGen.setUseNewPM(UseNewPM);
|
||||
|
||||
if (auto FT = codegen::getExplicitFileType())
|
||||
CodeGen.setFileType(FT.getValue());
|
||||
|
||||
|
@ -1041,25 +1048,24 @@ int main(int argc, char **argv) {
|
|||
error("writing merged module failed.");
|
||||
}
|
||||
|
||||
std::list<ToolOutputFile> OSs;
|
||||
std::vector<raw_pwrite_stream *> OSPtrs;
|
||||
for (unsigned I = 0; I != Parallelism; ++I) {
|
||||
auto AddStream =
|
||||
[&](size_t Task) -> std::unique_ptr<lto::NativeObjectStream> {
|
||||
std::string PartFilename = OutputFilename;
|
||||
if (Parallelism != 1)
|
||||
PartFilename += "." + utostr(I);
|
||||
PartFilename += "." + utostr(Task);
|
||||
|
||||
std::error_code EC;
|
||||
OSs.emplace_back(PartFilename, EC, sys::fs::OF_None);
|
||||
auto S =
|
||||
std::make_unique<raw_fd_ostream>(PartFilename, EC, sys::fs::OF_None);
|
||||
if (EC)
|
||||
error("error opening the file '" + PartFilename + "': " + EC.message());
|
||||
OSPtrs.push_back(&OSs.back().os());
|
||||
}
|
||||
return std::make_unique<lto::NativeObjectStream>(std::move(S));
|
||||
};
|
||||
|
||||
if (!CodeGen.compileOptimized(OSPtrs))
|
||||
if (!CodeGen.compileOptimized(AddStream, Parallelism))
|
||||
// Diagnostic messages should have been printed by the handler.
|
||||
error("error compiling the code");
|
||||
|
||||
for (ToolOutputFile &OS : OSs)
|
||||
OS.keep();
|
||||
} else {
|
||||
if (Parallelism != 1)
|
||||
error("-j must be specified together with -o");
|
||||
|
|
Loading…
Reference in New Issue