AliasAnalysisCounter.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. //===- AliasAnalysisCounter.cpp - Alias Analysis Query Counter ------------===//
  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 implements a pass which can be used to count how many alias queries
  11. // are being made and how the alias analysis implementation being used responds.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/Analysis/Passes.h"
  15. #include "llvm/Pass.h"
  16. #include "llvm/Analysis/AliasAnalysis.h"
  17. #include "llvm/Assembly/Writer.h"
  18. #include "llvm/Support/CommandLine.h"
  19. #include "llvm/Support/Compiler.h"
  20. #include "llvm/Support/Streams.h"
  21. using namespace llvm;
  22. static cl::opt<bool>
  23. PrintAll("count-aa-print-all-queries", cl::ReallyHidden);
  24. static cl::opt<bool>
  25. PrintAllFailures("count-aa-print-all-failed-queries", cl::ReallyHidden);
  26. namespace {
  27. class VISIBILITY_HIDDEN AliasAnalysisCounter
  28. : public ModulePass, public AliasAnalysis {
  29. unsigned No, May, Must;
  30. unsigned NoMR, JustRef, JustMod, MR;
  31. const char *Name;
  32. Module *M;
  33. public:
  34. static char ID; // Class identification, replacement for typeinfo
  35. AliasAnalysisCounter() : ModulePass(&ID) {
  36. No = May = Must = 0;
  37. NoMR = JustRef = JustMod = MR = 0;
  38. }
  39. void printLine(const char *Desc, unsigned Val, unsigned Sum) {
  40. cerr << " " << Val << " " << Desc << " responses ("
  41. << Val*100/Sum << "%)\n";
  42. }
  43. ~AliasAnalysisCounter() {
  44. unsigned AASum = No+May+Must;
  45. unsigned MRSum = NoMR+JustRef+JustMod+MR;
  46. if (AASum + MRSum) { // Print a report if any counted queries occurred...
  47. cerr << "\n===== Alias Analysis Counter Report =====\n"
  48. << " Analysis counted: " << Name << "\n"
  49. << " " << AASum << " Total Alias Queries Performed\n";
  50. if (AASum) {
  51. printLine("no alias", No, AASum);
  52. printLine("may alias", May, AASum);
  53. printLine("must alias", Must, AASum);
  54. cerr << " Alias Analysis Counter Summary: " << No*100/AASum << "%/"
  55. << May*100/AASum << "%/" << Must*100/AASum<<"%\n\n";
  56. }
  57. cerr << " " << MRSum << " Total Mod/Ref Queries Performed\n";
  58. if (MRSum) {
  59. printLine("no mod/ref", NoMR, MRSum);
  60. printLine("ref", JustRef, MRSum);
  61. printLine("mod", JustMod, MRSum);
  62. printLine("mod/ref", MR, MRSum);
  63. cerr << " Mod/Ref Analysis Counter Summary: " <<NoMR*100/MRSum<< "%/"
  64. << JustRef*100/MRSum << "%/" << JustMod*100/MRSum << "%/"
  65. << MR*100/MRSum <<"%\n\n";
  66. }
  67. }
  68. }
  69. bool runOnModule(Module &M) {
  70. this->M = &M;
  71. InitializeAliasAnalysis(this);
  72. Name = dynamic_cast<Pass*>(&getAnalysis<AliasAnalysis>())->getPassName();
  73. return false;
  74. }
  75. virtual void getAnalysisUsage(AnalysisUsage &AU) const {
  76. AliasAnalysis::getAnalysisUsage(AU);
  77. AU.addRequired<AliasAnalysis>();
  78. AU.setPreservesAll();
  79. }
  80. // FIXME: We could count these too...
  81. bool pointsToConstantMemory(const Value *P) {
  82. return getAnalysis<AliasAnalysis>().pointsToConstantMemory(P);
  83. }
  84. bool doesNotAccessMemory(CallSite CS) {
  85. return getAnalysis<AliasAnalysis>().doesNotAccessMemory(CS);
  86. }
  87. bool doesNotAccessMemory(Function *F) {
  88. return getAnalysis<AliasAnalysis>().doesNotAccessMemory(F);
  89. }
  90. bool onlyReadsMemory(CallSite CS) {
  91. return getAnalysis<AliasAnalysis>().onlyReadsMemory(CS);
  92. }
  93. bool onlyReadsMemory(Function *F) {
  94. return getAnalysis<AliasAnalysis>().onlyReadsMemory(F);
  95. }
  96. // Forwarding functions: just delegate to a real AA implementation, counting
  97. // the number of responses...
  98. AliasResult alias(const Value *V1, unsigned V1Size,
  99. const Value *V2, unsigned V2Size);
  100. ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
  101. ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
  102. return AliasAnalysis::getModRefInfo(CS1,CS2);
  103. }
  104. };
  105. }
  106. char AliasAnalysisCounter::ID = 0;
  107. static RegisterPass<AliasAnalysisCounter>
  108. X("count-aa", "Count Alias Analysis Query Responses", false, true);
  109. static RegisterAnalysisGroup<AliasAnalysis> Y(X);
  110. ModulePass *llvm::createAliasAnalysisCounterPass() {
  111. return new AliasAnalysisCounter();
  112. }
  113. AliasAnalysis::AliasResult
  114. AliasAnalysisCounter::alias(const Value *V1, unsigned V1Size,
  115. const Value *V2, unsigned V2Size) {
  116. AliasResult R = getAnalysis<AliasAnalysis>().alias(V1, V1Size, V2, V2Size);
  117. const char *AliasString;
  118. switch (R) {
  119. default: assert(0 && "Unknown alias type!");
  120. case NoAlias: No++; AliasString = "No alias"; break;
  121. case MayAlias: May++; AliasString = "May alias"; break;
  122. case MustAlias: Must++; AliasString = "Must alias"; break;
  123. }
  124. if (PrintAll || (PrintAllFailures && R == MayAlias)) {
  125. cerr << AliasString << ":\t";
  126. cerr << "[" << V1Size << "B] ";
  127. WriteAsOperand(*cerr.stream(), V1, true, M);
  128. cerr << ", ";
  129. cerr << "[" << V2Size << "B] ";
  130. WriteAsOperand(*cerr.stream(), V2, true, M);
  131. cerr << "\n";
  132. }
  133. return R;
  134. }
  135. AliasAnalysis::ModRefResult
  136. AliasAnalysisCounter::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
  137. ModRefResult R = getAnalysis<AliasAnalysis>().getModRefInfo(CS, P, Size);
  138. const char *MRString;
  139. switch (R) {
  140. default: assert(0 && "Unknown mod/ref type!");
  141. case NoModRef: NoMR++; MRString = "NoModRef"; break;
  142. case Ref: JustRef++; MRString = "JustRef"; break;
  143. case Mod: JustMod++; MRString = "JustMod"; break;
  144. case ModRef: MR++; MRString = "ModRef"; break;
  145. }
  146. if (PrintAll || (PrintAllFailures && R == ModRef)) {
  147. cerr << MRString << ": Ptr: ";
  148. cerr << "[" << Size << "B] ";
  149. WriteAsOperand(*cerr.stream(), P, true, M);
  150. cerr << "\t<->" << *CS.getInstruction();
  151. }
  152. return R;
  153. }