Skip to content
PassManager.cpp 62.9 KiB
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.
//
//===----------------------------------------------------------------------===//
//
Dan Gohman's avatar
Dan Gohman committed
// This file implements the LLVM Pass Manager infrastructure.
//
//===----------------------------------------------------------------------===//


#include "llvm/PassManagers.h"
David Greene's avatar
 
David Greene committed
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CommandLine.h"
David Greene's avatar
David Greene committed
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
Devang Patel's avatar
Devang Patel committed
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
David Greene's avatar
 
David Greene committed
#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
Jeff Cohen's avatar
Jeff Cohen committed
#include <algorithm>
#include <map>
using namespace llvm;
// 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 {
  Disabled, Arguments, Structure, Executions, Details
bool TimePassesIsEnabled = false;

/// Encapsulate PassManager debug options. These are convenient options that
/// should be available to any LLVM-based tool. They exist purely as
/// command-line debug options, therefore don't need to be local to an LLVM
/// context or captured by a formal API. In all respects they are handled like
/// global variables, but being defined in the LLVMCore library cannot have
/// static initializers and must be destroyed only at llvm_shutdown.
struct PassDebugOpts {
  cl::opt<enum PassDebugLevel> PassDebugging;

  typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser>
  PassOptionList;

  // Print IR out before/after specified passes.
  PassOptionList PrintBefore;

  PassOptionList PrintAfter;

  cl::opt<bool> PrintBeforeAll;
  cl::opt<bool> PrintAfterAll;

  cl::opt<bool,true> EnableTiming;

  PassDebugOpts():
    PassDebugging("debug-pass", cl::Hidden,
                  cl::desc("Print PassManager debugging information"),
                  cl::values(
                    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"),
                    clEnumValEnd)),
    PrintBefore("print-before",
                llvm::cl::desc("Print IR before specified passes"),
                cl::Hidden),
    PrintAfter("print-after",
               llvm::cl::desc("Print IR after specified passes"),
               cl::Hidden),
    PrintBeforeAll("print-before-all",
                   llvm::cl::desc("Print IR before each pass"),
                   cl::init(false)),
    PrintAfterAll("print-after-all",
                  llvm::cl::desc("Print IR after each pass"),
                  cl::init(false)),
    EnableTiming("time-passes", cl::location(TimePassesIsEnabled),
                 cl::desc(
                   "Time each pass, printing elapsed time for each on exit"))
  {}

  /// This is a helper to determine whether to print IR before or
  /// after a pass.
  bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI,
                                    PassOptionList &PassesToPrint) {
    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;
        }
    }
    return false;
David Greene's avatar
 
David Greene committed
  }
Dan Gohman's avatar
Dan Gohman committed

  /// This is a utility to check whether a pass should have IR dumped
  /// before it.
  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.
  bool ShouldPrintAfterPass(const PassInfo *PI) {
    return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter);
  }
};
David Greene's avatar
 
David Greene committed

static ManagedStatic<PassDebugOpts> GlobalPassDebugOpts;

/// This is called by tools to force registration of debugging options and
/// ensure they appear in the tool's -help usage.
void initializePassManager() {
  // Force instantiation of PassDebugOpts.
  *GlobalPassDebugOpts;
David Greene's avatar
 
David Greene committed
}

/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
/// or higher is specified.
bool PMDataManager::isPassDebuggingExecutionsOrMore() const {
  return GlobalPassDebugOpts->PassDebugging >= Executions;
void PassManagerPrettyStackEntry::print(raw_ostream &OS) const {
  if (V == 0 && M == 0)
    OS << "Releasing pass '";
  else
    OS << "Running pass '";
Dan Gohman's avatar
Dan Gohman committed

Dan Gohman's avatar
Dan Gohman committed

  if (M) {
    OS << " on module '" << M->getModuleIdentifier() << "'.\n";
    return;
  }
  if (V == 0) {
    OS << '\n';
    return;
  }

    OS << "value";

  OS << " '";
  WriteAsOperand(OS, V, /*PrintTy=*/false, M);
  OS << "'\n";
Devang Patel's avatar
Devang Patel committed
//===----------------------------------------------------------------------===//
// BBPassManager
Devang Patel's avatar
Devang Patel committed
//
/// BBPassManager manages BasicBlockPass. It batches all the
/// pass together and sequence them to process one basic block before
/// processing next basic block.
class BBPassManager : public PMDataManager, public FunctionPass {
Devang Patel's avatar
Devang Patel committed
  static char ID;
  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();
  }

Loading
Loading full blame...