Add -verify-each option to ease debugging

This commit is contained in:
Frits van Bommel 2009-05-03 21:58:28 +02:00
parent 67fc0aca20
commit a2eee70761

View file

@ -6,6 +6,7 @@
#include "llvm/PassManager.h" #include "llvm/PassManager.h"
#include "llvm/LinkAllPasses.h" #include "llvm/LinkAllPasses.h"
#include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/PassNameParser.h" #include "llvm/Support/PassNameParser.h"
@ -35,6 +36,12 @@ static cl::opt<unsigned char> optimizeLevel(
clEnumValEnd), clEnumValEnd),
cl::init(0)); cl::init(0));
static cl::opt<bool>
verifyEach("verify-each",
cl::desc("Run verifier after each optimization pass"),
cl::Hidden,
cl::ZeroOrMore);
static cl::opt<bool> static cl::opt<bool>
disableLangSpecificPasses("disable-d-passes", disableLangSpecificPasses("disable-d-passes",
cl::desc("Disable D-specific passes in -O<N>"), cl::desc("Disable D-specific passes in -O<N>"),
@ -80,79 +87,85 @@ bool optimize() {
return optimizeLevel || doInline() || !passList.empty(); return optimizeLevel || doInline() || !passList.empty();
} }
static void addPass(PassManager& pm, Pass* pass) {
pm.add(pass);
if (verifyEach) pm.add(createVerifierPass());
}
// this function inserts some or all of the std-compile-opts passes depending on the // this function inserts some or all of the std-compile-opts passes depending on the
// optimization level given. // optimization level given.
static void addPassesForOptLevel(PassManager& pm) { static void addPassesForOptLevel(PassManager& pm) {
// -O1 // -O1
if (optimizeLevel >= 1) if (optimizeLevel >= 1)
{ {
//pm.add(createStripDeadPrototypesPass()); //addPass(pm, createStripDeadPrototypesPass());
pm.add(createGlobalDCEPass()); addPass(pm, createGlobalDCEPass());
pm.add(createRaiseAllocationsPass()); addPass(pm, createRaiseAllocationsPass());
pm.add(createCFGSimplificationPass()); addPass(pm, createCFGSimplificationPass());
if (optimizeLevel == 1) if (optimizeLevel == 1)
pm.add(createPromoteMemoryToRegisterPass()); addPass(pm, createPromoteMemoryToRegisterPass());
else else
pm.add(createScalarReplAggregatesPass()); addPass(pm, createScalarReplAggregatesPass());
pm.add(createGlobalOptimizerPass()); addPass(pm, createGlobalOptimizerPass());
pm.add(createGlobalDCEPass()); addPass(pm, createGlobalDCEPass());
} }
// -O2 // -O2
if (optimizeLevel >= 2) if (optimizeLevel >= 2)
{ {
pm.add(createIPConstantPropagationPass()); addPass(pm, createIPConstantPropagationPass());
pm.add(createDeadArgEliminationPass()); addPass(pm, createDeadArgEliminationPass());
pm.add(createInstructionCombiningPass()); addPass(pm, createInstructionCombiningPass());
pm.add(createCFGSimplificationPass()); addPass(pm, createCFGSimplificationPass());
pm.add(createPruneEHPass()); addPass(pm, createPruneEHPass());
#ifdef USE_METADATA #ifdef USE_METADATA
if (!disableLangSpecificPasses && !disableGCToStack) if (!disableLangSpecificPasses && !disableGCToStack)
pm.add(createGarbageCollect2Stack()); addPass(pm, createGarbageCollect2Stack());
#endif #endif
} }
// -inline // -inline
if (doInline()) { if (doInline()) {
pm.add(createFunctionInliningPass()); addPass(pm, createFunctionInliningPass());
if (optimizeLevel >= 2) { if (optimizeLevel >= 2) {
// Run some optimizations to clean up after inlining. // Run some optimizations to clean up after inlining.
pm.add(createScalarReplAggregatesPass()); addPass(pm, createScalarReplAggregatesPass());
pm.add(createInstructionCombiningPass()); addPass(pm, createInstructionCombiningPass());
#ifdef USE_METADATA #ifdef USE_METADATA
if (!disableLangSpecificPasses && !disableGCToStack) if (!disableLangSpecificPasses && !disableGCToStack)
pm.add(createGarbageCollect2Stack()); addPass(pm, createGarbageCollect2Stack());
#endif #endif
// Inline again, to catch things like foreach delegates // Inline again, to catch things like foreach delegates
// passed to inlined opApply's where the function wasn't // passed to inlined opApply's where the function wasn't
// known during the first inliner pass. // known during the first inliner pass.
pm.add(createFunctionInliningPass()); addPass(pm, createFunctionInliningPass());
// Run clean-up again. // Run clean-up again.
pm.add(createScalarReplAggregatesPass()); addPass(pm, createScalarReplAggregatesPass());
pm.add(createInstructionCombiningPass()); addPass(pm, createInstructionCombiningPass());
#ifdef USE_METADATA #ifdef USE_METADATA
if (!disableLangSpecificPasses && !disableGCToStack) if (!disableLangSpecificPasses && !disableGCToStack)
pm.add(createGarbageCollect2Stack()); addPass(pm, createGarbageCollect2Stack());
#endif #endif
} }
} }
if (optimizeLevel >= 2 && !disableLangSpecificPasses) { if (optimizeLevel >= 2 && !disableLangSpecificPasses) {
if (!disableSimplifyRuntimeCalls) if (!disableSimplifyRuntimeCalls)
pm.add(createSimplifyDRuntimeCalls()); addPass(pm, createSimplifyDRuntimeCalls());
#ifdef USE_METADATA #ifdef USE_METADATA
if (!disableGCToStack) { if (!disableGCToStack) {
// Run some clean-up after the last GC to stack promotion pass. // Run some clean-up after the last GC to stack promotion pass.
pm.add(createScalarReplAggregatesPass()); addPass(pm, createScalarReplAggregatesPass());
pm.add(createInstructionCombiningPass()); addPass(pm, createInstructionCombiningPass());
pm.add(createCFGSimplificationPass()); addPass(pm, createCFGSimplificationPass());
} }
#endif #endif
} }
@ -160,36 +173,36 @@ static void addPassesForOptLevel(PassManager& pm) {
// -O3 // -O3
if (optimizeLevel >= 3) if (optimizeLevel >= 3)
{ {
pm.add(createArgumentPromotionPass()); addPass(pm, createArgumentPromotionPass());
pm.add(createTailDuplicationPass()); addPass(pm, createTailDuplicationPass());
pm.add(createInstructionCombiningPass()); addPass(pm, createInstructionCombiningPass());
pm.add(createCFGSimplificationPass()); addPass(pm, createCFGSimplificationPass());
pm.add(createScalarReplAggregatesPass()); addPass(pm, createScalarReplAggregatesPass());
pm.add(createInstructionCombiningPass()); addPass(pm, createInstructionCombiningPass());
pm.add(createCondPropagationPass()); addPass(pm, createCondPropagationPass());
pm.add(createTailCallEliminationPass()); addPass(pm, createTailCallEliminationPass());
pm.add(createCFGSimplificationPass()); addPass(pm, createCFGSimplificationPass());
pm.add(createReassociatePass()); addPass(pm, createReassociatePass());
pm.add(createLoopRotatePass()); addPass(pm, createLoopRotatePass());
pm.add(createLICMPass()); addPass(pm, createLICMPass());
pm.add(createLoopUnswitchPass()); addPass(pm, createLoopUnswitchPass());
pm.add(createInstructionCombiningPass()); addPass(pm, createInstructionCombiningPass());
pm.add(createIndVarSimplifyPass()); addPass(pm, createIndVarSimplifyPass());
pm.add(createLoopUnrollPass()); addPass(pm, createLoopUnrollPass());
pm.add(createInstructionCombiningPass()); addPass(pm, createInstructionCombiningPass());
pm.add(createGVNPass()); addPass(pm, createGVNPass());
pm.add(createSCCPPass()); addPass(pm, createSCCPPass());
pm.add(createInstructionCombiningPass()); addPass(pm, createInstructionCombiningPass());
pm.add(createCondPropagationPass()); addPass(pm, createCondPropagationPass());
pm.add(createDeadStoreEliminationPass()); addPass(pm, createDeadStoreEliminationPass());
pm.add(createAggressiveDCEPass()); addPass(pm, createAggressiveDCEPass());
pm.add(createCFGSimplificationPass()); addPass(pm, createCFGSimplificationPass());
pm.add(createSimplifyLibCallsPass()); addPass(pm, createSimplifyLibCallsPass());
pm.add(createDeadTypeEliminationPass()); addPass(pm, createDeadTypeEliminationPass());
pm.add(createConstantMergePass()); addPass(pm, createConstantMergePass());
} }
// level -O4 and -O5 are linktime optimizations // level -O4 and -O5 are linktime optimizations
@ -214,7 +227,10 @@ bool ldc_optimize_module(llvm::Module* m)
} }
PassManager pm; PassManager pm;
pm.add(new TargetData(m));
if (verifyEach) pm.add(createVerifierPass());
addPass(pm, new TargetData(m));
bool optimize = optimizeLevel != 0 || doInline(); bool optimize = optimizeLevel != 0 || doInline();
@ -231,7 +247,7 @@ bool ldc_optimize_module(llvm::Module* m)
const PassInfo* pass = passList[i]; const PassInfo* pass = passList[i];
if (PassInfo::NormalCtor_t ctor = pass->getNormalCtor()) { if (PassInfo::NormalCtor_t ctor = pass->getNormalCtor()) {
pm.add(ctor()); addPass(pm, ctor());
} else { } else {
const char* arg = pass->getPassArgument(); // may return null const char* arg = pass->getPassArgument(); // may return null
if (arg) if (arg)
@ -249,7 +265,7 @@ bool ldc_optimize_module(llvm::Module* m)
if (!disableStripMetaData) { if (!disableStripMetaData) {
// This one is purposely not disabled by disableLangSpecificPasses // This one is purposely not disabled by disableLangSpecificPasses
// because the code generator will assert if it's not used. // because the code generator will assert if it's not used.
pm.add(createStripMetaData()); addPass(pm, createStripMetaData());
} }
#endif #endif