1193323Sed//===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file defines pass wrappers around LLVM analyses that don't make sense to
11193323Sed// be passes.  It provides a nice standard pass interface to these classes so
12193323Sed// that they can be printed out by analyze.
13193323Sed//
14193323Sed// These classes are separated out of analyze.cpp so that it is more clear which
15193323Sed// code is the integral part of the analyze tool, and which part of the code is
16193323Sed// just making it so more passes are available.
17193323Sed//
18193323Sed//===----------------------------------------------------------------------===//
19193323Sed
20249423Sdim#include "llvm/Analysis/CallGraph.h"
21276479Sdim#include "llvm/IR/CallSite.h"
22249423Sdim#include "llvm/IR/Module.h"
23193323Sed#include "llvm/Pass.h"
24198090Srdivacky#include "llvm/Support/raw_ostream.h"
25193323Sedusing namespace llvm;
26193323Sed
27193323Sednamespace {
28193323Sed  /// ExternalFunctionsPassedConstants - This pass prints out call sites to
29193323Sed  /// external functions that are called with constant arguments.  This can be
30193323Sed  /// useful when looking for standard library functions we should constant fold
31193323Sed  /// or handle in alias analyses.
32193323Sed  struct ExternalFunctionsPassedConstants : public ModulePass {
33193323Sed    static char ID; // Pass ID, replacement for typeid
34212793Sdim    ExternalFunctionsPassedConstants() : ModulePass(ID) {}
35276479Sdim    bool runOnModule(Module &M) override {
36198090Srdivacky      for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
37198090Srdivacky        if (!I->isDeclaration()) continue;
38276479Sdim
39198090Srdivacky        bool PrintedFn = false;
40276479Sdim        for (User *U : I->users()) {
41276479Sdim          Instruction *UI = dyn_cast<Instruction>(U);
42276479Sdim          if (!UI) continue;
43276479Sdim
44276479Sdim          CallSite CS(cast<Value>(UI));
45212793Sdim          if (!CS) continue;
46276479Sdim
47198090Srdivacky          for (CallSite::arg_iterator AI = CS.arg_begin(),
48198090Srdivacky               E = CS.arg_end(); AI != E; ++AI) {
49198090Srdivacky            if (!isa<Constant>(*AI)) continue;
50198090Srdivacky
51198090Srdivacky            if (!PrintedFn) {
52198090Srdivacky              errs() << "Function '" << I->getName() << "':\n";
53198090Srdivacky              PrintedFn = true;
54193323Sed            }
55276479Sdim            errs() << *UI;
56198090Srdivacky            break;
57198090Srdivacky          }
58193323Sed        }
59198090Srdivacky      }
60193323Sed
61193323Sed      return false;
62193323Sed    }
63193323Sed
64276479Sdim    void getAnalysisUsage(AnalysisUsage &AU) const override {
65193323Sed      AU.setPreservesAll();
66193323Sed    }
67193323Sed  };
68212793Sdim}
69193323Sed
70212793Sdimchar ExternalFunctionsPassedConstants::ID = 0;
71212793Sdimstatic RegisterPass<ExternalFunctionsPassedConstants>
72193323Sed  P1("print-externalfnconstants",
73193323Sed     "Print external fn callsites passed constants");
74193323Sed
75212793Sdimnamespace {
76193323Sed  struct CallGraphPrinter : public ModulePass {
77193323Sed    static char ID; // Pass ID, replacement for typeid
78212793Sdim    CallGraphPrinter() : ModulePass(ID) {}
79193323Sed
80276479Sdim    void getAnalysisUsage(AnalysisUsage &AU) const override {
81193323Sed      AU.setPreservesAll();
82276479Sdim      AU.addRequiredTransitive<CallGraphWrapperPass>();
83193323Sed    }
84276479Sdim    bool runOnModule(Module &M) override {
85276479Sdim      getAnalysis<CallGraphWrapperPass>().print(errs(), &M);
86193323Sed      return false;
87193323Sed    }
88193323Sed  };
89212793Sdim}
90193323Sed
91212793Sdimchar CallGraphPrinter::ID = 0;
92212793Sdimstatic RegisterPass<CallGraphPrinter>
93212793Sdim  P2("print-callgraph", "Print a call graph");
94