diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-04-03 07:51:10 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-04-03 07:51:10 +0000 |
commit | b5efedaf2ab20d844d5a21cdef76b55acbf4f01c (patch) | |
tree | ba3309de92b14839b2ca6ca0c6d3b39714f95d4c /lib/VMCore | |
parent | 104bd8179fb5f6551c65c94ebcd0a4918b060189 (diff) |
Notes
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/BasicBlock.cpp | 11 | ||||
-rw-r--r-- | lib/VMCore/Core.cpp | 2 | ||||
-rw-r--r-- | lib/VMCore/DebugLoc.cpp | 24 | ||||
-rw-r--r-- | lib/VMCore/Metadata.cpp | 6 | ||||
-rw-r--r-- | lib/VMCore/Pass.cpp | 18 | ||||
-rw-r--r-- | lib/VMCore/PassManager.cpp | 83 | ||||
-rw-r--r-- | lib/VMCore/PrintModulePass.cpp | 12 |
7 files changed, 135 insertions, 21 deletions
diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp index 16437bc130454..8ad53736c993f 100644 --- a/lib/VMCore/BasicBlock.cpp +++ b/lib/VMCore/BasicBlock.cpp @@ -14,6 +14,7 @@ #include "llvm/BasicBlock.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" #include "llvm/Type.h" #include "llvm/ADT/STLExtras.h" @@ -136,6 +137,16 @@ Instruction* BasicBlock::getFirstNonPHI() { return &*i; } +Instruction* BasicBlock::getFirstNonPHIOrDbg() { + BasicBlock::iterator i = begin(); + // All valid basic blocks should have a terminator, + // which is not a PHINode. If we have an invalid basic + // block we'll get an assertion failure when dereferencing + // a past-the-end iterator. + while (isa<PHINode>(i) || isa<DbgInfoIntrinsic>(i)) ++i; + return &*i; +} + void BasicBlock::dropAllReferences() { for(iterator I = begin(), E = end(); I != E; ++I) I->dropAllReferences(); diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index 44d487a8e2b40..634407ca13ff7 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -1671,7 +1671,7 @@ void LLVMDisposeBuilder(LLVMBuilderRef Builder) { void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) { MDNode *Loc = L ? unwrap<MDNode>(L) : NULL; - unwrap(Builder)->SetCurrentDebugLocation(NewDebugLoc::getFromDILocation(Loc)); + unwrap(Builder)->SetCurrentDebugLocation(DebugLoc::getFromDILocation(Loc)); } LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder) { diff --git a/lib/VMCore/DebugLoc.cpp b/lib/VMCore/DebugLoc.cpp index f02ce57c3b042..f8b45eed0d5e9 100644 --- a/lib/VMCore/DebugLoc.cpp +++ b/lib/VMCore/DebugLoc.cpp @@ -15,7 +15,7 @@ using namespace llvm; // DebugLoc Implementation //===----------------------------------------------------------------------===// -MDNode *NewDebugLoc::getScope(const LLVMContext &Ctx) const { +MDNode *DebugLoc::getScope(const LLVMContext &Ctx) const { if (ScopeIdx == 0) return 0; if (ScopeIdx > 0) { @@ -32,7 +32,7 @@ MDNode *NewDebugLoc::getScope(const LLVMContext &Ctx) const { return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get(); } -MDNode *NewDebugLoc::getInlinedAt(const LLVMContext &Ctx) const { +MDNode *DebugLoc::getInlinedAt(const LLVMContext &Ctx) const { // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at // position specified. Zero is invalid. if (ScopeIdx >= 0) return 0; @@ -44,8 +44,8 @@ MDNode *NewDebugLoc::getInlinedAt(const LLVMContext &Ctx) const { } /// Return both the Scope and the InlinedAt values. -void NewDebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA, - const LLVMContext &Ctx) const { +void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA, + const LLVMContext &Ctx) const { if (ScopeIdx == 0) { Scope = IA = 0; return; @@ -69,9 +69,9 @@ void NewDebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA, } -NewDebugLoc NewDebugLoc::get(unsigned Line, unsigned Col, - MDNode *Scope, MDNode *InlinedAt) { - NewDebugLoc Result; +DebugLoc DebugLoc::get(unsigned Line, unsigned Col, + MDNode *Scope, MDNode *InlinedAt) { + DebugLoc Result; // If no scope is available, this is an unknown location. if (Scope == 0) return Result; @@ -95,7 +95,7 @@ NewDebugLoc NewDebugLoc::get(unsigned Line, unsigned Col, /// getAsMDNode - This method converts the compressed DebugLoc node into a /// DILocation compatible MDNode. -MDNode *NewDebugLoc::getAsMDNode(const LLVMContext &Ctx) const { +MDNode *DebugLoc::getAsMDNode(const LLVMContext &Ctx) const { if (isUnknown()) return 0; MDNode *Scope, *IA; @@ -111,12 +111,12 @@ MDNode *NewDebugLoc::getAsMDNode(const LLVMContext &Ctx) const { return MDNode::get(Ctx2, &Elts[0], 4); } -/// getFromDILocation - Translate the DILocation quad into a NewDebugLoc. -NewDebugLoc NewDebugLoc::getFromDILocation(MDNode *N) { - if (N == 0 || N->getNumOperands() != 4) return NewDebugLoc(); +/// getFromDILocation - Translate the DILocation quad into a DebugLoc. +DebugLoc DebugLoc::getFromDILocation(MDNode *N) { + if (N == 0 || N->getNumOperands() != 4) return DebugLoc(); MDNode *Scope = dyn_cast_or_null<MDNode>(N->getOperand(2)); - if (Scope == 0) return NewDebugLoc(); + if (Scope == 0) return DebugLoc(); unsigned LineNo = 0, ColNo = 0; if (ConstantInt *Line = dyn_cast_or_null<ConstantInt>(N->getOperand(0))) diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index 73e60912e43b3..72de0321c3aae 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -425,7 +425,7 @@ MDNode *Instruction::getMetadataImpl(const char *Kind) const { } void Instruction::setDbgMetadata(MDNode *Node) { - DbgLoc = NewDebugLoc::getFromDILocation(Node); + DbgLoc = DebugLoc::getFromDILocation(Node); } /// setMetadata - Set the metadata of of the specified kind to the specified @@ -436,7 +436,7 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) { // Handle 'dbg' as a special case since it is not stored in the hash table. if (KindID == LLVMContext::MD_dbg) { - DbgLoc = NewDebugLoc::getFromDILocation(Node); + DbgLoc = DebugLoc::getFromDILocation(Node); return; } @@ -549,7 +549,7 @@ getAllMetadataOtherThanDebugLocImpl(SmallVectorImpl<std::pair<unsigned, /// removeAllMetadata - Remove all metadata from this instruction. void Instruction::removeAllMetadata() { assert(hasMetadata() && "Caller should check"); - DbgLoc = NewDebugLoc(); + DbgLoc = DebugLoc(); if (hasMetadataHashEntry()) { getContext().pImpl->MetadataStore.erase(this); setHasMetadataHashEntry(false); diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index a782e5a82e91b..6093750124809 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -18,6 +18,7 @@ #include "llvm/Module.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" +#include "llvm/Assembly/PrintModulePass.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PassNameParser.h" @@ -42,6 +43,11 @@ Pass::~Pass() { // Force out-of-line virtual method. ModulePass::~ModulePass() { } +Pass *ModulePass::createPrinterPass(raw_ostream &O, + const std::string &Banner) const { + return createPrintModulePass(&O, false, Banner); +} + PassManagerType ModulePass::getPotentialPassManagerType() const { return PMT_ModulePassManager; } @@ -113,6 +119,11 @@ void ImmutablePass::initializePass() { // FunctionPass Implementation // +Pass *FunctionPass::createPrinterPass(raw_ostream &O, + const std::string &Banner) const { + return createPrintFunctionPass(Banner, &O); +} + // run - On a module, we run this pass by initializing, runOnFunction'ing once // for every function in the module, then by finalizing. // @@ -155,6 +166,13 @@ PassManagerType FunctionPass::getPotentialPassManagerType() const { // BasicBlockPass Implementation // +Pass *BasicBlockPass::createPrinterPass(raw_ostream &O, + const std::string &Banner) const { + + llvm_unreachable("BasicBlockPass printing unsupported."); + return 0; +} + // To run this pass on a function, we simply call runOnBasicBlock once for each // function. // diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 6774cecdcf244..6ca35ac0260f6 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -13,6 +13,7 @@ #include "llvm/PassManagers.h" +#include "llvm/Assembly/PrintModulePass.h" #include "llvm/Assembly/Writer.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -20,6 +21,7 @@ #include "llvm/Module.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/PassNameParser.h" #include "llvm/Support/raw_ostream.h" #include "llvm/System/Mutex.h" #include "llvm/System/Threading.h" @@ -55,6 +57,57 @@ PassDebugging("debug-pass", cl::Hidden, clEnumVal(Executions, "print pass name before it is executed"), clEnumVal(Details , "print pass details when it is executed"), clEnumValEnd)); + +typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser> +PassOptionList; + +// Print IR out before/after specified passes. +static PassOptionList +PrintBefore("print-before", + llvm::cl::desc("Print IR before specified passes")); + +static PassOptionList +PrintAfter("print-after", + llvm::cl::desc("Print IR after specified passes")); + +static cl::opt<bool> +PrintBeforeAll("print-before-all", + llvm::cl::desc("Print IR before each pass"), + cl::init(false)); +static cl::opt<bool> +PrintAfterAll("print-after-all", + llvm::cl::desc("Print IR after each pass"), + cl::init(false)); + +/// This is a helper to determine whether to print IR before or +/// after a pass. + +static bool ShouldPrintBeforeOrAfterPass(Pass *P, + PassOptionList &PassesToPrint) { + for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) { + const llvm::PassInfo *PassInf = PassesToPrint[i]; + if (PassInf && P->getPassInfo()) + if (PassInf->getPassArgument() == + P->getPassInfo()->getPassArgument()) { + return true; + } + } + return false; +} + + +/// This is a utility to check whether a pass should have IR dumped +/// before it. +static bool ShouldPrintBeforePass(Pass *P) { + return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(P, PrintBefore); +} + +/// This is a utility to check whether a pass should have IR dumped +/// after it. +static bool ShouldPrintAfterPass(Pass *P) { + return PrintAfterAll || ShouldPrintBeforeOrAfterPass(P, PrintAfter); +} + } // End of llvm namespace /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions @@ -182,6 +235,11 @@ public: schedulePass(P); } + /// createPrinterPass - Get a function printer pass. + Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { + return createPrintFunctionPass(Banner, &O); + } + // Prepare for running an on the fly pass, freeing memory if needed // from a previous run. void releaseMemoryOnTheFly(); @@ -252,6 +310,11 @@ public: } } + /// createPrinterPass - Get a module printer pass. + Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { + return createPrintModulePass(&O, false, Banner); + } + /// run - Execute all of the passes scheduled for execution. Keep track of /// whether any of the passes modifies the module, and if so, return true. bool runOnModule(Module &M); @@ -331,6 +394,11 @@ public: schedulePass(P); } + /// createPrinterPass - Get a module printer pass. + Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { + return createPrintModulePass(&O, false, Banner); + } + /// run - Execute all of the passes scheduled for execution. Keep track of /// whether any of the passes modifies the module, and if so, return true. bool run(Module &M); @@ -1208,7 +1276,14 @@ FunctionPassManager::~FunctionPassManager() { /// there is no need to delete the pass. (TODO delete passes.) /// This implies that all passes MUST be allocated with 'new'. void FunctionPassManager::add(Pass *P) { + if (ShouldPrintBeforePass(P)) + add(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ") + + P->getPassName() + " ***")); FPM->add(P); + + if (ShouldPrintAfterPass(P)) + add(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ") + + P->getPassName() + " ***")); } /// run - Execute all of the passes scheduled for execution. Keep @@ -1519,7 +1594,15 @@ PassManager::~PassManager() { /// will be destroyed as well, so there is no need to delete the pass. This /// implies that all passes MUST be allocated with 'new'. void PassManager::add(Pass *P) { + if (ShouldPrintBeforePass(P)) + add(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ") + + P->getPassName() + " ***")); + PM->add(P); + + if (ShouldPrintAfterPass(P)) + add(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ") + + P->getPassName() + " ***")); } /// run - Execute all of the passes scheduled for execution. Keep track of diff --git a/lib/VMCore/PrintModulePass.cpp b/lib/VMCore/PrintModulePass.cpp index f0f6e7a9efe7c..2d69dce07f3f7 100644 --- a/lib/VMCore/PrintModulePass.cpp +++ b/lib/VMCore/PrintModulePass.cpp @@ -23,21 +23,22 @@ using namespace llvm; namespace { class PrintModulePass : public ModulePass { + std::string Banner; raw_ostream *Out; // raw_ostream to print on bool DeleteStream; // Delete the ostream in our dtor? public: static char ID; PrintModulePass() : ModulePass(&ID), Out(&dbgs()), DeleteStream(false) {} - PrintModulePass(raw_ostream *o, bool DS) - : ModulePass(&ID), Out(o), DeleteStream(DS) {} + PrintModulePass(const std::string &B, raw_ostream *o, bool DS) + : ModulePass(&ID), Banner(B), Out(o), DeleteStream(DS) {} ~PrintModulePass() { if (DeleteStream) delete Out; } bool runOnModule(Module &M) { - (*Out) << M; + (*Out) << Banner << M; return false; } @@ -85,8 +86,9 @@ Y("print-function","Print function to stderr"); /// createPrintModulePass - Create and return a pass that writes the /// module to the specified raw_ostream. ModulePass *llvm::createPrintModulePass(llvm::raw_ostream *OS, - bool DeleteStream) { - return new PrintModulePass(OS, DeleteStream); + bool DeleteStream, + const std::string &Banner) { + return new PrintModulePass(Banner, OS, DeleteStream); } /// createPrintFunctionPass - Create and return a pass that prints |