summaryrefslogtreecommitdiff
path: root/lib/VMCore
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-04-03 07:51:10 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-04-03 07:51:10 +0000
commitb5efedaf2ab20d844d5a21cdef76b55acbf4f01c (patch)
treeba3309de92b14839b2ca6ca0c6d3b39714f95d4c /lib/VMCore
parent104bd8179fb5f6551c65c94ebcd0a4918b060189 (diff)
Notes
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/BasicBlock.cpp11
-rw-r--r--lib/VMCore/Core.cpp2
-rw-r--r--lib/VMCore/DebugLoc.cpp24
-rw-r--r--lib/VMCore/Metadata.cpp6
-rw-r--r--lib/VMCore/Pass.cpp18
-rw-r--r--lib/VMCore/PassManager.cpp83
-rw-r--r--lib/VMCore/PrintModulePass.cpp12
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