AnalysisWrappers.cpp revision 21c62da287237d39d0d95004881ea4baae3be6da
1781e6f5f894175a48e21c7b9d443616a7428f1f7Chris Lattner//===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===//
23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//                     The LLVM Compiler Infrastructure
47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//
521c62da287237d39d0d95004881ea4baae3be6daChris Lattner// This file is distributed under the University of Illinois Open Source
621c62da287237d39d0d95004881ea4baae3be6daChris Lattner// License. See LICENSE.TXT for details.
73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===//
9781e6f5f894175a48e21c7b9d443616a7428f1f7Chris Lattner//
10781e6f5f894175a48e21c7b9d443616a7428f1f7Chris Lattner// This file defines pass wrappers around LLVM analyses that don't make sense to
11781e6f5f894175a48e21c7b9d443616a7428f1f7Chris Lattner// be passes.  It provides a nice standard pass interface to these classes so
12781e6f5f894175a48e21c7b9d443616a7428f1f7Chris Lattner// that they can be printed out by analyze.
13781e6f5f894175a48e21c7b9d443616a7428f1f7Chris Lattner//
14bc0e998c497446f5448425b3cbd7f8f19a458764Misha Brukman// These classes are separated out of analyze.cpp so that it is more clear which
15781e6f5f894175a48e21c7b9d443616a7428f1f7Chris Lattner// code is the integral part of the analyze tool, and which part of the code is
16781e6f5f894175a48e21c7b9d443616a7428f1f7Chris Lattner// just making it so more passes are available.
17781e6f5f894175a48e21c7b9d443616a7428f1f7Chris Lattner//
18781e6f5f894175a48e21c7b9d443616a7428f1f7Chris Lattner//===----------------------------------------------------------------------===//
19781e6f5f894175a48e21c7b9d443616a7428f1f7Chris Lattner
20d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner#include "llvm/Module.h"
2104eaef28a8bc1e530a55c18dab0785f7d1dff640Chris Lattner#include "llvm/Pass.h"
22d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner#include "llvm/Support/CallSite.h"
23171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner#include "llvm/Analysis/CallGraph.h"
2486f42bdad93677fa0ca33b27afb0f493028376cbReid Spencer#include <iostream>
25d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm;
26d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
27781e6f5f894175a48e21c7b9d443616a7428f1f7Chris Lattnernamespace {
28d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner  /// ExternalFunctionsPassedConstants - This pass prints out call sites to
29d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner  /// external functions that are called with constant arguments.  This can be
30d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner  /// useful when looking for standard library functions we should constant fold
31d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner  /// or handle in alias analyses.
32b12914bfc0f76a7a48357162d5f4c39a1343e69bChris Lattner  struct ExternalFunctionsPassedConstants : public ModulePass {
331997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel    static char ID; // Pass ID, replacement for typeid
34794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel    ExternalFunctionsPassedConstants() : ModulePass((intptr_t)&ID) {}
35b12914bfc0f76a7a48357162d5f4c39a1343e69bChris Lattner    virtual bool runOnModule(Module &M) {
36d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner      for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
375cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer        if (I->isDeclaration()) {
38d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner          bool PrintedFn = false;
39d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner          for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
40d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner               UI != E; ++UI)
41d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner            if (Instruction *User = dyn_cast<Instruction>(*UI)) {
42d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner              CallSite CS = CallSite::get(User);
43d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner              if (CS.getInstruction()) {
44d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner                for (CallSite::arg_iterator AI = CS.arg_begin(),
45d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner                       E = CS.arg_end(); AI != E; ++AI)
46593eb952281138e1877adbfb11b88b6e32fdd732Reid Spencer                  if (isa<Constant>(*AI)) {
47d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner                    if (!PrintedFn) {
48d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner                      std::cerr << "Function '" << I->getName() << "':\n";
49d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner                      PrintedFn = true;
50d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner                    }
51d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner                    std::cerr << *User;
52d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner                    break;
53d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner                  }
54d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner              }
55d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner            }
56d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner        }
57d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner
58d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner      return false;
59d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner    }
60d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner
61d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
62d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner      AU.setPreservesAll();
63d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner    }
64d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner  };
65d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner
661997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel  char ExternalFunctionsPassedConstants::ID = 0;
675d8925c7c506a54ebdfb0bc93437ec9f602eaaa0Chris Lattner  RegisterPass<ExternalFunctionsPassedConstants>
68171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner  P1("externalfnconstants", "Print external fn callsites passed constants");
69171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner
70171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner  struct CallGraphPrinter : public ModulePass {
711997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel    static char ID; // Pass ID, replacement for typeid
72794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel    CallGraphPrinter() : ModulePass((intptr_t)&ID) {}
73794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel
74171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
75171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner      AU.setPreservesAll();
768257bee70bc45179d401e970faf67405b6cf46a2Chris Lattner      AU.addRequiredTransitive<CallGraph>();
77171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner    }
78171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner    virtual bool runOnModule(Module &M) { return false; }
79171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner
800cafa92371ce020ce19e9aacf1a96f8c8a7bb47aAndrew Lenharth    virtual void print(std::ostream &OS, const Module *M) const {
81171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner      getAnalysis<CallGraph>().print(OS, M);
82171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner    }
83171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner  };
84171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner
851997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel  char CallGraphPrinter::ID = 0;
865d8925c7c506a54ebdfb0bc93437ec9f602eaaa0Chris Lattner  RegisterPass<CallGraphPrinter>
87171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner    P2("callgraph", "Print a call graph");
88d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner}
89