//===- PassPrinters.cpp - Utilities to print analysis info for passes -----===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// /// /// \file /// \brief Utilities to print analysis info for various kinds of passes. /// //===----------------------------------------------------------------------===// #include "PassPrinters.h" #include "llvm/Analysis/CallGraphSCCPass.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/RegionPass.h" #include "llvm/IR/Function.h" #include "llvm/Pass.h" #include <string> using namespace llvm; namespace { struct FunctionPassPrinter : public FunctionPass { const PassInfo *PassToPrint; raw_ostream &Out; static char ID; std::string PassName; bool QuietPass; FunctionPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet) : FunctionPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) { std::string PassToPrintName = PassToPrint->getPassName(); PassName = "FunctionPass Printer: " + PassToPrintName; } bool runOnFunction(Function &F) override { if (!QuietPass) Out << "Printing analysis '" << PassToPrint->getPassName() << "' for function '" << F.getName() << "':\n"; // Get and print pass... getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, F.getParent()); return false; } const char *getPassName() const override { return PassName.c_str(); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequiredID(PassToPrint->getTypeInfo()); AU.setPreservesAll(); } }; char FunctionPassPrinter::ID = 0; struct CallGraphSCCPassPrinter : public CallGraphSCCPass { static char ID; const PassInfo *PassToPrint; raw_ostream &Out; std::string PassName; bool QuietPass; CallGraphSCCPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet) : CallGraphSCCPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) { std::string PassToPrintName = PassToPrint->getPassName(); PassName = "CallGraphSCCPass Printer: " + PassToPrintName; } bool runOnSCC(CallGraphSCC &SCC) override { if (!QuietPass) Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; // Get and print pass... for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { Function *F = (*I)->getFunction(); if (F) getAnalysisID<Pass>(PassToPrint->getTypeInfo()) .print(Out, F->getParent()); } return false; } const char *getPassName() const override { return PassName.c_str(); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequiredID(PassToPrint->getTypeInfo()); AU.setPreservesAll(); } }; char CallGraphSCCPassPrinter::ID = 0; struct ModulePassPrinter : public ModulePass { static char ID; const PassInfo *PassToPrint; raw_ostream &Out; std::string PassName; bool QuietPass; ModulePassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet) : ModulePass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) { std::string PassToPrintName = PassToPrint->getPassName(); PassName = "ModulePass Printer: " + PassToPrintName; } bool runOnModule(Module &M) override { if (!QuietPass) Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; // Get and print pass... getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, &M); return false; } const char *getPassName() const override { return PassName.c_str(); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequiredID(PassToPrint->getTypeInfo()); AU.setPreservesAll(); } }; char ModulePassPrinter::ID = 0; struct LoopPassPrinter : public LoopPass { static char ID; const PassInfo *PassToPrint; raw_ostream &Out; std::string PassName; bool QuietPass; LoopPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet) : LoopPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) { std::string PassToPrintName = PassToPrint->getPassName(); PassName = "LoopPass Printer: " + PassToPrintName; } bool runOnLoop(Loop *L, LPPassManager &LPM) override { if (!QuietPass) Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; // Get and print pass... getAnalysisID<Pass>(PassToPrint->getTypeInfo()) .print(Out, L->getHeader()->getParent()->getParent()); return false; } const char *getPassName() const override { return PassName.c_str(); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequiredID(PassToPrint->getTypeInfo()); AU.setPreservesAll(); } }; char LoopPassPrinter::ID = 0; struct RegionPassPrinter : public RegionPass { static char ID; const PassInfo *PassToPrint; raw_ostream &Out; std::string PassName; bool QuietPass; RegionPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet) : RegionPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) { std::string PassToPrintName = PassToPrint->getPassName(); PassName = "RegionPass Printer: " + PassToPrintName; } bool runOnRegion(Region *R, RGPassManager &RGM) override { if (!QuietPass) { Out << "Printing analysis '" << PassToPrint->getPassName() << "' for " << "region: '" << R->getNameStr() << "' in function '" << R->getEntry()->getParent()->getName() << "':\n"; } // Get and print pass... getAnalysisID<Pass>(PassToPrint->getTypeInfo()) .print(Out, R->getEntry()->getParent()->getParent()); return false; } const char *getPassName() const override { return PassName.c_str(); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequiredID(PassToPrint->getTypeInfo()); AU.setPreservesAll(); } }; char RegionPassPrinter::ID = 0; struct BasicBlockPassPrinter : public BasicBlockPass { const PassInfo *PassToPrint; raw_ostream &Out; static char ID; std::string PassName; bool QuietPass; BasicBlockPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet) : BasicBlockPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) { std::string PassToPrintName = PassToPrint->getPassName(); PassName = "BasicBlockPass Printer: " + PassToPrintName; } bool runOnBasicBlock(BasicBlock &BB) override { if (!QuietPass) Out << "Printing Analysis info for BasicBlock '" << BB.getName() << "': Pass " << PassToPrint->getPassName() << ":\n"; // Get and print pass... getAnalysisID<Pass>(PassToPrint->getTypeInfo()) .print(Out, BB.getParent()->getParent()); return false; } const char *getPassName() const override { return PassName.c_str(); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequiredID(PassToPrint->getTypeInfo()); AU.setPreservesAll(); } }; char BasicBlockPassPrinter::ID = 0; } FunctionPass *llvm::createFunctionPassPrinter(const PassInfo *PI, raw_ostream &OS, bool Quiet) { return new FunctionPassPrinter(PI, OS, Quiet); } CallGraphSCCPass *llvm::createCallGraphPassPrinter(const PassInfo *PI, raw_ostream &OS, bool Quiet) { return new CallGraphSCCPassPrinter(PI, OS, Quiet); } ModulePass *llvm::createModulePassPrinter(const PassInfo *PI, raw_ostream &OS, bool Quiet) { return new ModulePassPrinter(PI, OS, Quiet); } LoopPass *llvm::createLoopPassPrinter(const PassInfo *PI, raw_ostream &OS, bool Quiet) { return new LoopPassPrinter(PI, OS, Quiet); } RegionPass *llvm::createRegionPassPrinter(const PassInfo *PI, raw_ostream &OS, bool Quiet) { return new RegionPassPrinter(PI, OS, Quiet); } BasicBlockPass *llvm::createBasicBlockPassPrinter(const PassInfo *PI, raw_ostream &OS, bool Quiet) { return new BasicBlockPassPrinter(PI, OS, Quiet); }