1*0b57cec5SDimitry Andric //===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file defines pass wrappers around LLVM analyses that don't make sense to 10*0b57cec5SDimitry Andric // be passes. It provides a nice standard pass interface to these classes so 11*0b57cec5SDimitry Andric // that they can be printed out by analyze. 12*0b57cec5SDimitry Andric // 13*0b57cec5SDimitry Andric // These classes are separated out of analyze.cpp so that it is more clear which 14*0b57cec5SDimitry Andric // code is the integral part of the analyze tool, and which part of the code is 15*0b57cec5SDimitry Andric // just making it so more passes are available. 16*0b57cec5SDimitry Andric // 17*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andric #include "llvm/Analysis/CallGraph.h" 20*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 21*0b57cec5SDimitry Andric #include "llvm/Pass.h" 22*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 23*0b57cec5SDimitry Andric using namespace llvm; 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric namespace { 26*0b57cec5SDimitry Andric /// ExternalFunctionsPassedConstants - This pass prints out call sites to 27*0b57cec5SDimitry Andric /// external functions that are called with constant arguments. This can be 28*0b57cec5SDimitry Andric /// useful when looking for standard library functions we should constant fold 29*0b57cec5SDimitry Andric /// or handle in alias analyses. 30*0b57cec5SDimitry Andric struct ExternalFunctionsPassedConstants : public ModulePass { 31*0b57cec5SDimitry Andric static char ID; // Pass ID, replacement for typeid ExternalFunctionsPassedConstants__anonfff0d5980111::ExternalFunctionsPassedConstants32*0b57cec5SDimitry Andric ExternalFunctionsPassedConstants() : ModulePass(ID) {} runOnModule__anonfff0d5980111::ExternalFunctionsPassedConstants33*0b57cec5SDimitry Andric bool runOnModule(Module &M) override { 34*0b57cec5SDimitry Andric for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 35*0b57cec5SDimitry Andric if (!I->isDeclaration()) continue; 36*0b57cec5SDimitry Andric 37*0b57cec5SDimitry Andric bool PrintedFn = false; 38*0b57cec5SDimitry Andric for (User *U : I->users()) { 39*0b57cec5SDimitry Andric Instruction *UI = dyn_cast<Instruction>(U); 40*0b57cec5SDimitry Andric if (!UI) continue; 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric CallBase *CB = dyn_cast<CallBase>(UI); 43*0b57cec5SDimitry Andric if (!CB) 44*0b57cec5SDimitry Andric continue; 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric for (auto AI = CB->arg_begin(), E = CB->arg_end(); AI != E; ++AI) { 47*0b57cec5SDimitry Andric if (!isa<Constant>(*AI)) continue; 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric if (!PrintedFn) { 50*0b57cec5SDimitry Andric errs() << "Function '" << I->getName() << "':\n"; 51*0b57cec5SDimitry Andric PrintedFn = true; 52*0b57cec5SDimitry Andric } 53*0b57cec5SDimitry Andric errs() << *UI; 54*0b57cec5SDimitry Andric break; 55*0b57cec5SDimitry Andric } 56*0b57cec5SDimitry Andric } 57*0b57cec5SDimitry Andric } 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric return false; 60*0b57cec5SDimitry Andric } 61*0b57cec5SDimitry Andric getAnalysisUsage__anonfff0d5980111::ExternalFunctionsPassedConstants62*0b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 63*0b57cec5SDimitry Andric AU.setPreservesAll(); 64*0b57cec5SDimitry Andric } 65*0b57cec5SDimitry Andric }; 66*0b57cec5SDimitry Andric } 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric char ExternalFunctionsPassedConstants::ID = 0; 69*0b57cec5SDimitry Andric static RegisterPass<ExternalFunctionsPassedConstants> 70*0b57cec5SDimitry Andric P1("print-externalfnconstants", 71*0b57cec5SDimitry Andric "Print external fn callsites passed constants"); 72*0b57cec5SDimitry Andric