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/Analysis/CallGraph.h" 21 #include "llvm/IR/CallSite.h" 22 #include "llvm/IR/Module.h" 23 #include "llvm/Pass.h" 24 #include "llvm/Support/raw_ostream.h" 25 using namespace llvm; 26 27 namespace { 28 /// ExternalFunctionsPassedConstants - This pass prints out call sites to 29 /// external functions that are called with constant arguments. This can be 30 /// useful when looking for standard library functions we should constant fold 31 /// or handle in alias analyses. 32 struct ExternalFunctionsPassedConstants : public ModulePass { 33 static char ID; // Pass ID, replacement for typeid 34 ExternalFunctionsPassedConstants() : ModulePass(ID) {} 35 bool runOnModule(Module &M) override { 36 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 37 if (!I->isDeclaration()) continue; 38 39 bool PrintedFn = false; 40 for (User *U : I->users()) { 41 Instruction *UI = dyn_cast<Instruction>(U); 42 if (!UI) continue; 43 44 CallSite CS(cast<Value>(UI)); 45 if (!CS) continue; 46 47 for (CallSite::arg_iterator AI = CS.arg_begin(), 48 E = CS.arg_end(); AI != E; ++AI) { 49 if (!isa<Constant>(*AI)) continue; 50 51 if (!PrintedFn) { 52 errs() << "Function '" << I->getName() << "':\n"; 53 PrintedFn = true; 54 } 55 errs() << *UI; 56 break; 57 } 58 } 59 } 60 61 return false; 62 } 63 64 void getAnalysisUsage(AnalysisUsage &AU) const override { 65 AU.setPreservesAll(); 66 } 67 }; 68 } 69 70 char ExternalFunctionsPassedConstants::ID = 0; 71 static RegisterPass<ExternalFunctionsPassedConstants> 72 P1("print-externalfnconstants", 73 "Print external fn callsites passed constants"); 74 75 namespace { 76 struct CallGraphPrinter : public ModulePass { 77 static char ID; // Pass ID, replacement for typeid 78 CallGraphPrinter() : ModulePass(ID) {} 79 80 void getAnalysisUsage(AnalysisUsage &AU) const override { 81 AU.setPreservesAll(); 82 AU.addRequiredTransitive<CallGraphWrapperPass>(); 83 } 84 bool runOnModule(Module &M) override { 85 getAnalysis<CallGraphWrapperPass>().print(errs(), &M); 86 return false; 87 } 88 }; 89 } 90 91 char CallGraphPrinter::ID = 0; 92 static RegisterPass<CallGraphPrinter> 93 P2("print-callgraph", "Print a call graph"); 94