1193323Sed//===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file defines pass wrappers around LLVM analyses that don't make sense to 11193323Sed// be passes. It provides a nice standard pass interface to these classes so 12193323Sed// that they can be printed out by analyze. 13193323Sed// 14193323Sed// These classes are separated out of analyze.cpp so that it is more clear which 15193323Sed// code is the integral part of the analyze tool, and which part of the code is 16193323Sed// just making it so more passes are available. 17193323Sed// 18193323Sed//===----------------------------------------------------------------------===// 19193323Sed 20249423Sdim#include "llvm/Analysis/CallGraph.h" 21276479Sdim#include "llvm/IR/CallSite.h" 22249423Sdim#include "llvm/IR/Module.h" 23193323Sed#include "llvm/Pass.h" 24198090Srdivacky#include "llvm/Support/raw_ostream.h" 25193323Sedusing namespace llvm; 26193323Sed 27193323Sednamespace { 28193323Sed /// ExternalFunctionsPassedConstants - This pass prints out call sites to 29193323Sed /// external functions that are called with constant arguments. This can be 30193323Sed /// useful when looking for standard library functions we should constant fold 31193323Sed /// or handle in alias analyses. 32193323Sed struct ExternalFunctionsPassedConstants : public ModulePass { 33193323Sed static char ID; // Pass ID, replacement for typeid 34212793Sdim ExternalFunctionsPassedConstants() : ModulePass(ID) {} 35276479Sdim bool runOnModule(Module &M) override { 36198090Srdivacky for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 37198090Srdivacky if (!I->isDeclaration()) continue; 38276479Sdim 39198090Srdivacky bool PrintedFn = false; 40276479Sdim for (User *U : I->users()) { 41276479Sdim Instruction *UI = dyn_cast<Instruction>(U); 42276479Sdim if (!UI) continue; 43276479Sdim 44276479Sdim CallSite CS(cast<Value>(UI)); 45212793Sdim if (!CS) continue; 46276479Sdim 47198090Srdivacky for (CallSite::arg_iterator AI = CS.arg_begin(), 48198090Srdivacky E = CS.arg_end(); AI != E; ++AI) { 49198090Srdivacky if (!isa<Constant>(*AI)) continue; 50198090Srdivacky 51198090Srdivacky if (!PrintedFn) { 52198090Srdivacky errs() << "Function '" << I->getName() << "':\n"; 53198090Srdivacky PrintedFn = true; 54193323Sed } 55276479Sdim errs() << *UI; 56198090Srdivacky break; 57198090Srdivacky } 58193323Sed } 59198090Srdivacky } 60193323Sed 61193323Sed return false; 62193323Sed } 63193323Sed 64276479Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 65193323Sed AU.setPreservesAll(); 66193323Sed } 67193323Sed }; 68212793Sdim} 69193323Sed 70212793Sdimchar ExternalFunctionsPassedConstants::ID = 0; 71212793Sdimstatic RegisterPass<ExternalFunctionsPassedConstants> 72193323Sed P1("print-externalfnconstants", 73193323Sed "Print external fn callsites passed constants"); 74193323Sed 75212793Sdimnamespace { 76193323Sed struct CallGraphPrinter : public ModulePass { 77193323Sed static char ID; // Pass ID, replacement for typeid 78212793Sdim CallGraphPrinter() : ModulePass(ID) {} 79193323Sed 80276479Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 81193323Sed AU.setPreservesAll(); 82276479Sdim AU.addRequiredTransitive<CallGraphWrapperPass>(); 83193323Sed } 84276479Sdim bool runOnModule(Module &M) override { 85276479Sdim getAnalysis<CallGraphWrapperPass>().print(errs(), &M); 86193323Sed return false; 87193323Sed } 88193323Sed }; 89212793Sdim} 90193323Sed 91212793Sdimchar CallGraphPrinter::ID = 0; 92212793Sdimstatic RegisterPass<CallGraphPrinter> 93212793Sdim P2("print-callgraph", "Print a call graph"); 94