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