10b57cec5SDimitry Andric //===- AliasAnalysisEvaluator.cpp - Alias Analysis Accuracy Evaluator -----===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysisEvaluator.h" 100b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h" 110b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h" 120b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 130b57cec5SDimitry Andric #include "llvm/IR/Function.h" 140b57cec5SDimitry Andric #include "llvm/IR/InstIterator.h" 150b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 160b57cec5SDimitry Andric #include "llvm/IR/Module.h" 17480093f4SDimitry Andric #include "llvm/InitializePasses.h" 180b57cec5SDimitry Andric #include "llvm/Pass.h" 190b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 200b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 210b57cec5SDimitry Andric using namespace llvm; 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric static cl::opt<bool> PrintAll("print-all-alias-modref-info", cl::ReallyHidden); 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric static cl::opt<bool> PrintNoAlias("print-no-aliases", cl::ReallyHidden); 260b57cec5SDimitry Andric static cl::opt<bool> PrintMayAlias("print-may-aliases", cl::ReallyHidden); 270b57cec5SDimitry Andric static cl::opt<bool> PrintPartialAlias("print-partial-aliases", cl::ReallyHidden); 280b57cec5SDimitry Andric static cl::opt<bool> PrintMustAlias("print-must-aliases", cl::ReallyHidden); 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric static cl::opt<bool> PrintNoModRef("print-no-modref", cl::ReallyHidden); 310b57cec5SDimitry Andric static cl::opt<bool> PrintRef("print-ref", cl::ReallyHidden); 320b57cec5SDimitry Andric static cl::opt<bool> PrintMod("print-mod", cl::ReallyHidden); 330b57cec5SDimitry Andric static cl::opt<bool> PrintModRef("print-modref", cl::ReallyHidden); 340b57cec5SDimitry Andric static cl::opt<bool> PrintMust("print-must", cl::ReallyHidden); 350b57cec5SDimitry Andric static cl::opt<bool> PrintMustRef("print-mustref", cl::ReallyHidden); 360b57cec5SDimitry Andric static cl::opt<bool> PrintMustMod("print-mustmod", cl::ReallyHidden); 370b57cec5SDimitry Andric static cl::opt<bool> PrintMustModRef("print-mustmodref", cl::ReallyHidden); 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric static cl::opt<bool> EvalAAMD("evaluate-aa-metadata", cl::ReallyHidden); 400b57cec5SDimitry Andric 41*81ad6265SDimitry Andric static void PrintResults(AliasResult AR, bool P, 42*81ad6265SDimitry Andric std::pair<const Value *, Type *> Loc1, 43*81ad6265SDimitry Andric std::pair<const Value *, Type *> Loc2, 44*81ad6265SDimitry Andric const Module *M) { 450b57cec5SDimitry Andric if (PrintAll || P) { 46*81ad6265SDimitry Andric Type *Ty1 = Loc1.second, *Ty2 = Loc2.second; 47*81ad6265SDimitry Andric unsigned AS1 = Loc1.first->getType()->getPointerAddressSpace(); 48*81ad6265SDimitry Andric unsigned AS2 = Loc2.first->getType()->getPointerAddressSpace(); 490b57cec5SDimitry Andric std::string o1, o2; 500b57cec5SDimitry Andric { 510b57cec5SDimitry Andric raw_string_ostream os1(o1), os2(o2); 52*81ad6265SDimitry Andric Loc1.first->printAsOperand(os1, false, M); 53*81ad6265SDimitry Andric Loc2.first->printAsOperand(os2, false, M); 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric 56fe6060f1SDimitry Andric if (o2 < o1) { 570b57cec5SDimitry Andric std::swap(o1, o2); 58*81ad6265SDimitry Andric std::swap(Ty1, Ty2); 59*81ad6265SDimitry Andric std::swap(AS1, AS2); 60fe6060f1SDimitry Andric // Change offset sign for the local AR, for printing only. 61fe6060f1SDimitry Andric AR.swap(); 62fe6060f1SDimitry Andric } 63*81ad6265SDimitry Andric errs() << " " << AR << ":\t"; 64*81ad6265SDimitry Andric Ty1->print(errs(), false, /* NoDetails */ true); 65*81ad6265SDimitry Andric if (AS1 != 0) 66*81ad6265SDimitry Andric errs() << " addrspace(" << AS1 << ")"; 67*81ad6265SDimitry Andric errs() << "* " << o1 << ", "; 68*81ad6265SDimitry Andric Ty2->print(errs(), false, /* NoDetails */ true); 69*81ad6265SDimitry Andric if (AS2 != 0) 70*81ad6265SDimitry Andric errs() << " addrspace(" << AS2 << ")"; 71*81ad6265SDimitry Andric errs() << "* " << o2 << "\n"; 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric } 740b57cec5SDimitry Andric 75*81ad6265SDimitry Andric static inline void PrintModRefResults( 76*81ad6265SDimitry Andric const char *Msg, bool P, Instruction *I, 77*81ad6265SDimitry Andric std::pair<const Value *, Type *> Loc, Module *M) { 780b57cec5SDimitry Andric if (PrintAll || P) { 790b57cec5SDimitry Andric errs() << " " << Msg << ": Ptr: "; 80*81ad6265SDimitry Andric Loc.second->print(errs(), false, /* NoDetails */ true); 81*81ad6265SDimitry Andric errs() << "* "; 82*81ad6265SDimitry Andric Loc.first->printAsOperand(errs(), false, M); 830b57cec5SDimitry Andric errs() << "\t<->" << *I << '\n'; 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric static inline void PrintModRefResults(const char *Msg, bool P, CallBase *CallA, 880b57cec5SDimitry Andric CallBase *CallB, Module *M) { 890b57cec5SDimitry Andric if (PrintAll || P) { 900b57cec5SDimitry Andric errs() << " " << Msg << ": " << *CallA << " <-> " << *CallB << '\n'; 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric static inline void PrintLoadStoreResults(AliasResult AR, bool P, 950b57cec5SDimitry Andric const Value *V1, const Value *V2, 960b57cec5SDimitry Andric const Module *M) { 970b57cec5SDimitry Andric if (PrintAll || P) { 980b57cec5SDimitry Andric errs() << " " << AR << ": " << *V1 << " <-> " << *V2 << '\n'; 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric PreservedAnalyses AAEvaluator::run(Function &F, FunctionAnalysisManager &AM) { 1030b57cec5SDimitry Andric runInternal(F, AM.getResult<AAManager>(F)); 1040b57cec5SDimitry Andric return PreservedAnalyses::all(); 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric void AAEvaluator::runInternal(Function &F, AAResults &AA) { 1080b57cec5SDimitry Andric const DataLayout &DL = F.getParent()->getDataLayout(); 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric ++FunctionCount; 1110b57cec5SDimitry Andric 112*81ad6265SDimitry Andric SetVector<std::pair<const Value *, Type *>> Pointers; 1130b57cec5SDimitry Andric SmallSetVector<CallBase *, 16> Calls; 1140b57cec5SDimitry Andric SetVector<Value *> Loads; 1150b57cec5SDimitry Andric SetVector<Value *> Stores; 1160b57cec5SDimitry Andric 117fe6060f1SDimitry Andric for (Instruction &Inst : instructions(F)) { 118*81ad6265SDimitry Andric if (auto *LI = dyn_cast<LoadInst>(&Inst)) { 119*81ad6265SDimitry Andric Pointers.insert({LI->getPointerOperand(), LI->getType()}); 120*81ad6265SDimitry Andric Loads.insert(LI); 121*81ad6265SDimitry Andric } else if (auto *SI = dyn_cast<StoreInst>(&Inst)) { 122*81ad6265SDimitry Andric Pointers.insert({SI->getPointerOperand(), 123*81ad6265SDimitry Andric SI->getValueOperand()->getType()}); 124*81ad6265SDimitry Andric Stores.insert(SI); 125*81ad6265SDimitry Andric } else if (auto *CB = dyn_cast<CallBase>(&Inst)) 126*81ad6265SDimitry Andric Calls.insert(CB); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric if (PrintAll || PrintNoAlias || PrintMayAlias || PrintPartialAlias || 1300b57cec5SDimitry Andric PrintMustAlias || PrintNoModRef || PrintMod || PrintRef || PrintModRef) 1310b57cec5SDimitry Andric errs() << "Function: " << F.getName() << ": " << Pointers.size() 1320b57cec5SDimitry Andric << " pointers, " << Calls.size() << " call sites\n"; 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric // iterate over the worklist, and run the full (n^2)/2 disambiguations 135*81ad6265SDimitry Andric for (auto I1 = Pointers.begin(), E = Pointers.end(); I1 != E; ++I1) { 136*81ad6265SDimitry Andric LocationSize Size1 = LocationSize::precise(DL.getTypeStoreSize(I1->second)); 137*81ad6265SDimitry Andric for (auto I2 = Pointers.begin(); I2 != I1; ++I2) { 138*81ad6265SDimitry Andric LocationSize Size2 = 139*81ad6265SDimitry Andric LocationSize::precise(DL.getTypeStoreSize(I2->second)); 140*81ad6265SDimitry Andric AliasResult AR = AA.alias(I1->first, Size1, I2->first, Size2); 1410b57cec5SDimitry Andric switch (AR) { 142fe6060f1SDimitry Andric case AliasResult::NoAlias: 1430b57cec5SDimitry Andric PrintResults(AR, PrintNoAlias, *I1, *I2, F.getParent()); 1440b57cec5SDimitry Andric ++NoAliasCount; 1450b57cec5SDimitry Andric break; 146fe6060f1SDimitry Andric case AliasResult::MayAlias: 1470b57cec5SDimitry Andric PrintResults(AR, PrintMayAlias, *I1, *I2, F.getParent()); 1480b57cec5SDimitry Andric ++MayAliasCount; 1490b57cec5SDimitry Andric break; 150fe6060f1SDimitry Andric case AliasResult::PartialAlias: 1510b57cec5SDimitry Andric PrintResults(AR, PrintPartialAlias, *I1, *I2, F.getParent()); 1520b57cec5SDimitry Andric ++PartialAliasCount; 1530b57cec5SDimitry Andric break; 154fe6060f1SDimitry Andric case AliasResult::MustAlias: 1550b57cec5SDimitry Andric PrintResults(AR, PrintMustAlias, *I1, *I2, F.getParent()); 1560b57cec5SDimitry Andric ++MustAliasCount; 1570b57cec5SDimitry Andric break; 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric } 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric if (EvalAAMD) { 1630b57cec5SDimitry Andric // iterate over all pairs of load, store 1640b57cec5SDimitry Andric for (Value *Load : Loads) { 1650b57cec5SDimitry Andric for (Value *Store : Stores) { 1660b57cec5SDimitry Andric AliasResult AR = AA.alias(MemoryLocation::get(cast<LoadInst>(Load)), 1670b57cec5SDimitry Andric MemoryLocation::get(cast<StoreInst>(Store))); 1680b57cec5SDimitry Andric switch (AR) { 169fe6060f1SDimitry Andric case AliasResult::NoAlias: 1700b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintNoAlias, Load, Store, F.getParent()); 1710b57cec5SDimitry Andric ++NoAliasCount; 1720b57cec5SDimitry Andric break; 173fe6060f1SDimitry Andric case AliasResult::MayAlias: 1740b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintMayAlias, Load, Store, F.getParent()); 1750b57cec5SDimitry Andric ++MayAliasCount; 1760b57cec5SDimitry Andric break; 177fe6060f1SDimitry Andric case AliasResult::PartialAlias: 1780b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintPartialAlias, Load, Store, F.getParent()); 1790b57cec5SDimitry Andric ++PartialAliasCount; 1800b57cec5SDimitry Andric break; 181fe6060f1SDimitry Andric case AliasResult::MustAlias: 1820b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintMustAlias, Load, Store, F.getParent()); 1830b57cec5SDimitry Andric ++MustAliasCount; 1840b57cec5SDimitry Andric break; 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric } 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric // iterate over all pairs of store, store 1900b57cec5SDimitry Andric for (SetVector<Value *>::iterator I1 = Stores.begin(), E = Stores.end(); 1910b57cec5SDimitry Andric I1 != E; ++I1) { 1920b57cec5SDimitry Andric for (SetVector<Value *>::iterator I2 = Stores.begin(); I2 != I1; ++I2) { 1930b57cec5SDimitry Andric AliasResult AR = AA.alias(MemoryLocation::get(cast<StoreInst>(*I1)), 1940b57cec5SDimitry Andric MemoryLocation::get(cast<StoreInst>(*I2))); 1950b57cec5SDimitry Andric switch (AR) { 196fe6060f1SDimitry Andric case AliasResult::NoAlias: 1970b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintNoAlias, *I1, *I2, F.getParent()); 1980b57cec5SDimitry Andric ++NoAliasCount; 1990b57cec5SDimitry Andric break; 200fe6060f1SDimitry Andric case AliasResult::MayAlias: 2010b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintMayAlias, *I1, *I2, F.getParent()); 2020b57cec5SDimitry Andric ++MayAliasCount; 2030b57cec5SDimitry Andric break; 204fe6060f1SDimitry Andric case AliasResult::PartialAlias: 2050b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintPartialAlias, *I1, *I2, F.getParent()); 2060b57cec5SDimitry Andric ++PartialAliasCount; 2070b57cec5SDimitry Andric break; 208fe6060f1SDimitry Andric case AliasResult::MustAlias: 2090b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintMustAlias, *I1, *I2, F.getParent()); 2100b57cec5SDimitry Andric ++MustAliasCount; 2110b57cec5SDimitry Andric break; 2120b57cec5SDimitry Andric } 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric } 2150b57cec5SDimitry Andric } 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric // Mod/ref alias analysis: compare all pairs of calls and values 2180b57cec5SDimitry Andric for (CallBase *Call : Calls) { 219*81ad6265SDimitry Andric for (const auto &Pointer : Pointers) { 220*81ad6265SDimitry Andric LocationSize Size = 221*81ad6265SDimitry Andric LocationSize::precise(DL.getTypeStoreSize(Pointer.second)); 222*81ad6265SDimitry Andric switch (AA.getModRefInfo(Call, Pointer.first, Size)) { 2230b57cec5SDimitry Andric case ModRefInfo::NoModRef: 2240b57cec5SDimitry Andric PrintModRefResults("NoModRef", PrintNoModRef, Call, Pointer, 2250b57cec5SDimitry Andric F.getParent()); 2260b57cec5SDimitry Andric ++NoModRefCount; 2270b57cec5SDimitry Andric break; 2280b57cec5SDimitry Andric case ModRefInfo::Mod: 2290b57cec5SDimitry Andric PrintModRefResults("Just Mod", PrintMod, Call, Pointer, F.getParent()); 2300b57cec5SDimitry Andric ++ModCount; 2310b57cec5SDimitry Andric break; 2320b57cec5SDimitry Andric case ModRefInfo::Ref: 2330b57cec5SDimitry Andric PrintModRefResults("Just Ref", PrintRef, Call, Pointer, F.getParent()); 2340b57cec5SDimitry Andric ++RefCount; 2350b57cec5SDimitry Andric break; 2360b57cec5SDimitry Andric case ModRefInfo::ModRef: 2370b57cec5SDimitry Andric PrintModRefResults("Both ModRef", PrintModRef, Call, Pointer, 2380b57cec5SDimitry Andric F.getParent()); 2390b57cec5SDimitry Andric ++ModRefCount; 2400b57cec5SDimitry Andric break; 2410b57cec5SDimitry Andric case ModRefInfo::Must: 2420b57cec5SDimitry Andric PrintModRefResults("Must", PrintMust, Call, Pointer, F.getParent()); 2430b57cec5SDimitry Andric ++MustCount; 2440b57cec5SDimitry Andric break; 2450b57cec5SDimitry Andric case ModRefInfo::MustMod: 2460b57cec5SDimitry Andric PrintModRefResults("Just Mod (MustAlias)", PrintMustMod, Call, Pointer, 2470b57cec5SDimitry Andric F.getParent()); 2480b57cec5SDimitry Andric ++MustModCount; 2490b57cec5SDimitry Andric break; 2500b57cec5SDimitry Andric case ModRefInfo::MustRef: 2510b57cec5SDimitry Andric PrintModRefResults("Just Ref (MustAlias)", PrintMustRef, Call, Pointer, 2520b57cec5SDimitry Andric F.getParent()); 2530b57cec5SDimitry Andric ++MustRefCount; 2540b57cec5SDimitry Andric break; 2550b57cec5SDimitry Andric case ModRefInfo::MustModRef: 2560b57cec5SDimitry Andric PrintModRefResults("Both ModRef (MustAlias)", PrintMustModRef, Call, 2570b57cec5SDimitry Andric Pointer, F.getParent()); 2580b57cec5SDimitry Andric ++MustModRefCount; 2590b57cec5SDimitry Andric break; 2600b57cec5SDimitry Andric } 2610b57cec5SDimitry Andric } 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric // Mod/ref alias analysis: compare all pairs of calls 2650b57cec5SDimitry Andric for (CallBase *CallA : Calls) { 2660b57cec5SDimitry Andric for (CallBase *CallB : Calls) { 2670b57cec5SDimitry Andric if (CallA == CallB) 2680b57cec5SDimitry Andric continue; 2690b57cec5SDimitry Andric switch (AA.getModRefInfo(CallA, CallB)) { 2700b57cec5SDimitry Andric case ModRefInfo::NoModRef: 2710b57cec5SDimitry Andric PrintModRefResults("NoModRef", PrintNoModRef, CallA, CallB, 2720b57cec5SDimitry Andric F.getParent()); 2730b57cec5SDimitry Andric ++NoModRefCount; 2740b57cec5SDimitry Andric break; 2750b57cec5SDimitry Andric case ModRefInfo::Mod: 2760b57cec5SDimitry Andric PrintModRefResults("Just Mod", PrintMod, CallA, CallB, F.getParent()); 2770b57cec5SDimitry Andric ++ModCount; 2780b57cec5SDimitry Andric break; 2790b57cec5SDimitry Andric case ModRefInfo::Ref: 2800b57cec5SDimitry Andric PrintModRefResults("Just Ref", PrintRef, CallA, CallB, F.getParent()); 2810b57cec5SDimitry Andric ++RefCount; 2820b57cec5SDimitry Andric break; 2830b57cec5SDimitry Andric case ModRefInfo::ModRef: 2840b57cec5SDimitry Andric PrintModRefResults("Both ModRef", PrintModRef, CallA, CallB, 2850b57cec5SDimitry Andric F.getParent()); 2860b57cec5SDimitry Andric ++ModRefCount; 2870b57cec5SDimitry Andric break; 2880b57cec5SDimitry Andric case ModRefInfo::Must: 2890b57cec5SDimitry Andric PrintModRefResults("Must", PrintMust, CallA, CallB, F.getParent()); 2900b57cec5SDimitry Andric ++MustCount; 2910b57cec5SDimitry Andric break; 2920b57cec5SDimitry Andric case ModRefInfo::MustMod: 2930b57cec5SDimitry Andric PrintModRefResults("Just Mod (MustAlias)", PrintMustMod, CallA, CallB, 2940b57cec5SDimitry Andric F.getParent()); 2950b57cec5SDimitry Andric ++MustModCount; 2960b57cec5SDimitry Andric break; 2970b57cec5SDimitry Andric case ModRefInfo::MustRef: 2980b57cec5SDimitry Andric PrintModRefResults("Just Ref (MustAlias)", PrintMustRef, CallA, CallB, 2990b57cec5SDimitry Andric F.getParent()); 3000b57cec5SDimitry Andric ++MustRefCount; 3010b57cec5SDimitry Andric break; 3020b57cec5SDimitry Andric case ModRefInfo::MustModRef: 3030b57cec5SDimitry Andric PrintModRefResults("Both ModRef (MustAlias)", PrintMustModRef, CallA, 3040b57cec5SDimitry Andric CallB, F.getParent()); 3050b57cec5SDimitry Andric ++MustModRefCount; 3060b57cec5SDimitry Andric break; 3070b57cec5SDimitry Andric } 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric static void PrintPercent(int64_t Num, int64_t Sum) { 3130b57cec5SDimitry Andric errs() << "(" << Num * 100LL / Sum << "." << ((Num * 1000LL / Sum) % 10) 3140b57cec5SDimitry Andric << "%)\n"; 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric AAEvaluator::~AAEvaluator() { 3180b57cec5SDimitry Andric if (FunctionCount == 0) 3190b57cec5SDimitry Andric return; 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric int64_t AliasSum = 3220b57cec5SDimitry Andric NoAliasCount + MayAliasCount + PartialAliasCount + MustAliasCount; 3230b57cec5SDimitry Andric errs() << "===== Alias Analysis Evaluator Report =====\n"; 3240b57cec5SDimitry Andric if (AliasSum == 0) { 3250b57cec5SDimitry Andric errs() << " Alias Analysis Evaluator Summary: No pointers!\n"; 3260b57cec5SDimitry Andric } else { 3270b57cec5SDimitry Andric errs() << " " << AliasSum << " Total Alias Queries Performed\n"; 3280b57cec5SDimitry Andric errs() << " " << NoAliasCount << " no alias responses "; 3290b57cec5SDimitry Andric PrintPercent(NoAliasCount, AliasSum); 3300b57cec5SDimitry Andric errs() << " " << MayAliasCount << " may alias responses "; 3310b57cec5SDimitry Andric PrintPercent(MayAliasCount, AliasSum); 3320b57cec5SDimitry Andric errs() << " " << PartialAliasCount << " partial alias responses "; 3330b57cec5SDimitry Andric PrintPercent(PartialAliasCount, AliasSum); 3340b57cec5SDimitry Andric errs() << " " << MustAliasCount << " must alias responses "; 3350b57cec5SDimitry Andric PrintPercent(MustAliasCount, AliasSum); 3360b57cec5SDimitry Andric errs() << " Alias Analysis Evaluator Pointer Alias Summary: " 3370b57cec5SDimitry Andric << NoAliasCount * 100 / AliasSum << "%/" 3380b57cec5SDimitry Andric << MayAliasCount * 100 / AliasSum << "%/" 3390b57cec5SDimitry Andric << PartialAliasCount * 100 / AliasSum << "%/" 3400b57cec5SDimitry Andric << MustAliasCount * 100 / AliasSum << "%\n"; 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric // Display the summary for mod/ref analysis 3440b57cec5SDimitry Andric int64_t ModRefSum = NoModRefCount + RefCount + ModCount + ModRefCount + 3450b57cec5SDimitry Andric MustCount + MustRefCount + MustModCount + MustModRefCount; 3460b57cec5SDimitry Andric if (ModRefSum == 0) { 3470b57cec5SDimitry Andric errs() << " Alias Analysis Mod/Ref Evaluator Summary: no " 3480b57cec5SDimitry Andric "mod/ref!\n"; 3490b57cec5SDimitry Andric } else { 3500b57cec5SDimitry Andric errs() << " " << ModRefSum << " Total ModRef Queries Performed\n"; 3510b57cec5SDimitry Andric errs() << " " << NoModRefCount << " no mod/ref responses "; 3520b57cec5SDimitry Andric PrintPercent(NoModRefCount, ModRefSum); 3530b57cec5SDimitry Andric errs() << " " << ModCount << " mod responses "; 3540b57cec5SDimitry Andric PrintPercent(ModCount, ModRefSum); 3550b57cec5SDimitry Andric errs() << " " << RefCount << " ref responses "; 3560b57cec5SDimitry Andric PrintPercent(RefCount, ModRefSum); 3570b57cec5SDimitry Andric errs() << " " << ModRefCount << " mod & ref responses "; 3580b57cec5SDimitry Andric PrintPercent(ModRefCount, ModRefSum); 3590b57cec5SDimitry Andric errs() << " " << MustCount << " must responses "; 3600b57cec5SDimitry Andric PrintPercent(MustCount, ModRefSum); 3610b57cec5SDimitry Andric errs() << " " << MustModCount << " must mod responses "; 3620b57cec5SDimitry Andric PrintPercent(MustModCount, ModRefSum); 3630b57cec5SDimitry Andric errs() << " " << MustRefCount << " must ref responses "; 3640b57cec5SDimitry Andric PrintPercent(MustRefCount, ModRefSum); 3650b57cec5SDimitry Andric errs() << " " << MustModRefCount << " must mod & ref responses "; 3660b57cec5SDimitry Andric PrintPercent(MustModRefCount, ModRefSum); 3670b57cec5SDimitry Andric errs() << " Alias Analysis Evaluator Mod/Ref Summary: " 3680b57cec5SDimitry Andric << NoModRefCount * 100 / ModRefSum << "%/" 3690b57cec5SDimitry Andric << ModCount * 100 / ModRefSum << "%/" << RefCount * 100 / ModRefSum 3700b57cec5SDimitry Andric << "%/" << ModRefCount * 100 / ModRefSum << "%/" 3710b57cec5SDimitry Andric << MustCount * 100 / ModRefSum << "%/" 3720b57cec5SDimitry Andric << MustRefCount * 100 / ModRefSum << "%/" 3730b57cec5SDimitry Andric << MustModCount * 100 / ModRefSum << "%/" 3740b57cec5SDimitry Andric << MustModRefCount * 100 / ModRefSum << "%\n"; 3750b57cec5SDimitry Andric } 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric namespace llvm { 3790b57cec5SDimitry Andric class AAEvalLegacyPass : public FunctionPass { 3800b57cec5SDimitry Andric std::unique_ptr<AAEvaluator> P; 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric public: 3830b57cec5SDimitry Andric static char ID; // Pass identification, replacement for typeid 3840b57cec5SDimitry Andric AAEvalLegacyPass() : FunctionPass(ID) { 3850b57cec5SDimitry Andric initializeAAEvalLegacyPassPass(*PassRegistry::getPassRegistry()); 3860b57cec5SDimitry Andric } 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 3890b57cec5SDimitry Andric AU.addRequired<AAResultsWrapperPass>(); 3900b57cec5SDimitry Andric AU.setPreservesAll(); 3910b57cec5SDimitry Andric } 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric bool doInitialization(Module &M) override { 3940b57cec5SDimitry Andric P.reset(new AAEvaluator()); 3950b57cec5SDimitry Andric return false; 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric bool runOnFunction(Function &F) override { 3990b57cec5SDimitry Andric P->runInternal(F, getAnalysis<AAResultsWrapperPass>().getAAResults()); 4000b57cec5SDimitry Andric return false; 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric bool doFinalization(Module &M) override { 4030b57cec5SDimitry Andric P.reset(); 4040b57cec5SDimitry Andric return false; 4050b57cec5SDimitry Andric } 4060b57cec5SDimitry Andric }; 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric char AAEvalLegacyPass::ID = 0; 4100b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(AAEvalLegacyPass, "aa-eval", 4110b57cec5SDimitry Andric "Exhaustive Alias Analysis Precision Evaluator", false, 4120b57cec5SDimitry Andric true) 4130b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 4140b57cec5SDimitry Andric INITIALIZE_PASS_END(AAEvalLegacyPass, "aa-eval", 4150b57cec5SDimitry Andric "Exhaustive Alias Analysis Precision Evaluator", false, 4160b57cec5SDimitry Andric true) 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric FunctionPass *llvm::createAAEvalPass() { return new AAEvalLegacyPass(); } 419