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