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