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 350b57cec5SDimitry Andric static cl::opt<bool> EvalAAMD("evaluate-aa-metadata", cl::ReallyHidden); 360b57cec5SDimitry Andric 3781ad6265SDimitry Andric static void PrintResults(AliasResult AR, bool P, 3881ad6265SDimitry Andric std::pair<const Value *, Type *> Loc1, 3981ad6265SDimitry Andric std::pair<const Value *, Type *> Loc2, 4081ad6265SDimitry Andric const Module *M) { 410b57cec5SDimitry Andric if (PrintAll || P) { 4281ad6265SDimitry Andric Type *Ty1 = Loc1.second, *Ty2 = Loc2.second; 4381ad6265SDimitry Andric unsigned AS1 = Loc1.first->getType()->getPointerAddressSpace(); 4481ad6265SDimitry Andric unsigned AS2 = Loc2.first->getType()->getPointerAddressSpace(); 450b57cec5SDimitry Andric std::string o1, o2; 460b57cec5SDimitry Andric { 470b57cec5SDimitry Andric raw_string_ostream os1(o1), os2(o2); 4881ad6265SDimitry Andric Loc1.first->printAsOperand(os1, false, M); 4981ad6265SDimitry Andric Loc2.first->printAsOperand(os2, false, M); 500b57cec5SDimitry Andric } 510b57cec5SDimitry Andric 52fe6060f1SDimitry Andric if (o2 < o1) { 530b57cec5SDimitry Andric std::swap(o1, o2); 5481ad6265SDimitry Andric std::swap(Ty1, Ty2); 5581ad6265SDimitry Andric std::swap(AS1, AS2); 56fe6060f1SDimitry Andric // Change offset sign for the local AR, for printing only. 57fe6060f1SDimitry Andric AR.swap(); 58fe6060f1SDimitry Andric } 5981ad6265SDimitry Andric errs() << " " << AR << ":\t"; 6081ad6265SDimitry Andric Ty1->print(errs(), false, /* NoDetails */ true); 6181ad6265SDimitry Andric if (AS1 != 0) 6281ad6265SDimitry Andric errs() << " addrspace(" << AS1 << ")"; 6381ad6265SDimitry Andric errs() << "* " << o1 << ", "; 6481ad6265SDimitry Andric Ty2->print(errs(), false, /* NoDetails */ true); 6581ad6265SDimitry Andric if (AS2 != 0) 6681ad6265SDimitry Andric errs() << " addrspace(" << AS2 << ")"; 6781ad6265SDimitry Andric errs() << "* " << o2 << "\n"; 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 7181ad6265SDimitry Andric static inline void PrintModRefResults( 7281ad6265SDimitry Andric const char *Msg, bool P, Instruction *I, 7381ad6265SDimitry Andric std::pair<const Value *, Type *> Loc, Module *M) { 740b57cec5SDimitry Andric if (PrintAll || P) { 750b57cec5SDimitry Andric errs() << " " << Msg << ": Ptr: "; 7681ad6265SDimitry Andric Loc.second->print(errs(), false, /* NoDetails */ true); 7781ad6265SDimitry Andric errs() << "* "; 7881ad6265SDimitry Andric Loc.first->printAsOperand(errs(), false, M); 790b57cec5SDimitry Andric errs() << "\t<->" << *I << '\n'; 800b57cec5SDimitry Andric } 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric static inline void PrintModRefResults(const char *Msg, bool P, CallBase *CallA, 840b57cec5SDimitry Andric CallBase *CallB, Module *M) { 850b57cec5SDimitry Andric if (PrintAll || P) { 860b57cec5SDimitry Andric errs() << " " << Msg << ": " << *CallA << " <-> " << *CallB << '\n'; 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric static inline void PrintLoadStoreResults(AliasResult AR, bool P, 910b57cec5SDimitry Andric const Value *V1, const Value *V2, 920b57cec5SDimitry Andric const Module *M) { 930b57cec5SDimitry Andric if (PrintAll || P) { 940b57cec5SDimitry Andric errs() << " " << AR << ": " << *V1 << " <-> " << *V2 << '\n'; 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric PreservedAnalyses AAEvaluator::run(Function &F, FunctionAnalysisManager &AM) { 990b57cec5SDimitry Andric runInternal(F, AM.getResult<AAManager>(F)); 1000b57cec5SDimitry Andric return PreservedAnalyses::all(); 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric void AAEvaluator::runInternal(Function &F, AAResults &AA) { 1040b57cec5SDimitry Andric const DataLayout &DL = F.getParent()->getDataLayout(); 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric ++FunctionCount; 1070b57cec5SDimitry Andric 10881ad6265SDimitry Andric SetVector<std::pair<const Value *, Type *>> Pointers; 1090b57cec5SDimitry Andric SmallSetVector<CallBase *, 16> Calls; 1100b57cec5SDimitry Andric SetVector<Value *> Loads; 1110b57cec5SDimitry Andric SetVector<Value *> Stores; 1120b57cec5SDimitry Andric 113fe6060f1SDimitry Andric for (Instruction &Inst : instructions(F)) { 11481ad6265SDimitry Andric if (auto *LI = dyn_cast<LoadInst>(&Inst)) { 11581ad6265SDimitry Andric Pointers.insert({LI->getPointerOperand(), LI->getType()}); 11681ad6265SDimitry Andric Loads.insert(LI); 11781ad6265SDimitry Andric } else if (auto *SI = dyn_cast<StoreInst>(&Inst)) { 11881ad6265SDimitry Andric Pointers.insert({SI->getPointerOperand(), 11981ad6265SDimitry Andric SI->getValueOperand()->getType()}); 12081ad6265SDimitry Andric Stores.insert(SI); 12181ad6265SDimitry Andric } else if (auto *CB = dyn_cast<CallBase>(&Inst)) 12281ad6265SDimitry Andric Calls.insert(CB); 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric if (PrintAll || PrintNoAlias || PrintMayAlias || PrintPartialAlias || 1260b57cec5SDimitry Andric PrintMustAlias || PrintNoModRef || PrintMod || PrintRef || PrintModRef) 1270b57cec5SDimitry Andric errs() << "Function: " << F.getName() << ": " << Pointers.size() 1280b57cec5SDimitry Andric << " pointers, " << Calls.size() << " call sites\n"; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric // iterate over the worklist, and run the full (n^2)/2 disambiguations 13181ad6265SDimitry Andric for (auto I1 = Pointers.begin(), E = Pointers.end(); I1 != E; ++I1) { 13281ad6265SDimitry Andric LocationSize Size1 = LocationSize::precise(DL.getTypeStoreSize(I1->second)); 13381ad6265SDimitry Andric for (auto I2 = Pointers.begin(); I2 != I1; ++I2) { 13481ad6265SDimitry Andric LocationSize Size2 = 13581ad6265SDimitry Andric LocationSize::precise(DL.getTypeStoreSize(I2->second)); 13681ad6265SDimitry Andric AliasResult AR = AA.alias(I1->first, Size1, I2->first, Size2); 1370b57cec5SDimitry Andric switch (AR) { 138fe6060f1SDimitry Andric case AliasResult::NoAlias: 1390b57cec5SDimitry Andric PrintResults(AR, PrintNoAlias, *I1, *I2, F.getParent()); 1400b57cec5SDimitry Andric ++NoAliasCount; 1410b57cec5SDimitry Andric break; 142fe6060f1SDimitry Andric case AliasResult::MayAlias: 1430b57cec5SDimitry Andric PrintResults(AR, PrintMayAlias, *I1, *I2, F.getParent()); 1440b57cec5SDimitry Andric ++MayAliasCount; 1450b57cec5SDimitry Andric break; 146fe6060f1SDimitry Andric case AliasResult::PartialAlias: 1470b57cec5SDimitry Andric PrintResults(AR, PrintPartialAlias, *I1, *I2, F.getParent()); 1480b57cec5SDimitry Andric ++PartialAliasCount; 1490b57cec5SDimitry Andric break; 150fe6060f1SDimitry Andric case AliasResult::MustAlias: 1510b57cec5SDimitry Andric PrintResults(AR, PrintMustAlias, *I1, *I2, F.getParent()); 1520b57cec5SDimitry Andric ++MustAliasCount; 1530b57cec5SDimitry Andric break; 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric if (EvalAAMD) { 1590b57cec5SDimitry Andric // iterate over all pairs of load, store 1600b57cec5SDimitry Andric for (Value *Load : Loads) { 1610b57cec5SDimitry Andric for (Value *Store : Stores) { 1620b57cec5SDimitry Andric AliasResult AR = AA.alias(MemoryLocation::get(cast<LoadInst>(Load)), 1630b57cec5SDimitry Andric MemoryLocation::get(cast<StoreInst>(Store))); 1640b57cec5SDimitry Andric switch (AR) { 165fe6060f1SDimitry Andric case AliasResult::NoAlias: 1660b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintNoAlias, Load, Store, F.getParent()); 1670b57cec5SDimitry Andric ++NoAliasCount; 1680b57cec5SDimitry Andric break; 169fe6060f1SDimitry Andric case AliasResult::MayAlias: 1700b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintMayAlias, Load, Store, F.getParent()); 1710b57cec5SDimitry Andric ++MayAliasCount; 1720b57cec5SDimitry Andric break; 173fe6060f1SDimitry Andric case AliasResult::PartialAlias: 1740b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintPartialAlias, Load, Store, F.getParent()); 1750b57cec5SDimitry Andric ++PartialAliasCount; 1760b57cec5SDimitry Andric break; 177fe6060f1SDimitry Andric case AliasResult::MustAlias: 1780b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintMustAlias, Load, Store, F.getParent()); 1790b57cec5SDimitry Andric ++MustAliasCount; 1800b57cec5SDimitry Andric break; 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric // iterate over all pairs of store, store 1860b57cec5SDimitry Andric for (SetVector<Value *>::iterator I1 = Stores.begin(), E = Stores.end(); 1870b57cec5SDimitry Andric I1 != E; ++I1) { 1880b57cec5SDimitry Andric for (SetVector<Value *>::iterator I2 = Stores.begin(); I2 != I1; ++I2) { 1890b57cec5SDimitry Andric AliasResult AR = AA.alias(MemoryLocation::get(cast<StoreInst>(*I1)), 1900b57cec5SDimitry Andric MemoryLocation::get(cast<StoreInst>(*I2))); 1910b57cec5SDimitry Andric switch (AR) { 192fe6060f1SDimitry Andric case AliasResult::NoAlias: 1930b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintNoAlias, *I1, *I2, F.getParent()); 1940b57cec5SDimitry Andric ++NoAliasCount; 1950b57cec5SDimitry Andric break; 196fe6060f1SDimitry Andric case AliasResult::MayAlias: 1970b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintMayAlias, *I1, *I2, F.getParent()); 1980b57cec5SDimitry Andric ++MayAliasCount; 1990b57cec5SDimitry Andric break; 200fe6060f1SDimitry Andric case AliasResult::PartialAlias: 2010b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintPartialAlias, *I1, *I2, F.getParent()); 2020b57cec5SDimitry Andric ++PartialAliasCount; 2030b57cec5SDimitry Andric break; 204fe6060f1SDimitry Andric case AliasResult::MustAlias: 2050b57cec5SDimitry Andric PrintLoadStoreResults(AR, PrintMustAlias, *I1, *I2, F.getParent()); 2060b57cec5SDimitry Andric ++MustAliasCount; 2070b57cec5SDimitry Andric break; 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric } 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric // Mod/ref alias analysis: compare all pairs of calls and values 2140b57cec5SDimitry Andric for (CallBase *Call : Calls) { 21581ad6265SDimitry Andric for (const auto &Pointer : Pointers) { 21681ad6265SDimitry Andric LocationSize Size = 21781ad6265SDimitry Andric LocationSize::precise(DL.getTypeStoreSize(Pointer.second)); 21881ad6265SDimitry Andric switch (AA.getModRefInfo(Call, Pointer.first, Size)) { 2190b57cec5SDimitry Andric case ModRefInfo::NoModRef: 2200b57cec5SDimitry Andric PrintModRefResults("NoModRef", PrintNoModRef, Call, Pointer, 2210b57cec5SDimitry Andric F.getParent()); 2220b57cec5SDimitry Andric ++NoModRefCount; 2230b57cec5SDimitry Andric break; 2240b57cec5SDimitry Andric case ModRefInfo::Mod: 2250b57cec5SDimitry Andric PrintModRefResults("Just Mod", PrintMod, Call, Pointer, F.getParent()); 2260b57cec5SDimitry Andric ++ModCount; 2270b57cec5SDimitry Andric break; 2280b57cec5SDimitry Andric case ModRefInfo::Ref: 2290b57cec5SDimitry Andric PrintModRefResults("Just Ref", PrintRef, Call, Pointer, F.getParent()); 2300b57cec5SDimitry Andric ++RefCount; 2310b57cec5SDimitry Andric break; 2320b57cec5SDimitry Andric case ModRefInfo::ModRef: 2330b57cec5SDimitry Andric PrintModRefResults("Both ModRef", PrintModRef, Call, Pointer, 2340b57cec5SDimitry Andric F.getParent()); 2350b57cec5SDimitry Andric ++ModRefCount; 2360b57cec5SDimitry Andric break; 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric // Mod/ref alias analysis: compare all pairs of calls 2420b57cec5SDimitry Andric for (CallBase *CallA : Calls) { 2430b57cec5SDimitry Andric for (CallBase *CallB : Calls) { 2440b57cec5SDimitry Andric if (CallA == CallB) 2450b57cec5SDimitry Andric continue; 2460b57cec5SDimitry Andric switch (AA.getModRefInfo(CallA, CallB)) { 2470b57cec5SDimitry Andric case ModRefInfo::NoModRef: 2480b57cec5SDimitry Andric PrintModRefResults("NoModRef", PrintNoModRef, CallA, CallB, 2490b57cec5SDimitry Andric F.getParent()); 2500b57cec5SDimitry Andric ++NoModRefCount; 2510b57cec5SDimitry Andric break; 2520b57cec5SDimitry Andric case ModRefInfo::Mod: 2530b57cec5SDimitry Andric PrintModRefResults("Just Mod", PrintMod, CallA, CallB, F.getParent()); 2540b57cec5SDimitry Andric ++ModCount; 2550b57cec5SDimitry Andric break; 2560b57cec5SDimitry Andric case ModRefInfo::Ref: 2570b57cec5SDimitry Andric PrintModRefResults("Just Ref", PrintRef, CallA, CallB, F.getParent()); 2580b57cec5SDimitry Andric ++RefCount; 2590b57cec5SDimitry Andric break; 2600b57cec5SDimitry Andric case ModRefInfo::ModRef: 2610b57cec5SDimitry Andric PrintModRefResults("Both ModRef", PrintModRef, CallA, CallB, 2620b57cec5SDimitry Andric F.getParent()); 2630b57cec5SDimitry Andric ++ModRefCount; 2640b57cec5SDimitry Andric break; 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric } 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric static void PrintPercent(int64_t Num, int64_t Sum) { 2710b57cec5SDimitry Andric errs() << "(" << Num * 100LL / Sum << "." << ((Num * 1000LL / Sum) % 10) 2720b57cec5SDimitry Andric << "%)\n"; 2730b57cec5SDimitry Andric } 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric AAEvaluator::~AAEvaluator() { 2760b57cec5SDimitry Andric if (FunctionCount == 0) 2770b57cec5SDimitry Andric return; 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric int64_t AliasSum = 2800b57cec5SDimitry Andric NoAliasCount + MayAliasCount + PartialAliasCount + MustAliasCount; 2810b57cec5SDimitry Andric errs() << "===== Alias Analysis Evaluator Report =====\n"; 2820b57cec5SDimitry Andric if (AliasSum == 0) { 2830b57cec5SDimitry Andric errs() << " Alias Analysis Evaluator Summary: No pointers!\n"; 2840b57cec5SDimitry Andric } else { 2850b57cec5SDimitry Andric errs() << " " << AliasSum << " Total Alias Queries Performed\n"; 2860b57cec5SDimitry Andric errs() << " " << NoAliasCount << " no alias responses "; 2870b57cec5SDimitry Andric PrintPercent(NoAliasCount, AliasSum); 2880b57cec5SDimitry Andric errs() << " " << MayAliasCount << " may alias responses "; 2890b57cec5SDimitry Andric PrintPercent(MayAliasCount, AliasSum); 2900b57cec5SDimitry Andric errs() << " " << PartialAliasCount << " partial alias responses "; 2910b57cec5SDimitry Andric PrintPercent(PartialAliasCount, AliasSum); 2920b57cec5SDimitry Andric errs() << " " << MustAliasCount << " must alias responses "; 2930b57cec5SDimitry Andric PrintPercent(MustAliasCount, AliasSum); 2940b57cec5SDimitry Andric errs() << " Alias Analysis Evaluator Pointer Alias Summary: " 2950b57cec5SDimitry Andric << NoAliasCount * 100 / AliasSum << "%/" 2960b57cec5SDimitry Andric << MayAliasCount * 100 / AliasSum << "%/" 2970b57cec5SDimitry Andric << PartialAliasCount * 100 / AliasSum << "%/" 2980b57cec5SDimitry Andric << MustAliasCount * 100 / AliasSum << "%\n"; 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric // Display the summary for mod/ref analysis 302*bdd1243dSDimitry Andric int64_t ModRefSum = NoModRefCount + RefCount + ModCount + ModRefCount; 3030b57cec5SDimitry Andric if (ModRefSum == 0) { 3040b57cec5SDimitry Andric errs() << " Alias Analysis Mod/Ref Evaluator Summary: no " 3050b57cec5SDimitry Andric "mod/ref!\n"; 3060b57cec5SDimitry Andric } else { 3070b57cec5SDimitry Andric errs() << " " << ModRefSum << " Total ModRef Queries Performed\n"; 3080b57cec5SDimitry Andric errs() << " " << NoModRefCount << " no mod/ref responses "; 3090b57cec5SDimitry Andric PrintPercent(NoModRefCount, ModRefSum); 3100b57cec5SDimitry Andric errs() << " " << ModCount << " mod responses "; 3110b57cec5SDimitry Andric PrintPercent(ModCount, ModRefSum); 3120b57cec5SDimitry Andric errs() << " " << RefCount << " ref responses "; 3130b57cec5SDimitry Andric PrintPercent(RefCount, ModRefSum); 3140b57cec5SDimitry Andric errs() << " " << ModRefCount << " mod & ref responses "; 3150b57cec5SDimitry Andric PrintPercent(ModRefCount, ModRefSum); 3160b57cec5SDimitry Andric errs() << " Alias Analysis Evaluator Mod/Ref Summary: " 3170b57cec5SDimitry Andric << NoModRefCount * 100 / ModRefSum << "%/" 3180b57cec5SDimitry Andric << ModCount * 100 / ModRefSum << "%/" << RefCount * 100 / ModRefSum 319*bdd1243dSDimitry Andric << "%/" << ModRefCount * 100 / ModRefSum << "%\n"; 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric namespace llvm { 3240b57cec5SDimitry Andric class AAEvalLegacyPass : public FunctionPass { 3250b57cec5SDimitry Andric std::unique_ptr<AAEvaluator> P; 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric public: 3280b57cec5SDimitry Andric static char ID; // Pass identification, replacement for typeid 3290b57cec5SDimitry Andric AAEvalLegacyPass() : FunctionPass(ID) { 3300b57cec5SDimitry Andric initializeAAEvalLegacyPassPass(*PassRegistry::getPassRegistry()); 3310b57cec5SDimitry Andric } 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 3340b57cec5SDimitry Andric AU.addRequired<AAResultsWrapperPass>(); 3350b57cec5SDimitry Andric AU.setPreservesAll(); 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric bool doInitialization(Module &M) override { 3390b57cec5SDimitry Andric P.reset(new AAEvaluator()); 3400b57cec5SDimitry Andric return false; 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric bool runOnFunction(Function &F) override { 3440b57cec5SDimitry Andric P->runInternal(F, getAnalysis<AAResultsWrapperPass>().getAAResults()); 3450b57cec5SDimitry Andric return false; 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric bool doFinalization(Module &M) override { 3480b57cec5SDimitry Andric P.reset(); 3490b57cec5SDimitry Andric return false; 3500b57cec5SDimitry Andric } 3510b57cec5SDimitry Andric }; 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric char AAEvalLegacyPass::ID = 0; 3550b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(AAEvalLegacyPass, "aa-eval", 3560b57cec5SDimitry Andric "Exhaustive Alias Analysis Precision Evaluator", false, 3570b57cec5SDimitry Andric true) 3580b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 3590b57cec5SDimitry Andric INITIALIZE_PASS_END(AAEvalLegacyPass, "aa-eval", 3600b57cec5SDimitry Andric "Exhaustive Alias Analysis Precision Evaluator", false, 3610b57cec5SDimitry Andric true) 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric FunctionPass *llvm::createAAEvalPass() { return new AAEvalLegacyPass(); } 364