//===----------------------------------------------------------------------===// // The LLVM analyze utility // // This utility is designed to print out the results of running various analysis // passes on a program. This is useful for understanding a program, or for // debugging an analysis pass. // // analyze --help - Output information about command line switches // analyze --quiet - Do not print analysis name before output // //===----------------------------------------------------------------------===// #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Bytecode/Reader.h" #include "llvm/Assembly/Parser.h" #include "llvm/Support/PassNameParser.h" #include struct ModulePassPrinter : public Pass { const PassInfo *PassToPrint; ModulePassPrinter(const PassInfo *PI) : PassToPrint(PI) {} virtual bool run(Module &M) { std::cout << "Printing Analysis info for Pass " << PassToPrint->getPassName() << ":\n"; getAnalysisID(PassToPrint).print(std::cout, &M); // Get and print pass... return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequiredID(PassToPrint); AU.setPreservesAll(); } }; struct FunctionPassPrinter : public FunctionPass { const PassInfo *PassToPrint; FunctionPassPrinter(const PassInfo *PI) : PassToPrint(PI) {} virtual bool runOnFunction(Function &F) { std::cout << "Printing Analysis info for function '" << F.getName() << "': Pass " << PassToPrint->getPassName() << ":\n"; getAnalysisID(PassToPrint).print(std::cout, F.getParent()); // Get and print pass... return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequiredID(PassToPrint); AU.setPreservesAll(); } }; struct BasicBlockPassPrinter : public BasicBlockPass { const PassInfo *PassToPrint; BasicBlockPassPrinter(const PassInfo *PI) : PassToPrint(PI) {} virtual bool runOnBasicBlock(BasicBlock &BB) { std::cout << "Printing Analysis info for BasicBlock '" << BB.getName() << "': Pass " << PassToPrint->getPassName() << ":\n"; getAnalysisID(PassToPrint).print(std::cout, BB.getParent()->getParent()); // Get and print pass... return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequiredID(PassToPrint); AU.setPreservesAll(); } }; static cl::opt InputFilename(cl::Positional, cl::desc(""), cl::init("-"), cl::value_desc("filename")); static cl::opt Quiet("q", cl::desc("Don't print analysis pass names")); static cl::alias QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet)); // The AnalysesList is automatically populated with registered Passes by the // PassNameParser. // static cl::list > AnalysesList(cl::desc("Analyses available:")); int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, " llvm analysis printer tool\n"); Module *CurMod = 0; try { CurMod = ParseBytecodeFile(InputFilename); if (!CurMod && !(CurMod = ParseAssemblyFile(InputFilename))){ std::cerr << argv[0] << ": input file didn't read correctly.\n"; return 1; } } catch (const ParseException &E) { std::cerr << argv[0] << ": " << E.getMessage() << "\n"; return 1; } // Create a PassManager to hold and optimize the collection of passes we are // about to build... // PassManager Passes; // Create a new optimization pass for each one specified on the command line for (unsigned i = 0; i < AnalysesList.size(); ++i) { const PassInfo *Analysis = AnalysesList[i]; if (Analysis->getNormalCtor()) { Pass *P = Analysis->getNormalCtor()(); Passes.add(P); if (BasicBlockPass *BBP = dynamic_cast(P)) Passes.add(new BasicBlockPassPrinter(Analysis)); else if (FunctionPass *FP = dynamic_cast(P)) Passes.add(new FunctionPassPrinter(Analysis)); else Passes.add(new ModulePassPrinter(Analysis)); } else std::cerr << argv[0] << ": cannot create pass: " << Analysis->getPassName() << "\n"; } Passes.run(*CurMod); delete CurMod; return 0; }