AnalysisWrappers.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. //===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines pass wrappers around LLVM analyses that don't make sense to
  11. // be passes. It provides a nice standard pass interface to these classes so
  12. // that they can be printed out by analyze.
  13. //
  14. // These classes are separated out of analyze.cpp so that it is more clear which
  15. // code is the integral part of the analyze tool, and which part of the code is
  16. // just making it so more passes are available.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #include "llvm/Analysis/CallGraph.h"
  20. #include "llvm/IR/CallSite.h"
  21. #include "llvm/IR/Module.h"
  22. #include "llvm/Pass.h"
  23. #include "llvm/Support/raw_ostream.h"
  24. using namespace llvm;
  25. namespace {
  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. bool PrintedFn = false;
  37. for (User *U : I->users()) {
  38. Instruction *UI = dyn_cast<Instruction>(U);
  39. if (!UI) continue;
  40. CallSite CS(cast<Value>(UI));
  41. if (!CS) continue;
  42. for (CallSite::arg_iterator AI = CS.arg_begin(),
  43. E = CS.arg_end(); AI != E; ++AI) {
  44. if (!isa<Constant>(*AI)) continue;
  45. if (!PrintedFn) {
  46. errs() << "Function '" << I->getName() << "':\n";
  47. PrintedFn = true;
  48. }
  49. errs() << *UI;
  50. break;
  51. }
  52. }
  53. }
  54. return false;
  55. }
  56. void getAnalysisUsage(AnalysisUsage &AU) const override {
  57. AU.setPreservesAll();
  58. }
  59. };
  60. }
  61. char ExternalFunctionsPassedConstants::ID = 0;
  62. static RegisterPass<ExternalFunctionsPassedConstants>
  63. P1("print-externalfnconstants",
  64. "Print external fn callsites passed constants");
  65. namespace {
  66. struct CallGraphPrinter : public ModulePass {
  67. static char ID; // Pass ID, replacement for typeid
  68. CallGraphPrinter() : ModulePass(ID) {}
  69. void getAnalysisUsage(AnalysisUsage &AU) const override {
  70. AU.setPreservesAll();
  71. AU.addRequiredTransitive<CallGraphWrapperPass>();
  72. }
  73. bool runOnModule(Module &M) override {
  74. getAnalysis<CallGraphWrapperPass>().print(errs(), &M);
  75. return false;
  76. }
  77. };
  78. }
  79. char CallGraphPrinter::ID = 0;
  80. static RegisterPass<CallGraphPrinter>
  81. P2("print-callgraph", "Print a call graph");