mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-28 22:21:31 +03:00
New passmanager clean (#4175)
* Start to implement optimization pipeline with new pass manager for LLVM15 * Set default to use legacy passmanager. Co-authored-by: james <jamesragray@bitbucket.org>
This commit is contained in:
parent
7d8e0f787b
commit
2f06fd7416
1 changed files with 403 additions and 1 deletions
|
@ -35,6 +35,16 @@
|
||||||
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
|
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
|
||||||
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
|
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
|
||||||
#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
|
#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
|
||||||
|
#if LDC_LLVM_VER >= 1400
|
||||||
|
#include "llvm/Passes/PassBuilder.h"
|
||||||
|
#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
|
||||||
|
#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
|
||||||
|
#include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"
|
||||||
|
#include "llvm/Transforms/IPO/GlobalDCE.h"
|
||||||
|
#include "llvm/Transforms/Scalar/EarlyCSE.h"
|
||||||
|
#include "llvm/Transforms/Scalar/LICM.h"
|
||||||
|
#include "llvm/Transforms/Scalar/Reassociate.h"
|
||||||
|
#endif
|
||||||
#if LDC_LLVM_VER >= 1000
|
#if LDC_LLVM_VER >= 1000
|
||||||
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
|
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -110,6 +120,12 @@ static cl::opt<int> fSanitizeMemoryTrackOrigins(
|
||||||
cl::desc(
|
cl::desc(
|
||||||
"Enable origins tracking in MemorySanitizer (0=disabled, default)"));
|
"Enable origins tracking in MemorySanitizer (0=disabled, default)"));
|
||||||
|
|
||||||
|
static cl::opt<signed char> passmanager("passmanager",
|
||||||
|
cl::desc("Setting the passmanager (new,legacy):"), cl::ZeroOrMore, cl::init(0),
|
||||||
|
cl::values(
|
||||||
|
clEnumValN(0, "legacy", "Use the legacy passmanager (available for LLVM14 and below) "),
|
||||||
|
clEnumValN(1, "new", "Use the new passmanager (available for LLVM14 and above)")));
|
||||||
|
|
||||||
unsigned optLevel() {
|
unsigned optLevel() {
|
||||||
// Use -O2 as a base for the size-optimization levels.
|
// Use -O2 as a base for the size-optimization levels.
|
||||||
return optimizeLevel >= 0 ? optimizeLevel : 2;
|
return optimizeLevel >= 0 ? optimizeLevel : 2;
|
||||||
|
@ -149,6 +165,7 @@ llvm::CodeGenOpt::Level codeGenOptLevel() {
|
||||||
return llvm::CodeGenOpt::Default;
|
return llvm::CodeGenOpt::Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LDC_LLVM_VER < 1500
|
||||||
static inline void legacyAddPass(PassManagerBase &pm, Pass *pass) {
|
static inline void legacyAddPass(PassManagerBase &pm, Pass *pass) {
|
||||||
pm.add(pass);
|
pm.add(pass);
|
||||||
|
|
||||||
|
@ -342,7 +359,7 @@ static void legacyAddOptimizationPasses(legacy::PassManagerBase &mpm,
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// This function runs optimization passes based on command line arguments.
|
// This function runs optimization passes based on command line arguments.
|
||||||
// Returns true if any optimization passes were invoked.
|
// Returns true if any optimization passes were invoked.
|
||||||
bool ldc_optimize_module(llvm::Module *M) {
|
bool legacy_ldc_optimize_module(llvm::Module *M) {
|
||||||
// Create a PassManager to hold and optimize the collection of
|
// Create a PassManager to hold and optimize the collection of
|
||||||
// per-module passes we are about to build.
|
// per-module passes we are about to build.
|
||||||
legacy::PassManager mpm;
|
legacy::PassManager mpm;
|
||||||
|
@ -413,6 +430,391 @@ bool ldc_optimize_module(llvm::Module *M) {
|
||||||
// Report that we run some passes.
|
// Report that we run some passes.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LDC_LLVM_VER >= 1400
|
||||||
|
|
||||||
|
static OptimizationLevel getOptimizationLevel(){
|
||||||
|
switch(optimizeLevel) {
|
||||||
|
case 0: return OptimizationLevel::O0;
|
||||||
|
case 1: return OptimizationLevel::O1;
|
||||||
|
case 2: return OptimizationLevel::O2;
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5: return OptimizationLevel::O3;
|
||||||
|
case -1: return OptimizationLevel::Os;
|
||||||
|
case -2: return OptimizationLevel::Oz;
|
||||||
|
}
|
||||||
|
//This should never be reached
|
||||||
|
llvm_unreachable("Unexpected optimizeLevel.");
|
||||||
|
return OptimizationLevel::O0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addAddressSanitizerPasses(ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level ) {
|
||||||
|
AddressSanitizerOptions aso;
|
||||||
|
aso.CompileKernel = false;
|
||||||
|
aso.Recover = false;
|
||||||
|
aso.UseAfterScope = true;
|
||||||
|
aso.UseAfterReturn = AsanDetectStackUseAfterReturnMode::Runtime;
|
||||||
|
|
||||||
|
mpm.addPass(ModuleAddressSanitizerPass(aso));
|
||||||
|
if (verifyEach) {
|
||||||
|
mpm.addPass(VerifierPass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addMemorySanitizerPass(FunctionPassManager &fpm,
|
||||||
|
OptimizationLevel level ) {
|
||||||
|
int trackOrigins = fSanitizeMemoryTrackOrigins;
|
||||||
|
bool recover = false;
|
||||||
|
bool kernel = false;
|
||||||
|
fpm.addPass(MemorySanitizerPass(
|
||||||
|
MemorySanitizerOptions{trackOrigins, recover, kernel}));
|
||||||
|
|
||||||
|
// MemorySanitizer inserts complex instrumentation that mostly follows
|
||||||
|
// the logic of the original code, but operates on "shadow" values.
|
||||||
|
// It can benefit from re-running some general purpose optimization passes.
|
||||||
|
if (level != OptimizationLevel::O0) {
|
||||||
|
fpm.addPass(EarlyCSEPass());
|
||||||
|
fpm.addPass(ReassociatePass());
|
||||||
|
//FIXME: Fix these parameters
|
||||||
|
fpm.addPass(createFunctionToLoopPassAdaptor(LICMPass(128,128,false)));
|
||||||
|
fpm.addPass(GVNPass());
|
||||||
|
//FIXME: Not sure what to do with these?
|
||||||
|
//fpm.addPass(InstructionCombiningPass());
|
||||||
|
//fpm.addPass(DeadStoreEliminationPass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void addThreadSanitizerPass(ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level ) {
|
||||||
|
mpm.addPass(ModuleThreadSanitizerPass());
|
||||||
|
mpm.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addSanitizerCoveragePass(ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level ) {
|
||||||
|
mpm.addPass(ModuleSanitizerCoveragePass(
|
||||||
|
opts::getSanitizerCoverageOptions()));
|
||||||
|
}
|
||||||
|
// Adds PGO instrumentation generation and use passes.
|
||||||
|
static void addPGOPasses(ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level ) {
|
||||||
|
if (opts::isInstrumentingForASTBasedPGO()) {
|
||||||
|
InstrProfOptions options;
|
||||||
|
options.NoRedZone = global.params.disableRedZone;
|
||||||
|
if (global.params.datafileInstrProf)
|
||||||
|
options.InstrProfileOutput = global.params.datafileInstrProf;
|
||||||
|
mpm.addPass(InstrProfiling(options));
|
||||||
|
} else if (opts::isUsingASTBasedPGOProfile()) {
|
||||||
|
// We are generating code with PGO profile information available.
|
||||||
|
// Do indirect call promotion from -O1
|
||||||
|
if (level != OptimizationLevel::O0) {
|
||||||
|
mpm.addPass(PGOIndirectCallPromotion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addStripExternalsPass(ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level ) {
|
||||||
|
|
||||||
|
if (level == OptimizationLevel::O1 || level == OptimizationLevel::O2 ||
|
||||||
|
level == OptimizationLevel::O3) {
|
||||||
|
//FIXME: Update and uncomment this once gen/passes/StripExternals.cpp is updated to
|
||||||
|
// work with the new pass manager.
|
||||||
|
//
|
||||||
|
// mpm.addPass(StripExternalsPass());
|
||||||
|
// if (verifyEach) {
|
||||||
|
// mpm.addPass(VerifierPass());
|
||||||
|
// }
|
||||||
|
// mpm.addPass(GlobalDCEPass());
|
||||||
|
// if (verifyEach) {
|
||||||
|
// mpm.addPass(VerifierPass());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addSimplifyDRuntimeCallsPass(ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level ) {
|
||||||
|
if (level == OptimizationLevel::O2 || level == OptimizationLevel::O3) {
|
||||||
|
//FIXME: Update and uncomment this once gen/passes/SimplifyDRuntimeCalls.cpp is updated to
|
||||||
|
// work with the new pass manager.
|
||||||
|
// mpm.addPass(SimplifyDRuntimeCalls());
|
||||||
|
// if (verifyEach) {
|
||||||
|
// mpm.addPass(VerifierPass());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addGarbageCollect2StackPass(ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level ) {
|
||||||
|
if (level == OptimizationLevel::O2 || level == OptimizationLevel::O3) {
|
||||||
|
//FIXME: Update and uncomment this once gen/passes/GarbageCollect2Stack.cpp is updated to
|
||||||
|
// work with the new pass manager.
|
||||||
|
// mpm.addPass(GarbageCollect2Stack());
|
||||||
|
// if (verifyEach) {
|
||||||
|
// mpm.addPass(VerifierPass());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static llvm::Optional<PGOOptions> getPGOOptions() {
|
||||||
|
//FIXME: Do we have these anywhere?
|
||||||
|
bool debugInfoForProfiling=false;
|
||||||
|
bool pseudoProbeForProfiling=false;
|
||||||
|
if (opts::isInstrumentingForIRBasedPGO()) {
|
||||||
|
return PGOOptions(global.params.datafileInstrProf, "", "",
|
||||||
|
PGOOptions::PGOAction::IRInstr,
|
||||||
|
PGOOptions::CSPGOAction::NoCSAction,
|
||||||
|
debugInfoForProfiling, pseudoProbeForProfiling);
|
||||||
|
} else if (opts::isUsingIRBasedPGOProfile()) {
|
||||||
|
return PGOOptions(global.params.datafileInstrProf, "", "",
|
||||||
|
PGOOptions::PGOAction::IRUse,
|
||||||
|
PGOOptions::CSPGOAction::NoCSAction,
|
||||||
|
debugInfoForProfiling, pseudoProbeForProfiling);
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
static PipelineTuningOptions getPipelineTuningOptions(unsigned optLevelVal, unsigned sizeLevelVal) {
|
||||||
|
PipelineTuningOptions pto;
|
||||||
|
|
||||||
|
pto.LoopUnrolling = optLevelVal > 0;
|
||||||
|
|
||||||
|
pto.LoopUnrolling = !((disableLoopUnrolling.getNumOccurrences() > 0)
|
||||||
|
? disableLoopUnrolling
|
||||||
|
: optLevelVal == 0);
|
||||||
|
|
||||||
|
// This is final, unless there is a #pragma vectorize enable
|
||||||
|
if (disableLoopVectorization) {
|
||||||
|
pto.LoopVectorization = false;
|
||||||
|
// If option wasn't forced via cmd line (-vectorize-loops, -loop-vectorize)
|
||||||
|
} else if (!pto.LoopVectorization) {
|
||||||
|
pto.LoopVectorization = optLevelVal > 1 && sizeLevelVal < 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When #pragma vectorize is on for SLP, do the same as above
|
||||||
|
pto.SLPVectorization =
|
||||||
|
disableSLPVectorization ? false : optLevelVal > 1 && sizeLevelVal < 2;
|
||||||
|
|
||||||
|
return pto;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Adds a set of optimization passes to the given module/function pass
|
||||||
|
* managers based on the given optimization and size reduction levels.
|
||||||
|
*
|
||||||
|
* The selection mirrors Clang behavior and is based on LLVM's
|
||||||
|
* PassManagerBuilder.
|
||||||
|
*/
|
||||||
|
//Run optimization passes using the new pass manager
|
||||||
|
void runOptimizationPasses(llvm::Module *M) {
|
||||||
|
// Create a ModulePassManager to hold and optimize the collection of
|
||||||
|
// per-module passes we are about to build.
|
||||||
|
|
||||||
|
unsigned optLevelVal = optLevel();
|
||||||
|
unsigned sizeLevelVal = sizeLevel();
|
||||||
|
|
||||||
|
// builder.OptLevel = optLevel;
|
||||||
|
// builder.SizeLevel = sizeLevel;
|
||||||
|
// builder.PrepareForLTO = opts::isUsingLTO();
|
||||||
|
// builder.PrepareForThinLTO = opts::isUsingThinLTO();
|
||||||
|
//
|
||||||
|
// if (willInline()) {
|
||||||
|
// auto params = llvm::getInlineParams(optLevel, sizeLevel);
|
||||||
|
// builder.Inliner = createFunctionInliningPass(params);
|
||||||
|
// } else {
|
||||||
|
// builder.Inliner = createAlwaysInlinerLegacyPass();
|
||||||
|
// }
|
||||||
|
|
||||||
|
PassBuilder pb(gTargetMachine, getPipelineTuningOptions(optLevelVal, sizeLevelVal),
|
||||||
|
getPGOOptions());
|
||||||
|
|
||||||
|
LoopAnalysisManager lam;
|
||||||
|
FunctionAnalysisManager fam;
|
||||||
|
CGSCCAnalysisManager cgam;
|
||||||
|
ModuleAnalysisManager mam;
|
||||||
|
|
||||||
|
pb.registerModuleAnalyses(mam);
|
||||||
|
pb.registerCGSCCAnalyses(cgam);
|
||||||
|
pb.registerFunctionAnalyses(fam);
|
||||||
|
pb.registerLoopAnalyses(lam);
|
||||||
|
pb.crossRegisterProxies(lam, fam, cgam, mam);
|
||||||
|
|
||||||
|
ModulePassManager mpm;
|
||||||
|
|
||||||
|
if (!noVerify) {
|
||||||
|
pb.registerPipelineStartEPCallback([&](ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level) {
|
||||||
|
mpm.addPass(createModuleToFunctionPassAdaptor(VerifierPass()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pb.registerPipelineStartEPCallback([&](ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level) {
|
||||||
|
addPGOPasses(mpm, level);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (opts::isSanitizerEnabled(opts::AddressSanitizer)) {
|
||||||
|
pb.registerOptimizerLastEPCallback([&](ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level) {
|
||||||
|
addAddressSanitizerPasses(mpm,level);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts::isSanitizerEnabled(opts::MemorySanitizer)) {
|
||||||
|
pb.registerOptimizerLastEPCallback([&](ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level) {
|
||||||
|
FunctionPassManager fpm;
|
||||||
|
addMemorySanitizerPass(fpm,level);
|
||||||
|
mpm.addPass(createModuleToFunctionPassAdaptor(std::move(fpm)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts::isSanitizerEnabled(opts::ThreadSanitizer)) {
|
||||||
|
pb.registerOptimizerLastEPCallback([&](ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level) {
|
||||||
|
addThreadSanitizerPass(mpm, level);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts::isSanitizerEnabled(opts::CoverageSanitizer)) {
|
||||||
|
pb.registerOptimizerLastEPCallback([&](ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level) {
|
||||||
|
addSanitizerCoveragePass(mpm,level);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!disableLangSpecificPasses) {
|
||||||
|
if (!disableSimplifyDruntimeCalls) {
|
||||||
|
pb.registerLoopOptimizerEndEPCallback([&](LoopPassManager &lpm,
|
||||||
|
OptimizationLevel level) {
|
||||||
|
addSimplifyDRuntimeCallsPass(mpm,level);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!disableGCToStack) {
|
||||||
|
pb.registerLoopOptimizerEndEPCallback([&](LoopPassManager &lpm,
|
||||||
|
OptimizationLevel level) {
|
||||||
|
addGarbageCollect2StackPass(mpm,level);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pb.registerOptimizerLastEPCallback([&](ModulePassManager &mpm,
|
||||||
|
OptimizationLevel level) {
|
||||||
|
addStripExternalsPass(mpm, level);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
OptimizationLevel level = getOptimizationLevel();
|
||||||
|
|
||||||
|
if (optLevelVal == 0) {
|
||||||
|
mpm = pb.buildO0DefaultPipeline(level, opts::isUsingLTO() || opts::isUsingThinLTO());
|
||||||
|
} else if (opts::isUsingThinLTO()) {
|
||||||
|
mpm = pb.buildThinLTOPreLinkDefaultPipeline(level);
|
||||||
|
} else if (opts::isUsingLTO()) {
|
||||||
|
mpm = pb.buildLTOPreLinkDefaultPipeline(level);
|
||||||
|
} else {
|
||||||
|
mpm = pb.buildPerModuleDefaultPipeline(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mpm.run(*M,mam);
|
||||||
|
}
|
||||||
|
//Run codgen passes using the legacy pass manager
|
||||||
|
void runCodegenPasses(llvm::Module* M) {
|
||||||
|
legacy::PassManager mpm;
|
||||||
|
|
||||||
|
// Add an appropriate TargetLibraryInfo pass for the module's triple.
|
||||||
|
TargetLibraryInfoImpl *tlii =
|
||||||
|
new TargetLibraryInfoImpl(Triple(M->getTargetTriple()));
|
||||||
|
|
||||||
|
// The -disable-simplify-libcalls flag actually disables all builtin optzns.
|
||||||
|
if (disableSimplifyLibCalls)
|
||||||
|
tlii->disableAllFunctions();
|
||||||
|
|
||||||
|
mpm.add(new TargetLibraryInfoWrapperPass(*tlii));
|
||||||
|
|
||||||
|
// The DataLayout is already set at the module (in module.cpp,
|
||||||
|
// method Module::genLLVMModule())
|
||||||
|
// FIXME: Introduce new command line switch default-data-layout to
|
||||||
|
// override the module data layout
|
||||||
|
|
||||||
|
// Add internal analysis passes from the target machine.
|
||||||
|
mpm.add(createTargetTransformInfoWrapperPass(
|
||||||
|
gTargetMachine->getTargetIRAnalysis()));
|
||||||
|
|
||||||
|
// Also set up a manager for the per-function passes.
|
||||||
|
legacy::FunctionPassManager fpm(M);
|
||||||
|
|
||||||
|
// Add internal analysis passes from the target machine.
|
||||||
|
fpm.add(createTargetTransformInfoWrapperPass(
|
||||||
|
gTargetMachine->getTargetIRAnalysis()));
|
||||||
|
|
||||||
|
// If the -strip-debug command line option was specified, add it before
|
||||||
|
// anything else.
|
||||||
|
if (stripDebug) {
|
||||||
|
mpm.add(createStripSymbolsPass(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global.params.dllimport != DLLImport::none) {
|
||||||
|
mpm.add(createDLLImportRelocationPass());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run per-function passes.
|
||||||
|
fpm.doInitialization();
|
||||||
|
for (auto &F : *M) {
|
||||||
|
fpm.run(F);
|
||||||
|
}
|
||||||
|
fpm.doFinalization();
|
||||||
|
|
||||||
|
// Run per-module passes.
|
||||||
|
mpm.run(*M);
|
||||||
|
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// This function runs optimization passes based on command line arguments.
|
||||||
|
// Returns true if any optimization passes were invoked.
|
||||||
|
bool new_ldc_optimize_module(llvm::Module *M) {
|
||||||
|
// Dont optimise spirv modules because turning GEPs into extracts triggers
|
||||||
|
// asserts in the IR -> SPIR-V translation pass. SPIRV doesn't have a target
|
||||||
|
// machine, so any optimisation passes that rely on it to provide analysis,
|
||||||
|
// like DCE can't be run.
|
||||||
|
// The optimisation is supposed to happen between the SPIRV -> native machine
|
||||||
|
// code pass of the consumer of the binary.
|
||||||
|
// TODO: run rudimentary optimisations to improve IR debuggability.
|
||||||
|
if (getComputeTargetType(M) == ComputeBackend::SPIRV)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
runOptimizationPasses(M);
|
||||||
|
runCodegenPasses(M);
|
||||||
|
// Verify the resulting module.
|
||||||
|
if (!noVerify) {
|
||||||
|
verifyModule(M);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Report that we run some passes.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// This function calls the fuction which runs optimization passes based on command
|
||||||
|
// line arguments. Calls either legacy version using legacy pass manager
|
||||||
|
// or new version using the new pass managr
|
||||||
|
// Returns true if any optimization passes were invoked.
|
||||||
|
bool ldc_optimize_module(llvm::Module *M) {
|
||||||
|
#if LDC_LLVM_VER < 1400
|
||||||
|
return legacy_ldc_optimize_module(M);
|
||||||
|
#elif LDC_LLVM_VER < 1500
|
||||||
|
return passmanager==0 ? legacy_ldc_optimize_module(M)
|
||||||
|
: new_ldc_optimize_module(M);
|
||||||
|
#else
|
||||||
|
return new_ldc_optimize_module(M);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Verifies the module.
|
// Verifies the module.
|
||||||
void verifyModule(llvm::Module *m) {
|
void verifyModule(llvm::Module *m) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue