+static cl::opt<bool>
+AnalyzeOnly("analyze", cl::desc("Only perform analysis, no optimization"));
+
+// ---------- Define Printers for module and function passes ------------
+namespace {
+
+struct CallGraphSCCPassPrinter : public CallGraphSCCPass {
+ static char ID;
+ const PassInfo *PassToPrint;
+ CallGraphSCCPassPrinter(const PassInfo *PI) :
+ CallGraphSCCPass(&ID), PassToPrint(PI) {}
+
+ virtual bool runOnSCC(const std::vector<CallGraphNode *>&SCC) {
+ if (!Quiet) {
+ outs() << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
+
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
+ Function *F = SCC[i]->getFunction();
+ if (F) {
+ outs().flush();
+ getAnalysisID<Pass>(PassToPrint).print(cout, F->getParent());
+ cout << std::flush;
+ }
+ }
+ }
+ // Get and print pass...
+ return false;
+ }
+
+ virtual const char *getPassName() const { return "'Pass' Printer"; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(PassToPrint);
+ AU.setPreservesAll();
+ }
+};
+
+char CallGraphSCCPassPrinter::ID = 0;
+
+struct ModulePassPrinter : public ModulePass {
+ static char ID;
+ const PassInfo *PassToPrint;
+ ModulePassPrinter(const PassInfo *PI) : ModulePass(&ID),
+ PassToPrint(PI) {}
+
+ virtual bool runOnModule(Module &M) {
+ if (!Quiet) {
+ outs() << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
+ outs().flush();
+ getAnalysisID<Pass>(PassToPrint).print(cout, &M);
+ cout << std::flush;
+ }
+
+ // Get and print pass...
+ return false;
+ }
+
+ virtual const char *getPassName() const { return "'Pass' Printer"; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(PassToPrint);
+ AU.setPreservesAll();
+ }
+};
+
+char ModulePassPrinter::ID = 0;
+struct FunctionPassPrinter : public FunctionPass {
+ const PassInfo *PassToPrint;
+ static char ID;
+ FunctionPassPrinter(const PassInfo *PI) : FunctionPass(&ID),
+ PassToPrint(PI) {}
+
+ virtual bool runOnFunction(Function &F) {
+ if (!Quiet) {
+ outs() << "Printing analysis '" << PassToPrint->getPassName()
+ << "' for function '" << F.getName() << "':\n";
+ }
+ // Get and print pass...
+ outs().flush();
+ getAnalysisID<Pass>(PassToPrint).print(cout, F.getParent());
+ cout << std::flush;
+ return false;
+ }
+
+ virtual const char *getPassName() const { return "FunctionPass Printer"; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(PassToPrint);
+ AU.setPreservesAll();
+ }
+};
+
+char FunctionPassPrinter::ID = 0;
+
+struct LoopPassPrinter : public LoopPass {
+ static char ID;
+ const PassInfo *PassToPrint;
+ LoopPassPrinter(const PassInfo *PI) :
+ LoopPass(&ID), PassToPrint(PI) {}
+
+ virtual bool runOnLoop(Loop *L, LPPassManager &LPM) {
+ if (!Quiet) {
+ outs() << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
+ outs().flush();
+ getAnalysisID<Pass>(PassToPrint).print(cout,
+ L->getHeader()->getParent()->getParent());
+ cout << std::flush;
+ }
+ // Get and print pass...
+ return false;
+ }
+
+ virtual const char *getPassName() const { return "'Pass' Printer"; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(PassToPrint);
+ AU.setPreservesAll();
+ }
+};
+
+char LoopPassPrinter::ID = 0;
+
+struct BasicBlockPassPrinter : public BasicBlockPass {
+ const PassInfo *PassToPrint;
+ static char ID;
+ BasicBlockPassPrinter(const PassInfo *PI)
+ : BasicBlockPass(&ID), PassToPrint(PI) {}
+
+ virtual bool runOnBasicBlock(BasicBlock &BB) {
+ if (!Quiet) {
+ outs() << "Printing Analysis info for BasicBlock '" << BB.getName()
+ << "': Pass " << PassToPrint->getPassName() << ":\n";
+ }
+
+ // Get and print pass...
+ outs().flush();
+ getAnalysisID<Pass>(PassToPrint).print(cout, BB.getParent()->getParent());
+ cout << std::flush;
+ return false;
+ }
+
+ virtual const char *getPassName() const { return "BasicBlockPass Printer"; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(PassToPrint);
+ AU.setPreservesAll();
+ }
+};
+
+char BasicBlockPassPrinter::ID = 0;
+inline void addPass(PassManager &PM, Pass *P) {
+ // Add the pass to the pass manager...
+ PM.add(P);
+
+ // If we are verifying all of the intermediate steps, add the verifier...
+ if (VerifyEach) PM.add(createVerifierPass());
+}
+
+/// AddOptimizationPasses - This routine adds optimization passes
+/// based on selected optimization level, OptLevel. This routine
+/// duplicates llvm-gcc behaviour.
+///
+/// OptLevel - Optimization Level
+void AddOptimizationPasses(PassManager &MPM, FunctionPassManager &FPM,
+ unsigned OptLevel) {
+ createStandardFunctionPasses(&FPM, OptLevel);
+
+ llvm::Pass *InliningPass = OptLevel > 1 ? createFunctionInliningPass() : 0;
+ createStandardModulePasses(&MPM, OptLevel,
+ /*OptimizeSize=*/ false,
+ UnitAtATime,
+ /*UnrollLoops=*/ OptLevel > 1,
+ !DisableSimplifyLibCalls,
+ /*HaveExceptions=*/ true,
+ InliningPass);
+}
+
+void AddStandardCompilePasses(PassManager &PM) {
+ PM.add(createVerifierPass()); // Verify that input is correct
+
+ addPass(PM, createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp
+
+ // If the -strip-debug command line option was specified, do it.
+ if (StripDebug)
+ addPass(PM, createStripSymbolsPass(true));
+
+ if (DisableOptimizations) return;
+
+ llvm::Pass *InliningPass = !DisableInline ? createFunctionInliningPass() : 0;
+
+ // -std-compile-opts adds the same module passes as -O3.
+ createStandardModulePasses(&PM, 3,
+ /*OptimizeSize=*/ false,
+ /*UnitAtATime=*/ true,
+ /*UnrollLoops=*/ true,
+ /*SimplifyLibCalls=*/ true,
+ /*HaveExceptions=*/ true,
+ InliningPass);
+}
+
+} // anonymous namespace
+