1f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===// 2f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// 3f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// The LLVM Compiler Infrastructure 4f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// 55f5a573621dd45c94c96deebea973c31784ddaeaChris Lattner// This file is distributed under the University of Illinois Open Source 65f5a573621dd45c94c96deebea973c31784ddaeaChris Lattner// License. See LICENSE.TXT for details. 7f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// 8f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//===----------------------------------------------------------------------===// 9f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// 10f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// This file defines pass wrappers around LLVM analyses that don't make sense to 11f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// be passes. It provides a nice standard pass interface to these classes so 12f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// that they can be printed out by analyze. 13f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// 14f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// These classes are separated out of analyze.cpp so that it is more clear which 15f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// code is the integral part of the analyze tool, and which part of the code is 16f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// just making it so more passes are available. 17f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// 18f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//===----------------------------------------------------------------------===// 19f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman 20f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include "llvm/Module.h" 21f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include "llvm/Pass.h" 22f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include "llvm/Support/CallSite.h" 23f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include "llvm/Analysis/CallGraph.h" 24f8b81bfe608d09be3cbe7d58718052cd6fa4355cDan Gohman#include "llvm/Support/raw_ostream.h" 25f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohmanusing namespace llvm; 26f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman 27f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohmannamespace { 28f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman /// ExternalFunctionsPassedConstants - This pass prints out call sites to 29f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman /// external functions that are called with constant arguments. This can be 30f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman /// useful when looking for standard library functions we should constant fold 31f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman /// or handle in alias analyses. 32f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman struct ExternalFunctionsPassedConstants : public ModulePass { 33f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman static char ID; // Pass ID, replacement for typeid 347569322765651f19eea0609fb082e6b267d5d2b5Owen Anderson ExternalFunctionsPassedConstants() : ModulePass(ID) {} 35f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman virtual bool runOnModule(Module &M) { 36397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 37397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner if (!I->isDeclaration()) continue; 38397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner 39397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner bool PrintedFn = false; 40397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); 41397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner UI != E; ++UI) { 42397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner Instruction *User = dyn_cast<Instruction>(*UI); 43397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner if (!User) continue; 44397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner 4536129ca8be5481a03bbf164b04bd026f114db81aGabor Greif CallSite CS(cast<Value>(User)); 4636129ca8be5481a03bbf164b04bd026f114db81aGabor Greif if (!CS) continue; 47397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner 48397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner for (CallSite::arg_iterator AI = CS.arg_begin(), 49397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner E = CS.arg_end(); AI != E; ++AI) { 50397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner if (!isa<Constant>(*AI)) continue; 51397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner 52397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner if (!PrintedFn) { 53397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner errs() << "Function '" << I->getName() << "':\n"; 54397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner PrintedFn = true; 55f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman } 56397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner errs() << *User; 57397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner break; 58397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner } 59f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman } 60397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner } 61f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman 62f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman return false; 63f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman } 64f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman 65f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman virtual void getAnalysisUsage(AnalysisUsage &AU) const { 66f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman AU.setPreservesAll(); 67f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman } 68f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman }; 69f25a46d41ef2e7b33889d9999a738af6b8db6085Dan Gohman} 70f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman 71f25a46d41ef2e7b33889d9999a738af6b8db6085Dan Gohmanchar ExternalFunctionsPassedConstants::ID = 0; 72f25a46d41ef2e7b33889d9999a738af6b8db6085Dan Gohmanstatic RegisterPass<ExternalFunctionsPassedConstants> 73d10d6f7af734b8491b2f93227eb17e3b2fad0692Duncan Sands P1("print-externalfnconstants", 74d10d6f7af734b8491b2f93227eb17e3b2fad0692Duncan Sands "Print external fn callsites passed constants"); 75f7dbeb3bdf1945aa9eaba9dcc1b6859c77265143Duncan Sands 76f25a46d41ef2e7b33889d9999a738af6b8db6085Dan Gohmannamespace { 77f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman struct CallGraphPrinter : public ModulePass { 78f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman static char ID; // Pass ID, replacement for typeid 797569322765651f19eea0609fb082e6b267d5d2b5Owen Anderson CallGraphPrinter() : ModulePass(ID) {} 80f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman 81f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman virtual void getAnalysisUsage(AnalysisUsage &AU) const { 82f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman AU.setPreservesAll(); 83f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman AU.addRequiredTransitive<CallGraph>(); 84f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman } 85f7dbeb3bdf1945aa9eaba9dcc1b6859c77265143Duncan Sands virtual bool runOnModule(Module &M) { 86397f4560780d34da0bd1e4c9b9101c6f0774e8ffChris Lattner getAnalysis<CallGraph>().print(errs(), &M); 87f7dbeb3bdf1945aa9eaba9dcc1b6859c77265143Duncan Sands return false; 88f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman } 89f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman }; 90f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman} 91f25a46d41ef2e7b33889d9999a738af6b8db6085Dan Gohman 92f25a46d41ef2e7b33889d9999a738af6b8db6085Dan Gohmanchar CallGraphPrinter::ID = 0; 93f25a46d41ef2e7b33889d9999a738af6b8db6085Dan Gohmanstatic RegisterPass<CallGraphPrinter> 94f25a46d41ef2e7b33889d9999a738af6b8db6085Dan Gohman P2("print-callgraph", "Print a call graph"); 95