154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton//===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===// 254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// 354e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// The LLVM Compiler Infrastructure 454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// 554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// This file is distributed under the University of Illinois Open Source 654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// License. See LICENSE.TXT for details. 754e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// 854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton//===----------------------------------------------------------------------===// 954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// 1054e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// This file defines pass wrappers around LLVM analyses that don't make sense to 1154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// be passes. It provides a nice standard pass interface to these classes so 1254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// that they can be printed out by analyze. 13b9db9d5bb01963774f28540dbe2c5a11f586ff29Daniel Malea// 14b9db9d5bb01963774f28540dbe2c5a11f586ff29Daniel Malea// These classes are separated out of analyze.cpp so that it is more clear which 159ea7d8750030914f13dcdfe167542b8047de51a4Filipe Cabecinhas// code is the integral part of the analyze tool, and which part of the code is 1654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// just making it so more passes are available. 1752ce56101e97732def08c46279cffcb693458e63Stephen Wilson// 1854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton//===----------------------------------------------------------------------===// 1954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton 209ea7d8750030914f13dcdfe167542b8047de51a4Filipe Cabecinhas#include "llvm/Analysis/CallGraph.h" 219ea7d8750030914f13dcdfe167542b8047de51a4Filipe Cabecinhas#include "llvm/IR/CallSite.h" 2254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton#include "llvm/IR/Module.h" 2354e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton#include "llvm/Pass.h" 24fa2cd91f47a7782b9c040058aed369e022e332d3Sylvestre Ledru#include "llvm/Support/raw_ostream.h" 259ea7d8750030914f13dcdfe167542b8047de51a4Filipe Cabecinhasusing namespace llvm; 2626f93cead39bed47837880605ed70562e2796818Eli Friedman 2726f93cead39bed47837880605ed70562e2796818Eli Friedmannamespace { 284b66329ac82b5f3d939bd31b4d1498da9257d85aJohnny Chen /// ExternalFunctionsPassedConstants - This pass prints out call sites to 294b66329ac82b5f3d939bd31b4d1498da9257d85aJohnny Chen /// external functions that are called with constant arguments. This can be 309ea7d8750030914f13dcdfe167542b8047de51a4Filipe Cabecinhas /// useful when looking for standard library functions we should constant fold 314b66329ac82b5f3d939bd31b4d1498da9257d85aJohnny Chen /// or handle in alias analyses. 324b66329ac82b5f3d939bd31b4d1498da9257d85aJohnny Chen 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 70char ExternalFunctionsPassedConstants::ID = 0; 71static RegisterPass<ExternalFunctionsPassedConstants> 72 P1("print-externalfnconstants", 73 "Print external fn callsites passed constants"); 74 75namespace { 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 91char CallGraphPrinter::ID = 0; 92static RegisterPass<CallGraphPrinter> 93 P2("print-callgraph", "Print a call graph"); 94