From 6d0392224e576df574e8ec64ec6b0e7d5aa0fa02 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 20 Feb 2016 03:46:03 +0000 Subject: [PATCH] [PM/AA] Port alias analysis evaluator to the new pass manager, and use it to actually test the new pass manager AA wiring. This patch was extracted from the (somewhat too large) D12357 and rebosed on top of the slightly different design of the new pass manager AA wiring that I just landed. With this we can start testing the AA in a thorough way with the new pass manager. Some minor cleanups to the code in the pass was necessitated here, but otherwise it is a very minimal change. Differential Revision: http://reviews.llvm.org/D17372 llvm-svn: 261403 --- .../llvm/Analysis/AliasAnalysisEvaluator.h | 67 +++++++++ include/llvm/Analysis/Passes.h | 7 - include/llvm/InitializePasses.h | 2 +- include/llvm/LinkAllPasses.h | 1 + lib/Analysis/AliasAnalysisEvaluator.cpp | 137 +++++++++--------- lib/Analysis/Analysis.cpp | 2 +- lib/Passes/PassBuilder.cpp | 1 + lib/Passes/PassRegistry.def | 1 + test/Analysis/BasicAA/phi-aa.ll | 1 + unittests/Analysis/MixedTBAATest.cpp | 1 + 10 files changed, 140 insertions(+), 80 deletions(-) create mode 100644 include/llvm/Analysis/AliasAnalysisEvaluator.h diff --git a/include/llvm/Analysis/AliasAnalysisEvaluator.h b/include/llvm/Analysis/AliasAnalysisEvaluator.h new file mode 100644 index 00000000000..5275dcab1c6 --- /dev/null +++ b/include/llvm/Analysis/AliasAnalysisEvaluator.h @@ -0,0 +1,67 @@ +//===- AliasAnalysisEvaluator.h - Alias Analysis Accuracy Evaluator -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// 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. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_ALIASANALYSISEVALUATOR_H +#define LLVM_ANALYSIS_ALIASANALYSISEVALUATOR_H + +#include "llvm/IR/Function.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { +class AAResults; + +class AAEvaluator { + int64_t FunctionCount; + int64_t NoAliasCount, MayAliasCount, PartialAliasCount, MustAliasCount; + int64_t NoModRefCount, ModCount, RefCount, ModRefCount; + +public: + AAEvaluator() + : FunctionCount(), NoAliasCount(), MayAliasCount(), PartialAliasCount(), + MustAliasCount(), NoModRefCount(), ModCount(), RefCount(), + ModRefCount() {} + AAEvaluator(AAEvaluator &&Arg) + : FunctionCount(Arg.FunctionCount), NoAliasCount(Arg.NoAliasCount), + MayAliasCount(Arg.MayAliasCount), + PartialAliasCount(Arg.PartialAliasCount), + MustAliasCount(Arg.MustAliasCount), NoModRefCount(Arg.NoModRefCount), + ModCount(Arg.ModCount), RefCount(Arg.RefCount), + ModRefCount(Arg.ModRefCount) { + Arg.FunctionCount = 0; + } + ~AAEvaluator(); + + static StringRef name() { return "AAEvaluator"; } + + /// \brief Run the pass over the function. + PreservedAnalyses run(Function &F, AnalysisManager *AM); + +private: + // Allow the legacy pass to run this using an internal API. + friend class AAEvalLegacyPass; + + void runInternal(Function &F, AAResults &AA); +}; + +/// Create a wrapper of the above for the legacy pass manager. +FunctionPass *createAAEvalPass(); + +} + +#endif diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index da17457d344..1e0fe065e3a 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -23,13 +23,6 @@ namespace llvm { class Pass; class PassInfo; - //===--------------------------------------------------------------------===// - // - // createAAEvalPass - This pass implements a simple N^2 alias analysis - // accuracy evaluator. - // - FunctionPass *createAAEvalPass(); - //===--------------------------------------------------------------------===// // // createObjCARCAAWrapperPass - This pass implements ObjC-ARC-based diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 8aaedc06970..1da195baa7b 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -59,7 +59,7 @@ void initializeCodeGen(PassRegistry&); /// initializeCodeGen - Initialize all passes linked into the CodeGen library. void initializeTarget(PassRegistry&); -void initializeAAEvalPass(PassRegistry&); +void initializeAAEvalLegacyPassPass(PassRegistry&); void initializeAddDiscriminatorsPass(PassRegistry&); void initializeADCELegacyPassPass(PassRegistry&); void initializeBDCEPass(PassRegistry&); diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 91d70f4814a..97f9de416e6 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -17,6 +17,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasSetTracker.h" +#include "llvm/Analysis/AliasAnalysisEvaluator.h" #include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/CFLAliasAnalysis.h" #include "llvm/Analysis/CallPrinter.h" diff --git a/lib/Analysis/AliasAnalysisEvaluator.cpp b/lib/Analysis/AliasAnalysisEvaluator.cpp index 12917b650e5..3a40afcaa84 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 PrintModRef("print-modref", cl::ReallyHidden); static cl::opt 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(); - 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(V); } -bool AAEval::runOnFunction(Function &F) { +PreservedAnalyses AAEvaluator::run(Function &F, AnalysisManager *AM) { + runInternal(F, AM->getResult(F)); + return PreservedAnalyses::all(); +} + +void AAEvaluator::runInternal(Function &F, AAResults &AA) { const DataLayout &DL = F.getParent()->getDataLayout(); - AliasAnalysis &AA = getAnalysis().getAAResults(); + + ++FunctionCount; SetVector Pointers; SmallSetVector 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"; @@ -338,17 +292,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 +326,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 +345,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 P; + +public: + static char ID; // Pass identification, replacement for typeid + AAEvalLegacyPass() : FunctionPass(ID) { + initializeAAEvalLegacyPassPass(*PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired(); + AU.setPreservesAll(); + } + + bool doInitialization(Module &M) override { + P.reset(new AAEvaluator()); + return false; + } + + bool runOnFunction(Function &F) override { + P->runInternal(F, getAnalysis().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(); } diff --git a/lib/Analysis/Analysis.cpp b/lib/Analysis/Analysis.cpp index 9c1ac000be2..811741962aa 100644 --- a/lib/Analysis/Analysis.cpp +++ b/lib/Analysis/Analysis.cpp @@ -20,7 +20,7 @@ using namespace llvm; /// initializeAnalysis - Initialize all passes linked into the Analysis library. void llvm::initializeAnalysis(PassRegistry &Registry) { - initializeAAEvalPass(Registry); + initializeAAEvalLegacyPassPass(Registry); initializeAliasSetPrinterPass(Registry); initializeBasicAAWrapperPassPass(Registry); initializeBlockFrequencyInfoWrapperPassPass(Registry); diff --git a/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp index 17fb8c77d68..80c6e5e8df6 100644 --- a/lib/Passes/PassBuilder.cpp +++ b/lib/Passes/PassBuilder.cpp @@ -17,6 +17,7 @@ #include "llvm/Passes/PassBuilder.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/AliasAnalysisEvaluator.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/CGSCCPassManager.h" diff --git a/lib/Passes/PassRegistry.def b/lib/Passes/PassRegistry.def index 44029fb378c..423381aa1ca 100644 --- a/lib/Passes/PassRegistry.def +++ b/lib/Passes/PassRegistry.def @@ -75,6 +75,7 @@ FUNCTION_ALIAS_ANALYSIS("basic-aa", BasicAA()) #ifndef FUNCTION_PASS #define FUNCTION_PASS(NAME, CREATE_PASS) #endif +FUNCTION_PASS("aa-eval", AAEvaluator()) FUNCTION_PASS("adce", ADCEPass()) FUNCTION_PASS("early-cse", EarlyCSEPass()) FUNCTION_PASS("instcombine", InstCombinePass()) diff --git a/test/Analysis/BasicAA/phi-aa.ll b/test/Analysis/BasicAA/phi-aa.ll index 3944e9e4356..e410520bc0f 100644 --- a/test/Analysis/BasicAA/phi-aa.ll +++ b/test/Analysis/BasicAA/phi-aa.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/unittests/Analysis/MixedTBAATest.cpp b/unittests/Analysis/MixedTBAATest.cpp index d0cfa59f645..d70324f2c6a 100644 --- a/unittests/Analysis/MixedTBAATest.cpp +++ b/unittests/Analysis/MixedTBAATest.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/TypeBasedAliasAnalysis.h" +#include "llvm/Analysis/AliasAnalysisEvaluator.h" #include "llvm/Analysis/Passes.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h"