1 //===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines pass wrappers around LLVM analyses that don't make sense to 11 // be passes. It provides a nice standard pass interface to these classes so 12 // that they can be printed out by analyze. 13 // 14 // These classes are separated out of analyze.cpp so that it is more clear which 15 // code is the integral part of the analyze tool, and which part of the code is 16 // just making it so more passes are available. 17 // 18 //===----------------------------------------------------------------------===// 19 20 #include "llvm/Module.h" 21 #include "llvm/Pass.h" 22 #include "llvm/Support/CallSite.h" 23 #include "llvm/Analysis/CallGraph.h" 24 #include "llvm/Support/raw_ostream.h" 25 #include <iostream> 26 using namespace llvm; 27 28 namespace { 29 /// ExternalFunctionsPassedConstants - This pass prints out call sites to 30 /// external functions that are called with constant arguments. This can be 31 /// useful when looking for standard library functions we should constant fold 32 /// or handle in alias analyses. 33 struct ExternalFunctionsPassedConstants : public ModulePass { 34 static char ID; // Pass ID, replacement for typeid 35 ExternalFunctionsPassedConstants() : ModulePass(&ID) {} 36 virtual bool runOnModule(Module &M) { 37 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 38 if (I->isDeclaration()) { 39 bool PrintedFn = false; 40 for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); 41 UI != E; ++UI) 42 if (Instruction *User = dyn_cast<Instruction>(*UI)) { 43 CallSite CS = CallSite::get(User); 44 if (CS.getInstruction()) { 45 for (CallSite::arg_iterator AI = CS.arg_begin(), 46 E = CS.arg_end(); AI != E; ++AI) 47 if (isa<Constant>(*AI)) { 48 if (!PrintedFn) { 49 errs() << "Function '" << I->getName() << "':\n"; 50 PrintedFn = true; 51 } 52 errs() << *User; 53 break; 54 } 55 } 56 } 57 } 58 59 return false; 60 } 61 62 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 63 AU.setPreservesAll(); 64 } 65 }; 66 67 char ExternalFunctionsPassedConstants::ID = 0; 68 RegisterPass<ExternalFunctionsPassedConstants> 69 P1("print-externalfnconstants", 70 "Print external fn callsites passed constants"); 71 72 struct CallGraphPrinter : public ModulePass { 73 static char ID; // Pass ID, replacement for typeid 74 CallGraphPrinter() : ModulePass(&ID) {} 75 76 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 77 AU.setPreservesAll(); 78 AU.addRequiredTransitive<CallGraph>(); 79 } 80 virtual bool runOnModule(Module &M) { 81 getAnalysis<CallGraph>().print(std::cerr, &M); 82 return false; 83 } 84 }; 85 86 char CallGraphPrinter::ID = 0; 87 RegisterPass<CallGraphPrinter> 88 P2("print-callgraph", "Print a call graph"); 89 } 90