1193323Sed//===- AliasAnalysisCounter.cpp - Alias Analysis Query Counter ------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file implements a pass which can be used to count how many alias queries 11193323Sed// are being made and how the alias analysis implementation being used responds. 12193323Sed// 13193323Sed//===----------------------------------------------------------------------===// 14193323Sed 15193323Sed#include "llvm/Analysis/Passes.h" 16193323Sed#include "llvm/Analysis/AliasAnalysis.h" 17193323Sed#include "llvm/Assembly/Writer.h" 18249423Sdim#include "llvm/Pass.h" 19193323Sed#include "llvm/Support/CommandLine.h" 20201360Srdivacky#include "llvm/Support/Debug.h" 21198090Srdivacky#include "llvm/Support/ErrorHandling.h" 22198090Srdivacky#include "llvm/Support/raw_ostream.h" 23193323Sedusing namespace llvm; 24193323Sed 25193323Sedstatic cl::opt<bool> 26198090SrdivackyPrintAll("count-aa-print-all-queries", cl::ReallyHidden, cl::init(true)); 27193323Sedstatic cl::opt<bool> 28193323SedPrintAllFailures("count-aa-print-all-failed-queries", cl::ReallyHidden); 29193323Sed 30193323Sednamespace { 31198892Srdivacky class AliasAnalysisCounter : public ModulePass, public AliasAnalysis { 32218893Sdim unsigned No, May, Partial, Must; 33193323Sed unsigned NoMR, JustRef, JustMod, MR; 34193323Sed Module *M; 35193323Sed public: 36193323Sed static char ID; // Class identification, replacement for typeinfo 37212904Sdim AliasAnalysisCounter() : ModulePass(ID) { 38218893Sdim initializeAliasAnalysisCounterPass(*PassRegistry::getPassRegistry()); 39218893Sdim No = May = Partial = Must = 0; 40193323Sed NoMR = JustRef = JustMod = MR = 0; 41193323Sed } 42193323Sed 43193323Sed void printLine(const char *Desc, unsigned Val, unsigned Sum) { 44198090Srdivacky errs() << " " << Val << " " << Desc << " responses (" 45198090Srdivacky << Val*100/Sum << "%)\n"; 46193323Sed } 47193323Sed ~AliasAnalysisCounter() { 48218893Sdim unsigned AASum = No+May+Partial+Must; 49193323Sed unsigned MRSum = NoMR+JustRef+JustMod+MR; 50193323Sed if (AASum + MRSum) { // Print a report if any counted queries occurred... 51198090Srdivacky errs() << "\n===== Alias Analysis Counter Report =====\n" 52202878Srdivacky << " Analysis counted:\n" 53198090Srdivacky << " " << AASum << " Total Alias Queries Performed\n"; 54193323Sed if (AASum) { 55193323Sed printLine("no alias", No, AASum); 56193323Sed printLine("may alias", May, AASum); 57218893Sdim printLine("partial alias", Partial, AASum); 58193323Sed printLine("must alias", Must, AASum); 59198090Srdivacky errs() << " Alias Analysis Counter Summary: " << No*100/AASum << "%/" 60218893Sdim << May*100/AASum << "%/" 61218893Sdim << Partial*100/AASum << "%/" 62218893Sdim << Must*100/AASum<<"%\n\n"; 63193323Sed } 64193323Sed 65198090Srdivacky errs() << " " << MRSum << " Total Mod/Ref Queries Performed\n"; 66193323Sed if (MRSum) { 67193323Sed printLine("no mod/ref", NoMR, MRSum); 68193323Sed printLine("ref", JustRef, MRSum); 69193323Sed printLine("mod", JustMod, MRSum); 70193323Sed printLine("mod/ref", MR, MRSum); 71198090Srdivacky errs() << " Mod/Ref Analysis Counter Summary: " <<NoMR*100/MRSum 72198090Srdivacky << "%/" << JustRef*100/MRSum << "%/" << JustMod*100/MRSum 73198090Srdivacky << "%/" << MR*100/MRSum <<"%\n\n"; 74193323Sed } 75193323Sed } 76193323Sed } 77193323Sed 78193323Sed bool runOnModule(Module &M) { 79193323Sed this->M = &M; 80193323Sed InitializeAliasAnalysis(this); 81193323Sed return false; 82193323Sed } 83193323Sed 84193323Sed virtual void getAnalysisUsage(AnalysisUsage &AU) const { 85193323Sed AliasAnalysis::getAnalysisUsage(AU); 86193323Sed AU.addRequired<AliasAnalysis>(); 87193323Sed AU.setPreservesAll(); 88193323Sed } 89193323Sed 90202878Srdivacky /// getAdjustedAnalysisPointer - This method is used when a pass implements 91202878Srdivacky /// an analysis interface through multiple inheritance. If needed, it 92202878Srdivacky /// should override this to adjust the this pointer as needed for the 93202878Srdivacky /// specified pass info. 94212904Sdim virtual void *getAdjustedAnalysisPointer(AnalysisID PI) { 95212904Sdim if (PI == &AliasAnalysis::ID) 96202878Srdivacky return (AliasAnalysis*)this; 97202878Srdivacky return this; 98202878Srdivacky } 99202878Srdivacky 100193323Sed // FIXME: We could count these too... 101218893Sdim bool pointsToConstantMemory(const Location &Loc, bool OrLocal) { 102218893Sdim return getAnalysis<AliasAnalysis>().pointsToConstantMemory(Loc, OrLocal); 103193323Sed } 104193323Sed 105193323Sed // Forwarding functions: just delegate to a real AA implementation, counting 106193323Sed // the number of responses... 107218893Sdim AliasResult alias(const Location &LocA, const Location &LocB); 108193323Sed 109212904Sdim ModRefResult getModRefInfo(ImmutableCallSite CS, 110218893Sdim const Location &Loc); 111212904Sdim ModRefResult getModRefInfo(ImmutableCallSite CS1, 112212904Sdim ImmutableCallSite CS2) { 113193323Sed return AliasAnalysis::getModRefInfo(CS1,CS2); 114193323Sed } 115193323Sed }; 116193323Sed} 117193323Sed 118193323Sedchar AliasAnalysisCounter::ID = 0; 119212904SdimINITIALIZE_AG_PASS(AliasAnalysisCounter, AliasAnalysis, "count-aa", 120218893Sdim "Count Alias Analysis Query Responses", false, true, false) 121193323Sed 122193323SedModulePass *llvm::createAliasAnalysisCounterPass() { 123193323Sed return new AliasAnalysisCounter(); 124193323Sed} 125193323Sed 126193323SedAliasAnalysis::AliasResult 127218893SdimAliasAnalysisCounter::alias(const Location &LocA, const Location &LocB) { 128218893Sdim AliasResult R = getAnalysis<AliasAnalysis>().alias(LocA, LocB); 129193323Sed 130234353Sdim const char *AliasString = 0; 131193323Sed switch (R) { 132193323Sed case NoAlias: No++; AliasString = "No alias"; break; 133193323Sed case MayAlias: May++; AliasString = "May alias"; break; 134218893Sdim case PartialAlias: Partial++; AliasString = "Partial alias"; break; 135193323Sed case MustAlias: Must++; AliasString = "Must alias"; break; 136193323Sed } 137193323Sed 138193323Sed if (PrintAll || (PrintAllFailures && R == MayAlias)) { 139198090Srdivacky errs() << AliasString << ":\t"; 140218893Sdim errs() << "[" << LocA.Size << "B] "; 141218893Sdim WriteAsOperand(errs(), LocA.Ptr, true, M); 142198090Srdivacky errs() << ", "; 143218893Sdim errs() << "[" << LocB.Size << "B] "; 144218893Sdim WriteAsOperand(errs(), LocB.Ptr, true, M); 145198090Srdivacky errs() << "\n"; 146193323Sed } 147193323Sed 148193323Sed return R; 149193323Sed} 150193323Sed 151193323SedAliasAnalysis::ModRefResult 152212904SdimAliasAnalysisCounter::getModRefInfo(ImmutableCallSite CS, 153218893Sdim const Location &Loc) { 154218893Sdim ModRefResult R = getAnalysis<AliasAnalysis>().getModRefInfo(CS, Loc); 155193323Sed 156234353Sdim const char *MRString = 0; 157193323Sed switch (R) { 158193323Sed case NoModRef: NoMR++; MRString = "NoModRef"; break; 159193323Sed case Ref: JustRef++; MRString = "JustRef"; break; 160193323Sed case Mod: JustMod++; MRString = "JustMod"; break; 161193323Sed case ModRef: MR++; MRString = "ModRef"; break; 162193323Sed } 163193323Sed 164193323Sed if (PrintAll || (PrintAllFailures && R == ModRef)) { 165198090Srdivacky errs() << MRString << ": Ptr: "; 166218893Sdim errs() << "[" << Loc.Size << "B] "; 167218893Sdim WriteAsOperand(errs(), Loc.Ptr, true, M); 168204642Srdivacky errs() << "\t<->" << *CS.getInstruction() << '\n'; 169193323Sed } 170193323Sed return R; 171193323Sed} 172