Newer
Older
//===- PassManager.cpp - LLVM Pass Infrastructure Implementation ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the LLVM Pass Manager infrastructure.
//
//===----------------------------------------------------------------------===//
#include "llvm/PassManagers.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Timer.h"
Chris Lattner
committed
#include "llvm/Support/raw_ostream.h"
// See PassManagers.h for Pass Manager infrastructure overview.
namespace llvm {
//===----------------------------------------------------------------------===//
// Pass debugging information. Often it is useful to find out what pass is
// running when a crash occurs in a utility. When this library is compiled with
// debugging on, a command line option (--debug-pass) is enabled that causes the
// pass name to be printed before it executes.
//
// Different debug levels that can be enabled...
enum PassDebugLevel {
Dmitri Gribenko
committed
Disabled, Arguments, Structure, Executions, Details
static cl::opt<enum PassDebugLevel>
PassDebugging("debug-pass", cl::Hidden,
cl::desc("Print PassManager debugging information"),
cl::values(
Dmitri Gribenko
committed
clEnumVal(Disabled , "disable debug output"),
clEnumVal(Arguments , "print pass arguments to pass to 'opt'"),
clEnumVal(Structure , "print pass structure before run()"),
clEnumVal(Executions, "print pass name before it is executed"),
clEnumVal(Details , "print pass details when it is executed"),
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"),
cl::Hidden);
llvm::cl::desc("Print IR after specified passes"),
cl::Hidden);
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(const PassInfo *PI,
for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) {
const llvm::PassInfo *PassInf = PassesToPrint[i];
if (PassInf)
if (PassInf->getPassArgument() == PI->getPassArgument()) {
return true;
}
/// This is a utility to check whether a pass should have IR dumped
/// before it.
static bool ShouldPrintBeforePass(const PassInfo *PI) {
return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PI, PrintBefore);
}
/// This is a utility to check whether a pass should have IR dumped
/// after it.
static bool ShouldPrintAfterPass(const PassInfo *PI) {
return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter);
} // End of llvm namespace
/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
/// or higher is specified.
bool PMDataManager::isPassDebuggingExecutionsOrMore() const {
return PassDebugging >= Executions;
}
Chris Lattner
committed
void PassManagerPrettyStackEntry::print(raw_ostream &OS) const {
if (V == 0 && M == 0)
OS << "Releasing pass '";
else
OS << "Running pass '";
Chris Lattner
committed
OS << P->getPassName() << "'";
Chris Lattner
committed
if (M) {
OS << " on module '" << M->getModuleIdentifier() << "'.\n";
return;
}
if (V == 0) {
OS << '\n';
return;
}
OS << " on ";
Chris Lattner
committed
if (isa<Function>(V))
OS << "function";
Chris Lattner
committed
else if (isa<BasicBlock>(V))
OS << "basic block";
Chris Lattner
committed
else
OS << "value";
OS << " '";
WriteAsOperand(OS, V, /*PrintTy=*/false, M);
OS << "'\n";
Chris Lattner
committed
}
//===----------------------------------------------------------------------===//
/// BBPassManager manages BasicBlockPass. It batches all the
/// pass together and sequence them to process one basic block before
/// processing next basic block.
Nick Lewycky
committed
class BBPassManager : public PMDataManager, public FunctionPass {
explicit BBPassManager()
: PMDataManager(), FunctionPass(ID) {}
/// Execute all of the passes scheduled for execution. Keep track of
/// whether any of the passes modifies the function, and if so, return true.
bool runOnFunction(Function &F);
/// Pass Manager itself does not invalidate any analysis info.
void getAnalysisUsage(AnalysisUsage &Info) const {
Info.setPreservesAll();
}
bool doInitialization(Module &M);
bool doInitialization(Function &F);
bool doFinalization(Module &M);
bool doFinalization(Function &F);
virtual PMDataManager *getAsPMDataManager() { return this; }
virtual Pass *getAsPass() { return this; }
// Print passes managed by this manager
void dumpPassStructure(unsigned Offset) {
llvm::dbgs().indent(Offset*2) << "BasicBlockPass Manager\n";
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
BasicBlockPass *BP = getContainedPass(Index);
BP->dumpPassStructure(Offset + 1);
dumpLastUses(BP, Offset+1);
BasicBlockPass *getContainedPass(unsigned N) {
assert(N < PassVector.size() && "Pass number out of range!");
BasicBlockPass *BP = static_cast<BasicBlockPass *>(PassVector[N]);
return BP;
Loading
Loading full blame...