diff options
Diffstat (limited to 'lib/Analysis/AliasAnalysisEvaluator.cpp')
-rw-r--r-- | lib/Analysis/AliasAnalysisEvaluator.cpp | 174 |
1 files changed, 84 insertions, 90 deletions
diff --git a/lib/Analysis/AliasAnalysisEvaluator.cpp b/lib/Analysis/AliasAnalysisEvaluator.cpp index 12917b650e5ee..baf8f3f881dbe 100644 --- a/lib/Analysis/AliasAnalysisEvaluator.cpp +++ b/lib/Analysis/AliasAnalysisEvaluator.cpp @@ -6,18 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file implements a simple N^2 alias analysis accuracy evaluator. -// Basically, for each function in the program, it simply queries to see how the -// alias analysis implementation answers alias queries between each pair of -// pointers in the function. -// -// This is inspired and adapted from code by: Naveen Neelakantam, Francesco -// Spadini, and Wojciech Stryjewski. -// -//===----------------------------------------------------------------------===// -#include "llvm/Analysis/Passes.h" +#include "llvm/Analysis/AliasAnalysisEvaluator.h" #include "llvm/ADT/SetVector.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/IR/Constants.h" @@ -47,51 +37,9 @@ static cl::opt<bool> PrintModRef("print-modref", cl::ReallyHidden); static cl::opt<bool> EvalAAMD("evaluate-aa-metadata", cl::ReallyHidden); -namespace { - class AAEval : public FunctionPass { - unsigned NoAliasCount, MayAliasCount, PartialAliasCount, MustAliasCount; - unsigned NoModRefCount, ModCount, RefCount, ModRefCount; - - public: - static char ID; // Pass identification, replacement for typeid - AAEval() : FunctionPass(ID) { - initializeAAEvalPass(*PassRegistry::getPassRegistry()); - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired<AAResultsWrapperPass>(); - AU.setPreservesAll(); - } - - bool doInitialization(Module &M) override { - NoAliasCount = MayAliasCount = PartialAliasCount = MustAliasCount = 0; - NoModRefCount = ModCount = RefCount = ModRefCount = 0; - - if (PrintAll) { - PrintNoAlias = PrintMayAlias = true; - PrintPartialAlias = PrintMustAlias = true; - PrintNoModRef = PrintMod = PrintRef = PrintModRef = true; - } - return false; - } - - bool runOnFunction(Function &F) override; - bool doFinalization(Module &M) override; - }; -} - -char AAEval::ID = 0; -INITIALIZE_PASS_BEGIN(AAEval, "aa-eval", - "Exhaustive Alias Analysis Precision Evaluator", false, true) -INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) -INITIALIZE_PASS_END(AAEval, "aa-eval", - "Exhaustive Alias Analysis Precision Evaluator", false, true) - -FunctionPass *llvm::createAAEvalPass() { return new AAEval(); } - static void PrintResults(const char *Msg, bool P, const Value *V1, const Value *V2, const Module *M) { - if (P) { + if (PrintAll || P) { std::string o1, o2; { raw_string_ostream os1(o1), os2(o2); @@ -110,7 +58,7 @@ static void PrintResults(const char *Msg, bool P, const Value *V1, static inline void PrintModRefResults(const char *Msg, bool P, Instruction *I, Value *Ptr, Module *M) { - if (P) { + if (PrintAll || P) { errs() << " " << Msg << ": Ptr: "; Ptr->printAsOperand(errs(), true, M); errs() << "\t<->" << *I << '\n'; @@ -120,7 +68,7 @@ PrintModRefResults(const char *Msg, bool P, Instruction *I, Value *Ptr, static inline void PrintModRefResults(const char *Msg, bool P, CallSite CSA, CallSite CSB, Module *M) { - if (P) { + if (PrintAll || P) { errs() << " " << Msg << ": " << *CSA.getInstruction() << " <-> " << *CSB.getInstruction() << '\n'; } @@ -129,7 +77,7 @@ PrintModRefResults(const char *Msg, bool P, CallSite CSA, CallSite CSB, static inline void PrintLoadStoreResults(const char *Msg, bool P, const Value *V1, const Value *V2, const Module *M) { - if (P) { + if (PrintAll || P) { errs() << " " << Msg << ": " << *V1 << " <-> " << *V2 << '\n'; } @@ -140,9 +88,15 @@ static inline bool isInterestingPointer(Value *V) { && !isa<ConstantPointerNull>(V); } -bool AAEval::runOnFunction(Function &F) { +PreservedAnalyses AAEvaluator::run(Function &F, AnalysisManager<Function> &AM) { + runInternal(F, AM.getResult<AAManager>(F)); + return PreservedAnalyses::all(); +} + +void AAEvaluator::runInternal(Function &F, AAResults &AA) { const DataLayout &DL = F.getParent()->getDataLayout(); - AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults(); + + ++FunctionCount; SetVector<Value *> Pointers; SmallSetVector<CallSite, 16> CallSites; @@ -180,8 +134,8 @@ bool AAEval::runOnFunction(Function &F) { } } - if (PrintNoAlias || PrintMayAlias || PrintPartialAlias || PrintMustAlias || - PrintNoModRef || PrintMod || PrintRef || PrintModRef) + if (PrintAll || PrintNoAlias || PrintMayAlias || PrintPartialAlias || + PrintMustAlias || PrintNoModRef || PrintMod || PrintRef || PrintModRef) errs() << "Function: " << F.getName() << ": " << Pointers.size() << " pointers, " << CallSites.size() << " call sites\n"; @@ -221,29 +175,27 @@ bool AAEval::runOnFunction(Function &F) { if (EvalAAMD) { // iterate over all pairs of load, store - for (SetVector<Value *>::iterator I1 = Loads.begin(), E = Loads.end(); - I1 != E; ++I1) { - for (SetVector<Value *>::iterator I2 = Stores.begin(), E2 = Stores.end(); - I2 != E2; ++I2) { - switch (AA.alias(MemoryLocation::get(cast<LoadInst>(*I1)), - MemoryLocation::get(cast<StoreInst>(*I2)))) { + for (Value *Load : Loads) { + for (Value *Store : Stores) { + switch (AA.alias(MemoryLocation::get(cast<LoadInst>(Load)), + MemoryLocation::get(cast<StoreInst>(Store)))) { case NoAlias: - PrintLoadStoreResults("NoAlias", PrintNoAlias, *I1, *I2, + PrintLoadStoreResults("NoAlias", PrintNoAlias, Load, Store, F.getParent()); ++NoAliasCount; break; case MayAlias: - PrintLoadStoreResults("MayAlias", PrintMayAlias, *I1, *I2, + PrintLoadStoreResults("MayAlias", PrintMayAlias, Load, Store, F.getParent()); ++MayAliasCount; break; case PartialAlias: - PrintLoadStoreResults("PartialAlias", PrintPartialAlias, *I1, *I2, + PrintLoadStoreResults("PartialAlias", PrintPartialAlias, Load, Store, F.getParent()); ++PartialAliasCount; break; case MustAlias: - PrintLoadStoreResults("MustAlias", PrintMustAlias, *I1, *I2, + PrintLoadStoreResults("MustAlias", PrintMustAlias, Load, Store, F.getParent()); ++MustAliasCount; break; @@ -283,30 +235,31 @@ bool AAEval::runOnFunction(Function &F) { } // Mod/ref alias analysis: compare all pairs of calls and values - for (auto C = CallSites.begin(), Ce = CallSites.end(); C != Ce; ++C) { - Instruction *I = C->getInstruction(); + for (CallSite C : CallSites) { + Instruction *I = C.getInstruction(); - for (SetVector<Value *>::iterator V = Pointers.begin(), Ve = Pointers.end(); - V != Ve; ++V) { + for (auto Pointer : Pointers) { uint64_t Size = MemoryLocation::UnknownSize; - Type *ElTy = cast<PointerType>((*V)->getType())->getElementType(); + Type *ElTy = cast<PointerType>(Pointer->getType())->getElementType(); if (ElTy->isSized()) Size = DL.getTypeStoreSize(ElTy); - switch (AA.getModRefInfo(*C, *V, Size)) { + switch (AA.getModRefInfo(C, Pointer, Size)) { case MRI_NoModRef: - PrintModRefResults("NoModRef", PrintNoModRef, I, *V, F.getParent()); + PrintModRefResults("NoModRef", PrintNoModRef, I, Pointer, + F.getParent()); ++NoModRefCount; break; case MRI_Mod: - PrintModRefResults("Just Mod", PrintMod, I, *V, F.getParent()); + PrintModRefResults("Just Mod", PrintMod, I, Pointer, F.getParent()); ++ModCount; break; case MRI_Ref: - PrintModRefResults("Just Ref", PrintRef, I, *V, F.getParent()); + PrintModRefResults("Just Ref", PrintRef, I, Pointer, F.getParent()); ++RefCount; break; case MRI_ModRef: - PrintModRefResults("Both ModRef", PrintModRef, I, *V, F.getParent()); + PrintModRefResults("Both ModRef", PrintModRef, I, Pointer, + F.getParent()); ++ModRefCount; break; } @@ -338,17 +291,18 @@ bool AAEval::runOnFunction(Function &F) { } } } - - return false; } -static void PrintPercent(unsigned Num, unsigned Sum) { - errs() << "(" << Num*100ULL/Sum << "." - << ((Num*1000ULL/Sum) % 10) << "%)\n"; +static void PrintPercent(int64_t Num, int64_t Sum) { + errs() << "(" << Num * 100LL / Sum << "." << ((Num * 1000LL / Sum) % 10) + << "%)\n"; } -bool AAEval::doFinalization(Module &M) { - unsigned AliasSum = +AAEvaluator::~AAEvaluator() { + if (FunctionCount == 0) + return; + + int64_t AliasSum = NoAliasCount + MayAliasCount + PartialAliasCount + MustAliasCount; errs() << "===== Alias Analysis Evaluator Report =====\n"; if (AliasSum == 0) { @@ -371,7 +325,7 @@ bool AAEval::doFinalization(Module &M) { } // Display the summary for mod/ref analysis - unsigned ModRefSum = NoModRefCount + ModCount + RefCount + ModRefCount; + int64_t ModRefSum = NoModRefCount + ModCount + RefCount + ModRefCount; if (ModRefSum == 0) { errs() << " Alias Analysis Mod/Ref Evaluator Summary: no " "mod/ref!\n"; @@ -390,6 +344,46 @@ bool AAEval::doFinalization(Module &M) { << ModCount * 100 / ModRefSum << "%/" << RefCount * 100 / ModRefSum << "%/" << ModRefCount * 100 / ModRefSum << "%\n"; } +} - return false; +namespace llvm { +class AAEvalLegacyPass : public FunctionPass { + std::unique_ptr<AAEvaluator> P; + +public: + static char ID; // Pass identification, replacement for typeid + AAEvalLegacyPass() : FunctionPass(ID) { + initializeAAEvalLegacyPassPass(*PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired<AAResultsWrapperPass>(); + AU.setPreservesAll(); + } + + bool doInitialization(Module &M) override { + P.reset(new AAEvaluator()); + return false; + } + + bool runOnFunction(Function &F) override { + P->runInternal(F, getAnalysis<AAResultsWrapperPass>().getAAResults()); + return false; + } + bool doFinalization(Module &M) override { + P.reset(); + return false; + } +}; } + +char AAEvalLegacyPass::ID = 0; +INITIALIZE_PASS_BEGIN(AAEvalLegacyPass, "aa-eval", + "Exhaustive Alias Analysis Precision Evaluator", false, + true) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) +INITIALIZE_PASS_END(AAEvalLegacyPass, "aa-eval", + "Exhaustive Alias Analysis Precision Evaluator", false, + true) + +FunctionPass *llvm::createAAEvalPass() { return new AAEvalLegacyPass(); } |