1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[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
This commit is contained in:
Chandler Carruth 2016-02-20 03:46:03 +00:00
parent 8f10205d60
commit 6d0392224e
10 changed files with 140 additions and 80 deletions

View File

@ -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<Function> *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

View File

@ -23,13 +23,6 @@ namespace llvm {
class Pass; class Pass;
class PassInfo; class PassInfo;
//===--------------------------------------------------------------------===//
//
// createAAEvalPass - This pass implements a simple N^2 alias analysis
// accuracy evaluator.
//
FunctionPass *createAAEvalPass();
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// //
// createObjCARCAAWrapperPass - This pass implements ObjC-ARC-based // createObjCARCAAWrapperPass - This pass implements ObjC-ARC-based

View File

@ -59,7 +59,7 @@ void initializeCodeGen(PassRegistry&);
/// initializeCodeGen - Initialize all passes linked into the CodeGen library. /// initializeCodeGen - Initialize all passes linked into the CodeGen library.
void initializeTarget(PassRegistry&); void initializeTarget(PassRegistry&);
void initializeAAEvalPass(PassRegistry&); void initializeAAEvalLegacyPassPass(PassRegistry&);
void initializeAddDiscriminatorsPass(PassRegistry&); void initializeAddDiscriminatorsPass(PassRegistry&);
void initializeADCELegacyPassPass(PassRegistry&); void initializeADCELegacyPassPass(PassRegistry&);
void initializeBDCEPass(PassRegistry&); void initializeBDCEPass(PassRegistry&);

View File

@ -17,6 +17,7 @@
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/AliasAnalysisEvaluator.h"
#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/CFLAliasAnalysis.h" #include "llvm/Analysis/CFLAliasAnalysis.h"
#include "llvm/Analysis/CallPrinter.h" #include "llvm/Analysis/CallPrinter.h"

View File

@ -6,18 +6,8 @@
// License. See LICENSE.TXT for details. // 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/ADT/SetVector.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/Constants.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); 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, static void PrintResults(const char *Msg, bool P, const Value *V1,
const Value *V2, const Module *M) { const Value *V2, const Module *M) {
if (P) { if (PrintAll || P) {
std::string o1, o2; std::string o1, o2;
{ {
raw_string_ostream os1(o1), os2(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 static inline void
PrintModRefResults(const char *Msg, bool P, Instruction *I, Value *Ptr, PrintModRefResults(const char *Msg, bool P, Instruction *I, Value *Ptr,
Module *M) { Module *M) {
if (P) { if (PrintAll || P) {
errs() << " " << Msg << ": Ptr: "; errs() << " " << Msg << ": Ptr: ";
Ptr->printAsOperand(errs(), true, M); Ptr->printAsOperand(errs(), true, M);
errs() << "\t<->" << *I << '\n'; errs() << "\t<->" << *I << '\n';
@ -120,7 +68,7 @@ PrintModRefResults(const char *Msg, bool P, Instruction *I, Value *Ptr,
static inline void static inline void
PrintModRefResults(const char *Msg, bool P, CallSite CSA, CallSite CSB, PrintModRefResults(const char *Msg, bool P, CallSite CSA, CallSite CSB,
Module *M) { Module *M) {
if (P) { if (PrintAll || P) {
errs() << " " << Msg << ": " << *CSA.getInstruction() errs() << " " << Msg << ": " << *CSA.getInstruction()
<< " <-> " << *CSB.getInstruction() << '\n'; << " <-> " << *CSB.getInstruction() << '\n';
} }
@ -129,7 +77,7 @@ PrintModRefResults(const char *Msg, bool P, CallSite CSA, CallSite CSB,
static inline void static inline void
PrintLoadStoreResults(const char *Msg, bool P, const Value *V1, PrintLoadStoreResults(const char *Msg, bool P, const Value *V1,
const Value *V2, const Module *M) { const Value *V2, const Module *M) {
if (P) { if (PrintAll || P) {
errs() << " " << Msg << ": " << *V1 errs() << " " << Msg << ": " << *V1
<< " <-> " << *V2 << '\n'; << " <-> " << *V2 << '\n';
} }
@ -140,9 +88,15 @@ static inline bool isInterestingPointer(Value *V) {
&& !isa<ConstantPointerNull>(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(); const DataLayout &DL = F.getParent()->getDataLayout();
AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
++FunctionCount;
SetVector<Value *> Pointers; SetVector<Value *> Pointers;
SmallSetVector<CallSite, 16> CallSites; SmallSetVector<CallSite, 16> CallSites;
@ -180,8 +134,8 @@ bool AAEval::runOnFunction(Function &F) {
} }
} }
if (PrintNoAlias || PrintMayAlias || PrintPartialAlias || PrintMustAlias || if (PrintAll || PrintNoAlias || PrintMayAlias || PrintPartialAlias ||
PrintNoModRef || PrintMod || PrintRef || PrintModRef) PrintMustAlias || PrintNoModRef || PrintMod || PrintRef || PrintModRef)
errs() << "Function: " << F.getName() << ": " << Pointers.size() errs() << "Function: " << F.getName() << ": " << Pointers.size()
<< " pointers, " << CallSites.size() << " call sites\n"; << " pointers, " << CallSites.size() << " call sites\n";
@ -338,17 +292,18 @@ bool AAEval::runOnFunction(Function &F) {
} }
} }
} }
return false;
} }
static void PrintPercent(unsigned Num, unsigned Sum) { static void PrintPercent(int64_t Num, int64_t Sum) {
errs() << "(" << Num*100ULL/Sum << "." errs() << "(" << Num * 100LL / Sum << "." << ((Num * 1000LL / Sum) % 10)
<< ((Num*1000ULL/Sum) % 10) << "%)\n"; << "%)\n";
} }
bool AAEval::doFinalization(Module &M) { AAEvaluator::~AAEvaluator() {
unsigned AliasSum = if (FunctionCount == 0)
return;
int64_t AliasSum =
NoAliasCount + MayAliasCount + PartialAliasCount + MustAliasCount; NoAliasCount + MayAliasCount + PartialAliasCount + MustAliasCount;
errs() << "===== Alias Analysis Evaluator Report =====\n"; errs() << "===== Alias Analysis Evaluator Report =====\n";
if (AliasSum == 0) { if (AliasSum == 0) {
@ -371,7 +326,7 @@ bool AAEval::doFinalization(Module &M) {
} }
// Display the summary for mod/ref analysis // Display the summary for mod/ref analysis
unsigned ModRefSum = NoModRefCount + ModCount + RefCount + ModRefCount; int64_t ModRefSum = NoModRefCount + ModCount + RefCount + ModRefCount;
if (ModRefSum == 0) { if (ModRefSum == 0) {
errs() << " Alias Analysis Mod/Ref Evaluator Summary: no " errs() << " Alias Analysis Mod/Ref Evaluator Summary: no "
"mod/ref!\n"; "mod/ref!\n";
@ -390,6 +345,46 @@ bool AAEval::doFinalization(Module &M) {
<< ModCount * 100 / ModRefSum << "%/" << RefCount * 100 / ModRefSum << ModCount * 100 / ModRefSum << "%/" << RefCount * 100 / ModRefSum
<< "%/" << ModRefCount * 100 / ModRefSum << "%\n"; << "%/" << 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(); }

View File

@ -20,7 +20,7 @@ using namespace llvm;
/// initializeAnalysis - Initialize all passes linked into the Analysis library. /// initializeAnalysis - Initialize all passes linked into the Analysis library.
void llvm::initializeAnalysis(PassRegistry &Registry) { void llvm::initializeAnalysis(PassRegistry &Registry) {
initializeAAEvalPass(Registry); initializeAAEvalLegacyPassPass(Registry);
initializeAliasSetPrinterPass(Registry); initializeAliasSetPrinterPass(Registry);
initializeBasicAAWrapperPassPass(Registry); initializeBasicAAWrapperPassPass(Registry);
initializeBlockFrequencyInfoWrapperPassPass(Registry); initializeBlockFrequencyInfoWrapperPassPass(Registry);

View File

@ -17,6 +17,7 @@
#include "llvm/Passes/PassBuilder.h" #include "llvm/Passes/PassBuilder.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AliasAnalysisEvaluator.h"
#include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/CGSCCPassManager.h" #include "llvm/Analysis/CGSCCPassManager.h"

View File

@ -75,6 +75,7 @@ FUNCTION_ALIAS_ANALYSIS("basic-aa", BasicAA())
#ifndef FUNCTION_PASS #ifndef FUNCTION_PASS
#define FUNCTION_PASS(NAME, CREATE_PASS) #define FUNCTION_PASS(NAME, CREATE_PASS)
#endif #endif
FUNCTION_PASS("aa-eval", AAEvaluator())
FUNCTION_PASS("adce", ADCEPass()) FUNCTION_PASS("adce", ADCEPass())
FUNCTION_PASS("early-cse", EarlyCSEPass()) FUNCTION_PASS("early-cse", EarlyCSEPass())
FUNCTION_PASS("instcombine", InstCombinePass()) FUNCTION_PASS("instcombine", InstCombinePass())

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s ; 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 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" target triple = "x86_64-unknown-linux-gnu"

View File

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Analysis/TypeBasedAliasAnalysis.h" #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
#include "llvm/Analysis/AliasAnalysisEvaluator.h"
#include "llvm/Analysis/Passes.h" #include "llvm/Analysis/Passes.h"
#include "llvm/IR/Constants.h" #include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h" #include "llvm/IR/Instructions.h"