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
20f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Analysis/CallGraph.h"
210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
2204eaef28a8bc1e530a55c18dab0785f7d1dff640Chris Lattner#include "llvm/Pass.h"
23d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner#include "llvm/Support/CallSite.h"
2465f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman#include "llvm/Support/raw_ostream.h"
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
3490c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Anderson    ExternalFunctionsPassedConstants() : ModulePass(ID) {}
35b12914bfc0f76a7a48357162d5f4c39a1343e69bChris Lattner    virtual bool runOnModule(Module &M) {
3645cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner      for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
3745cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner        if (!I->isDeclaration()) continue;
3845cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner
3945cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner        bool PrintedFn = false;
4045cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner        for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
4145cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner             UI != E; ++UI) {
4245cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner          Instruction *User = dyn_cast<Instruction>(*UI);
4345cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner          if (!User) continue;
4445cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner
457d3056b16038a6a09c452c0dfcc3c8f4e421506aGabor Greif          CallSite CS(cast<Value>(User));
467d3056b16038a6a09c452c0dfcc3c8f4e421506aGabor Greif          if (!CS) continue;
4745cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner
4845cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner          for (CallSite::arg_iterator AI = CS.arg_begin(),
4945cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner               E = CS.arg_end(); AI != E; ++AI) {
5045cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner            if (!isa<Constant>(*AI)) continue;
5145cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner
5245cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner            if (!PrintedFn) {
5345cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner              errs() << "Function '" << I->getName() << "':\n";
5445cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner              PrintedFn = true;
55d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner            }
5645cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner            errs() << *User;
5745cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner            break;
5845cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner          }
59d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner        }
6045cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner      }
61d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner
62d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner      return false;
63d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner    }
64d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner
65d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
66d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner      AU.setPreservesAll();
67d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner    }
68d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner  };
69a2a3bbc668cdebcc87e18e93b4576d59dfab625cDan Gohman}
70d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner
71a2a3bbc668cdebcc87e18e93b4576d59dfab625cDan Gohmanchar ExternalFunctionsPassedConstants::ID = 0;
72a2a3bbc668cdebcc87e18e93b4576d59dfab625cDan Gohmanstatic RegisterPass<ExternalFunctionsPassedConstants>
733ee8fc964952a65bcb3668b85938c46f90631e42Duncan Sands  P1("print-externalfnconstants",
743ee8fc964952a65bcb3668b85938c46f90631e42Duncan Sands     "Print external fn callsites passed constants");
75e65d39a42ccb63c8b883db0c466cc43f42d83fffDuncan Sands
76a2a3bbc668cdebcc87e18e93b4576d59dfab625cDan Gohmannamespace {
77171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner  struct CallGraphPrinter : public ModulePass {
781997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel    static char ID; // Pass ID, replacement for typeid
7990c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Anderson    CallGraphPrinter() : ModulePass(ID) {}
80794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel
81171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
82171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner      AU.setPreservesAll();
838257bee70bc45179d401e970faf67405b6cf46a2Chris Lattner      AU.addRequiredTransitive<CallGraph>();
84171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner    }
85e65d39a42ccb63c8b883db0c466cc43f42d83fffDuncan Sands    virtual bool runOnModule(Module &M) {
8645cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner      getAnalysis<CallGraph>().print(errs(), &M);
87e65d39a42ccb63c8b883db0c466cc43f42d83fffDuncan Sands      return false;
88171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner    }
89171eee54717a22f439b06a4e07b361fcd983af1fChris Lattner  };
90d9572118ebd6ebf0b3ee55d5e3487b2a0b5b74f8Chris Lattner}
91a2a3bbc668cdebcc87e18e93b4576d59dfab625cDan Gohman
92a2a3bbc668cdebcc87e18e93b4576d59dfab625cDan Gohmanchar CallGraphPrinter::ID = 0;
93a2a3bbc668cdebcc87e18e93b4576d59dfab625cDan Gohmanstatic RegisterPass<CallGraphPrinter>
94a2a3bbc668cdebcc87e18e93b4576d59dfab625cDan Gohman  P2("print-callgraph", "Print a call graph");
95