2003-02-07 05:29:49 +08:00
|
|
|
//===- AliasAnalysisEvaluator.cpp - Alias Analysis Accuracy Evaluator -----===//
|
2005-04-22 05:13:18 +08:00
|
|
|
//
|
2003-10-21 03:43:21 +08:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 04:36:04 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2005-04-22 05:13:18 +08:00
|
|
|
//
|
2003-10-21 03:43:21 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2003-02-07 05:29:49 +08:00
|
|
|
|
2016-02-20 11:46:03 +08:00
|
|
|
#include "llvm/Analysis/AliasAnalysisEvaluator.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/ADT/SetVector.h"
|
|
|
|
#include "llvm/Analysis/AliasAnalysis.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/Constants.h"
|
2015-08-06 10:05:46 +08:00
|
|
|
#include "llvm/IR/DataLayout.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/DerivedTypes.h"
|
|
|
|
#include "llvm/IR/Function.h"
|
2014-03-04 18:30:26 +08:00
|
|
|
#include "llvm/IR/InstIterator.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/Instructions.h"
|
2017-06-06 19:49:48 +08:00
|
|
|
#include "llvm/IR/Module.h"
|
2004-03-12 14:15:08 +08:00
|
|
|
#include "llvm/Pass.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2009-12-24 03:21:19 +08:00
|
|
|
#include "llvm/Support/Debug.h"
|
2009-07-25 08:23:56 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2003-12-10 23:33:59 +08:00
|
|
|
using namespace llvm;
|
2003-11-12 06:41:34 +08:00
|
|
|
|
2008-05-13 08:00:25 +08:00
|
|
|
static cl::opt<bool> PrintAll("print-all-alias-modref-info", cl::ReallyHidden);
|
2004-07-17 14:28:49 +08:00
|
|
|
|
2008-05-13 08:00:25 +08:00
|
|
|
static cl::opt<bool> PrintNoAlias("print-no-aliases", cl::ReallyHidden);
|
|
|
|
static cl::opt<bool> PrintMayAlias("print-may-aliases", cl::ReallyHidden);
|
2010-12-11 03:52:40 +08:00
|
|
|
static cl::opt<bool> PrintPartialAlias("print-partial-aliases", cl::ReallyHidden);
|
2008-05-13 08:00:25 +08:00
|
|
|
static cl::opt<bool> PrintMustAlias("print-must-aliases", cl::ReallyHidden);
|
2004-03-12 14:15:08 +08:00
|
|
|
|
2008-05-13 08:00:25 +08:00
|
|
|
static cl::opt<bool> PrintNoModRef("print-no-modref", cl::ReallyHidden);
|
|
|
|
static cl::opt<bool> PrintRef("print-ref", cl::ReallyHidden);
|
[ModRefInfo] Add must alias info to ModRefInfo.
Summary:
Add an additional bit to ModRefInfo, ModRefInfo::Must, to be cleared for known must aliases.
Shift existing Mod/Ref/ModRef values to include an additional most
significant bit. Update wrappers that modify ModRefInfo values to
reflect the change.
Notes:
* ModRefInfo::Must is almost entirely cleared in the AAResults methods, the remaining changes are trying to preserve it.
* Only some small changes to make custom AA passes set ModRefInfo::Must (BasicAA).
* GlobalsModRef already declares a bit, who's meaning overlaps with the most significant bit in ModRefInfo (MayReadAnyGlobal). No changes to shift the value of MayReadAnyGlobal (see AlignedMap). FunctionInfo.getModRef() ajusts most significant bit so correctness is preserved, but the Must info is lost.
* There are cases where the ModRefInfo::Must is not set, e.g. 2 calls that only read will return ModRefInfo::NoModRef, though they may read from exactly the same location.
Reviewers: dberlin, hfinkel, george.burgess.iv
Subscribers: llvm-commits, sanjoy
Differential Revision: https://reviews.llvm.org/D38862
llvm-svn: 321309
2017-12-22 05:41:53 +08:00
|
|
|
static cl::opt<bool> PrintMod("print-mod", cl::ReallyHidden);
|
2008-05-13 08:00:25 +08:00
|
|
|
static cl::opt<bool> PrintModRef("print-modref", cl::ReallyHidden);
|
[ModRefInfo] Add must alias info to ModRefInfo.
Summary:
Add an additional bit to ModRefInfo, ModRefInfo::Must, to be cleared for known must aliases.
Shift existing Mod/Ref/ModRef values to include an additional most
significant bit. Update wrappers that modify ModRefInfo values to
reflect the change.
Notes:
* ModRefInfo::Must is almost entirely cleared in the AAResults methods, the remaining changes are trying to preserve it.
* Only some small changes to make custom AA passes set ModRefInfo::Must (BasicAA).
* GlobalsModRef already declares a bit, who's meaning overlaps with the most significant bit in ModRefInfo (MayReadAnyGlobal). No changes to shift the value of MayReadAnyGlobal (see AlignedMap). FunctionInfo.getModRef() ajusts most significant bit so correctness is preserved, but the Must info is lost.
* There are cases where the ModRefInfo::Must is not set, e.g. 2 calls that only read will return ModRefInfo::NoModRef, though they may read from exactly the same location.
Reviewers: dberlin, hfinkel, george.burgess.iv
Subscribers: llvm-commits, sanjoy
Differential Revision: https://reviews.llvm.org/D38862
llvm-svn: 321309
2017-12-22 05:41:53 +08:00
|
|
|
static cl::opt<bool> PrintMust("print-must", cl::ReallyHidden);
|
|
|
|
static cl::opt<bool> PrintMustRef("print-mustref", cl::ReallyHidden);
|
|
|
|
static cl::opt<bool> PrintMustMod("print-mustmod", cl::ReallyHidden);
|
|
|
|
static cl::opt<bool> PrintMustModRef("print-mustmodref", cl::ReallyHidden);
|
2003-02-10 04:40:13 +08:00
|
|
|
|
2014-07-24 20:16:19 +08:00
|
|
|
static cl::opt<bool> EvalAAMD("evaluate-aa-metadata", cl::ReallyHidden);
|
2013-03-23 06:34:41 +08:00
|
|
|
|
2018-06-15 03:55:53 +08:00
|
|
|
static void PrintResults(AliasResult AR, bool P, const Value *V1,
|
2009-08-23 13:17:37 +08:00
|
|
|
const Value *V2, const Module *M) {
|
2016-02-20 11:46:03 +08:00
|
|
|
if (PrintAll || P) {
|
2009-08-23 13:17:37 +08:00
|
|
|
std::string o1, o2;
|
|
|
|
{
|
|
|
|
raw_string_ostream os1(o1), os2(o2);
|
2014-01-09 10:29:41 +08:00
|
|
|
V1->printAsOperand(os1, true, M);
|
|
|
|
V2->printAsOperand(os2, true, M);
|
2009-08-23 13:17:37 +08:00
|
|
|
}
|
2018-06-15 03:55:53 +08:00
|
|
|
|
2008-02-28 16:38:45 +08:00
|
|
|
if (o2 < o1)
|
2009-07-25 08:23:56 +08:00
|
|
|
std::swap(o1, o2);
|
2018-06-15 03:55:53 +08:00
|
|
|
errs() << " " << AR << ":\t" << o1 << ", " << o2 << "\n";
|
2003-02-10 04:40:13 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-15 03:55:53 +08:00
|
|
|
static inline void PrintModRefResults(const char *Msg, bool P, Instruction *I,
|
|
|
|
Value *Ptr, Module *M) {
|
2016-02-20 11:46:03 +08:00
|
|
|
if (PrintAll || P) {
|
2009-12-24 06:49:57 +08:00
|
|
|
errs() << " " << Msg << ": Ptr: ";
|
2014-01-09 10:29:41 +08:00
|
|
|
Ptr->printAsOperand(errs(), true, M);
|
2009-12-24 06:49:57 +08:00
|
|
|
errs() << "\t<->" << *I << '\n';
|
2004-07-17 14:43:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-15 03:55:53 +08:00
|
|
|
static inline void PrintModRefResults(const char *Msg, bool P, CallSite CSA,
|
|
|
|
CallSite CSB, Module *M) {
|
2016-02-20 11:46:03 +08:00
|
|
|
if (PrintAll || P) {
|
2018-06-15 03:55:53 +08:00
|
|
|
errs() << " " << Msg << ": " << *CSA.getInstruction() << " <-> "
|
|
|
|
<< *CSB.getInstruction() << '\n';
|
2010-08-05 06:56:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-15 03:55:53 +08:00
|
|
|
static inline void PrintLoadStoreResults(AliasResult AR, bool P,
|
|
|
|
const Value *V1, const Value *V2,
|
|
|
|
const Module *M) {
|
2016-02-20 11:46:03 +08:00
|
|
|
if (PrintAll || P) {
|
2018-06-15 03:55:53 +08:00
|
|
|
errs() << " " << AR << ": " << *V1 << " <-> " << *V2 << '\n';
|
2013-03-23 06:34:41 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-04-09 00:46:24 +08:00
|
|
|
static inline bool isInterestingPointer(Value *V) {
|
|
|
|
return V->getType()->isPointerTy()
|
|
|
|
&& !isa<ConstantPointerNull>(V);
|
|
|
|
}
|
|
|
|
|
2016-08-09 08:28:15 +08:00
|
|
|
PreservedAnalyses AAEvaluator::run(Function &F, FunctionAnalysisManager &AM) {
|
2016-03-11 19:05:24 +08:00
|
|
|
runInternal(F, AM.getResult<AAManager>(F));
|
2016-02-20 11:46:03 +08:00
|
|
|
return PreservedAnalyses::all();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AAEvaluator::runInternal(Function &F, AAResults &AA) {
|
2015-08-06 10:05:46 +08:00
|
|
|
const DataLayout &DL = F.getParent()->getDataLayout();
|
2016-02-20 11:46:03 +08:00
|
|
|
|
|
|
|
++FunctionCount;
|
2010-07-07 22:27:09 +08:00
|
|
|
|
|
|
|
SetVector<Value *> Pointers;
|
2015-11-18 14:52:18 +08:00
|
|
|
SmallSetVector<CallSite, 16> CallSites;
|
2013-03-23 06:34:41 +08:00
|
|
|
SetVector<Value *> Loads;
|
|
|
|
SetVector<Value *> Stores;
|
2010-07-07 22:27:09 +08:00
|
|
|
|
Analysis: Remove implicit ilist iterator conversions
Remove implicit ilist iterator conversions from LLVMAnalysis.
I came across something really scary in `llvm::isKnownNotFullPoison()`
which relied on `Instruction::getNextNode()` being completely broken
(not surprising, but scary nevertheless). This function is documented
(and coded to) return `nullptr` when it gets to the sentinel, but with
an `ilist_half_node` as a sentinel, the sentinel check looks into some
other memory and we don't recognize we've hit the end.
Rooting out these scary cases is the reason I'm removing the implicit
conversions before doing anything else with `ilist`; I'm not at all
surprised that clients rely on badness.
I found another scary case -- this time, not relying on badness, just
bad (but I guess getting lucky so far) -- in
`ObjectSizeOffsetEvaluator::compute_()`. Here, we save out the
insertion point, do some things, and then restore it. Previously, we
let the iterator auto-convert to `Instruction*`, and then set it back
using the `Instruction*` version:
Instruction *PrevInsertPoint = Builder.GetInsertPoint();
/* Logic that may change insert point */
if (PrevInsertPoint)
Builder.SetInsertPoint(PrevInsertPoint);
The check for `PrevInsertPoint` doesn't protect correctly against bad
accesses. If the insertion point has been set to the end of a basic
block (i.e., `SetInsertPoint(SomeBB)`), then `GetInsertPoint()` returns
an iterator pointing at the list sentinel. The version of
`SetInsertPoint()` that's getting called will then call
`PrevInsertPoint->getParent()`, which explodes horribly. The only
reason this hasn't blown up is that it's fairly unlikely the builder is
adding to the end of the block; usually, we're adding instructions
somewhere before the terminator.
llvm-svn: 249925
2015-10-10 08:53:03 +08:00
|
|
|
for (auto &I : F.args())
|
|
|
|
if (I.getType()->isPointerTy()) // Add all pointer arguments.
|
|
|
|
Pointers.insert(&I);
|
2003-02-07 05:29:49 +08:00
|
|
|
|
2003-06-29 08:07:11 +08:00
|
|
|
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
|
2010-04-09 00:46:24 +08:00
|
|
|
if (I->getType()->isPointerTy()) // Add all pointer instructions.
|
2004-04-27 23:13:33 +08:00
|
|
|
Pointers.insert(&*I);
|
2014-07-24 20:16:19 +08:00
|
|
|
if (EvalAAMD && isa<LoadInst>(&*I))
|
2013-03-23 06:34:41 +08:00
|
|
|
Loads.insert(&*I);
|
2014-07-24 20:16:19 +08:00
|
|
|
if (EvalAAMD && isa<StoreInst>(&*I))
|
2013-03-23 06:34:41 +08:00
|
|
|
Stores.insert(&*I);
|
2005-03-18 04:25:04 +08:00
|
|
|
Instruction &Inst = *I;
|
2015-04-10 22:50:08 +08:00
|
|
|
if (auto CS = CallSite(&Inst)) {
|
2010-04-09 00:46:24 +08:00
|
|
|
Value *Callee = CS.getCalledValue();
|
|
|
|
// Skip actual functions for direct function calls.
|
|
|
|
if (!isa<Function>(Callee) && isInterestingPointer(Callee))
|
|
|
|
Pointers.insert(Callee);
|
|
|
|
// Consider formals.
|
2015-12-23 17:58:46 +08:00
|
|
|
for (Use &DataOp : CS.data_ops())
|
|
|
|
if (isInterestingPointer(DataOp))
|
|
|
|
Pointers.insert(DataOp);
|
2010-07-28 23:31:37 +08:00
|
|
|
CallSites.insert(CS);
|
2010-04-09 00:46:24 +08:00
|
|
|
} else {
|
|
|
|
// Consider all operands.
|
|
|
|
for (Instruction::op_iterator OI = Inst.op_begin(), OE = Inst.op_end();
|
|
|
|
OI != OE; ++OI)
|
|
|
|
if (isInterestingPointer(*OI))
|
|
|
|
Pointers.insert(*OI);
|
|
|
|
}
|
2004-03-12 14:15:08 +08:00
|
|
|
}
|
|
|
|
|
2016-02-20 11:46:03 +08:00
|
|
|
if (PrintAll || PrintNoAlias || PrintMayAlias || PrintPartialAlias ||
|
|
|
|
PrintMustAlias || PrintNoModRef || PrintMod || PrintRef || PrintModRef)
|
2010-07-07 22:27:09 +08:00
|
|
|
errs() << "Function: " << F.getName() << ": " << Pointers.size()
|
|
|
|
<< " pointers, " << CallSites.size() << " call sites\n";
|
2003-02-10 04:40:13 +08:00
|
|
|
|
2003-02-07 05:29:49 +08:00
|
|
|
// iterate over the worklist, and run the full (n^2)/2 disambiguations
|
2009-08-26 22:32:17 +08:00
|
|
|
for (SetVector<Value *>::iterator I1 = Pointers.begin(), E = Pointers.end();
|
2004-11-27 05:05:39 +08:00
|
|
|
I1 != E; ++I1) {
|
2015-06-17 15:21:38 +08:00
|
|
|
uint64_t I1Size = MemoryLocation::UnknownSize;
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *I1ElTy = cast<PointerType>((*I1)->getType())->getElementType();
|
2015-08-06 10:05:46 +08:00
|
|
|
if (I1ElTy->isSized()) I1Size = DL.getTypeStoreSize(I1ElTy);
|
2004-11-27 05:05:39 +08:00
|
|
|
|
2009-08-26 22:32:17 +08:00
|
|
|
for (SetVector<Value *>::iterator I2 = Pointers.begin(); I2 != I1; ++I2) {
|
2015-06-17 15:21:38 +08:00
|
|
|
uint64_t I2Size = MemoryLocation::UnknownSize;
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *I2ElTy =cast<PointerType>((*I2)->getType())->getElementType();
|
2015-08-06 10:05:46 +08:00
|
|
|
if (I2ElTy->isSized()) I2Size = DL.getTypeStoreSize(I2ElTy);
|
2004-11-27 05:05:39 +08:00
|
|
|
|
2018-06-15 03:55:53 +08:00
|
|
|
AliasResult AR = AA.alias(*I1, I1Size, *I2, I2Size);
|
|
|
|
switch (AR) {
|
2015-06-22 10:16:51 +08:00
|
|
|
case NoAlias:
|
2018-06-15 03:55:53 +08:00
|
|
|
PrintResults(AR, PrintNoAlias, *I1, *I2, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++NoAliasCount;
|
|
|
|
break;
|
2015-06-22 10:16:51 +08:00
|
|
|
case MayAlias:
|
2018-06-15 03:55:53 +08:00
|
|
|
PrintResults(AR, PrintMayAlias, *I1, *I2, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++MayAliasCount;
|
|
|
|
break;
|
2015-06-22 10:16:51 +08:00
|
|
|
case PartialAlias:
|
2018-06-15 03:55:53 +08:00
|
|
|
PrintResults(AR, PrintPartialAlias, *I1, *I2, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++PartialAliasCount;
|
|
|
|
break;
|
2015-06-22 10:16:51 +08:00
|
|
|
case MustAlias:
|
2018-06-15 03:55:53 +08:00
|
|
|
PrintResults(AR, PrintMustAlias, *I1, *I2, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++MustAliasCount;
|
|
|
|
break;
|
2003-02-07 05:29:49 +08:00
|
|
|
}
|
2004-11-27 05:05:39 +08:00
|
|
|
}
|
|
|
|
}
|
2003-02-07 05:29:49 +08:00
|
|
|
|
2014-07-24 20:16:19 +08:00
|
|
|
if (EvalAAMD) {
|
2013-03-23 06:34:41 +08:00
|
|
|
// iterate over all pairs of load, store
|
2016-06-27 01:27:42 +08:00
|
|
|
for (Value *Load : Loads) {
|
|
|
|
for (Value *Store : Stores) {
|
2018-06-15 03:55:53 +08:00
|
|
|
AliasResult AR = AA.alias(MemoryLocation::get(cast<LoadInst>(Load)),
|
|
|
|
MemoryLocation::get(cast<StoreInst>(Store)));
|
|
|
|
switch (AR) {
|
2015-06-22 10:16:51 +08:00
|
|
|
case NoAlias:
|
2018-06-15 03:55:53 +08:00
|
|
|
PrintLoadStoreResults(AR, PrintNoAlias, Load, Store, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++NoAliasCount;
|
|
|
|
break;
|
2015-06-22 10:16:51 +08:00
|
|
|
case MayAlias:
|
2018-06-15 03:55:53 +08:00
|
|
|
PrintLoadStoreResults(AR, PrintMayAlias, Load, Store, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++MayAliasCount;
|
|
|
|
break;
|
2015-06-22 10:16:51 +08:00
|
|
|
case PartialAlias:
|
2018-06-15 03:55:53 +08:00
|
|
|
PrintLoadStoreResults(AR, PrintPartialAlias, Load, Store, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++PartialAliasCount;
|
|
|
|
break;
|
2015-06-22 10:16:51 +08:00
|
|
|
case MustAlias:
|
2018-06-15 03:55:53 +08:00
|
|
|
PrintLoadStoreResults(AR, PrintMustAlias, Load, Store, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++MustAliasCount;
|
|
|
|
break;
|
2013-03-23 06:34:41 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// iterate over all pairs of store, store
|
|
|
|
for (SetVector<Value *>::iterator I1 = Stores.begin(), E = Stores.end();
|
|
|
|
I1 != E; ++I1) {
|
|
|
|
for (SetVector<Value *>::iterator I2 = Stores.begin(); I2 != I1; ++I2) {
|
2018-06-15 03:55:53 +08:00
|
|
|
AliasResult AR = AA.alias(MemoryLocation::get(cast<StoreInst>(*I1)),
|
|
|
|
MemoryLocation::get(cast<StoreInst>(*I2)));
|
|
|
|
switch (AR) {
|
2015-06-22 10:16:51 +08:00
|
|
|
case NoAlias:
|
2018-06-15 03:55:53 +08:00
|
|
|
PrintLoadStoreResults(AR, PrintNoAlias, *I1, *I2, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++NoAliasCount;
|
|
|
|
break;
|
2015-06-22 10:16:51 +08:00
|
|
|
case MayAlias:
|
2018-06-15 03:55:53 +08:00
|
|
|
PrintLoadStoreResults(AR, PrintMayAlias, *I1, *I2, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++MayAliasCount;
|
|
|
|
break;
|
2015-06-22 10:16:51 +08:00
|
|
|
case PartialAlias:
|
2018-06-15 03:55:53 +08:00
|
|
|
PrintLoadStoreResults(AR, PrintPartialAlias, *I1, *I2, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++PartialAliasCount;
|
|
|
|
break;
|
2015-06-22 10:16:51 +08:00
|
|
|
case MustAlias:
|
2018-06-15 03:55:53 +08:00
|
|
|
PrintLoadStoreResults(AR, PrintMustAlias, *I1, *I2, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++MustAliasCount;
|
|
|
|
break;
|
2013-03-23 06:34:41 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-03-12 14:15:08 +08:00
|
|
|
// Mod/ref alias analysis: compare all pairs of calls and values
|
2016-06-27 01:27:42 +08:00
|
|
|
for (CallSite C : CallSites) {
|
|
|
|
Instruction *I = C.getInstruction();
|
2005-04-22 05:13:18 +08:00
|
|
|
|
2016-06-27 01:27:42 +08:00
|
|
|
for (auto Pointer : Pointers) {
|
2015-06-17 15:21:38 +08:00
|
|
|
uint64_t Size = MemoryLocation::UnknownSize;
|
2016-06-27 01:27:42 +08:00
|
|
|
Type *ElTy = cast<PointerType>(Pointer->getType())->getElementType();
|
2015-08-06 10:05:46 +08:00
|
|
|
if (ElTy->isSized()) Size = DL.getTypeStoreSize(ElTy);
|
2005-04-22 05:13:18 +08:00
|
|
|
|
2016-06-27 01:27:42 +08:00
|
|
|
switch (AA.getModRefInfo(C, Pointer, Size)) {
|
2017-12-08 06:41:34 +08:00
|
|
|
case ModRefInfo::NoModRef:
|
2016-06-27 01:27:42 +08:00
|
|
|
PrintModRefResults("NoModRef", PrintNoModRef, I, Pointer,
|
|
|
|
F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++NoModRefCount;
|
|
|
|
break;
|
2017-12-08 06:41:34 +08:00
|
|
|
case ModRefInfo::Mod:
|
2016-06-27 01:27:42 +08:00
|
|
|
PrintModRefResults("Just Mod", PrintMod, I, Pointer, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++ModCount;
|
|
|
|
break;
|
2017-12-08 06:41:34 +08:00
|
|
|
case ModRefInfo::Ref:
|
2016-06-27 01:27:42 +08:00
|
|
|
PrintModRefResults("Just Ref", PrintRef, I, Pointer, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++RefCount;
|
|
|
|
break;
|
2017-12-08 06:41:34 +08:00
|
|
|
case ModRefInfo::ModRef:
|
2016-06-27 01:27:42 +08:00
|
|
|
PrintModRefResults("Both ModRef", PrintModRef, I, Pointer,
|
|
|
|
F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++ModRefCount;
|
|
|
|
break;
|
[ModRefInfo] Add must alias info to ModRefInfo.
Summary:
Add an additional bit to ModRefInfo, ModRefInfo::Must, to be cleared for known must aliases.
Shift existing Mod/Ref/ModRef values to include an additional most
significant bit. Update wrappers that modify ModRefInfo values to
reflect the change.
Notes:
* ModRefInfo::Must is almost entirely cleared in the AAResults methods, the remaining changes are trying to preserve it.
* Only some small changes to make custom AA passes set ModRefInfo::Must (BasicAA).
* GlobalsModRef already declares a bit, who's meaning overlaps with the most significant bit in ModRefInfo (MayReadAnyGlobal). No changes to shift the value of MayReadAnyGlobal (see AlignedMap). FunctionInfo.getModRef() ajusts most significant bit so correctness is preserved, but the Must info is lost.
* There are cases where the ModRefInfo::Must is not set, e.g. 2 calls that only read will return ModRefInfo::NoModRef, though they may read from exactly the same location.
Reviewers: dberlin, hfinkel, george.burgess.iv
Subscribers: llvm-commits, sanjoy
Differential Revision: https://reviews.llvm.org/D38862
llvm-svn: 321309
2017-12-22 05:41:53 +08:00
|
|
|
case ModRefInfo::Must:
|
|
|
|
PrintModRefResults("Must", PrintMust, I, Pointer, F.getParent());
|
|
|
|
++MustCount;
|
|
|
|
break;
|
|
|
|
case ModRefInfo::MustMod:
|
|
|
|
PrintModRefResults("Just Mod (MustAlias)", PrintMustMod, I, Pointer,
|
|
|
|
F.getParent());
|
|
|
|
++MustModCount;
|
|
|
|
break;
|
|
|
|
case ModRefInfo::MustRef:
|
|
|
|
PrintModRefResults("Just Ref (MustAlias)", PrintMustRef, I, Pointer,
|
|
|
|
F.getParent());
|
|
|
|
++MustRefCount;
|
|
|
|
break;
|
|
|
|
case ModRefInfo::MustModRef:
|
|
|
|
PrintModRefResults("Both ModRef (MustAlias)", PrintMustModRef, I,
|
|
|
|
Pointer, F.getParent());
|
|
|
|
++MustModRefCount;
|
|
|
|
break;
|
2004-03-12 14:15:08 +08:00
|
|
|
}
|
2004-11-27 05:05:39 +08:00
|
|
|
}
|
2004-07-17 15:40:34 +08:00
|
|
|
}
|
2005-04-22 05:13:18 +08:00
|
|
|
|
2010-08-05 06:56:29 +08:00
|
|
|
// Mod/ref alias analysis: compare all pairs of calls
|
2015-11-18 14:52:18 +08:00
|
|
|
for (auto C = CallSites.begin(), Ce = CallSites.end(); C != Ce; ++C) {
|
|
|
|
for (auto D = CallSites.begin(); D != Ce; ++D) {
|
2010-08-05 06:56:29 +08:00
|
|
|
if (D == C)
|
|
|
|
continue;
|
|
|
|
switch (AA.getModRefInfo(*C, *D)) {
|
2017-12-08 06:41:34 +08:00
|
|
|
case ModRefInfo::NoModRef:
|
2010-08-05 06:56:29 +08:00
|
|
|
PrintModRefResults("NoModRef", PrintNoModRef, *C, *D, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++NoModRefCount;
|
|
|
|
break;
|
2017-12-08 06:41:34 +08:00
|
|
|
case ModRefInfo::Mod:
|
2010-08-05 07:37:55 +08:00
|
|
|
PrintModRefResults("Just Mod", PrintMod, *C, *D, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++ModCount;
|
|
|
|
break;
|
2017-12-08 06:41:34 +08:00
|
|
|
case ModRefInfo::Ref:
|
2010-08-05 07:37:55 +08:00
|
|
|
PrintModRefResults("Just Ref", PrintRef, *C, *D, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++RefCount;
|
|
|
|
break;
|
2017-12-08 06:41:34 +08:00
|
|
|
case ModRefInfo::ModRef:
|
2010-08-05 07:37:55 +08:00
|
|
|
PrintModRefResults("Both ModRef", PrintModRef, *C, *D, F.getParent());
|
2015-06-17 15:21:41 +08:00
|
|
|
++ModRefCount;
|
|
|
|
break;
|
[ModRefInfo] Add must alias info to ModRefInfo.
Summary:
Add an additional bit to ModRefInfo, ModRefInfo::Must, to be cleared for known must aliases.
Shift existing Mod/Ref/ModRef values to include an additional most
significant bit. Update wrappers that modify ModRefInfo values to
reflect the change.
Notes:
* ModRefInfo::Must is almost entirely cleared in the AAResults methods, the remaining changes are trying to preserve it.
* Only some small changes to make custom AA passes set ModRefInfo::Must (BasicAA).
* GlobalsModRef already declares a bit, who's meaning overlaps with the most significant bit in ModRefInfo (MayReadAnyGlobal). No changes to shift the value of MayReadAnyGlobal (see AlignedMap). FunctionInfo.getModRef() ajusts most significant bit so correctness is preserved, but the Must info is lost.
* There are cases where the ModRefInfo::Must is not set, e.g. 2 calls that only read will return ModRefInfo::NoModRef, though they may read from exactly the same location.
Reviewers: dberlin, hfinkel, george.burgess.iv
Subscribers: llvm-commits, sanjoy
Differential Revision: https://reviews.llvm.org/D38862
llvm-svn: 321309
2017-12-22 05:41:53 +08:00
|
|
|
case ModRefInfo::Must:
|
|
|
|
PrintModRefResults("Must", PrintMust, *C, *D, F.getParent());
|
|
|
|
++MustCount;
|
|
|
|
break;
|
|
|
|
case ModRefInfo::MustMod:
|
|
|
|
PrintModRefResults("Just Mod (MustAlias)", PrintMustMod, *C, *D,
|
|
|
|
F.getParent());
|
|
|
|
++MustModCount;
|
|
|
|
break;
|
|
|
|
case ModRefInfo::MustRef:
|
|
|
|
PrintModRefResults("Just Ref (MustAlias)", PrintMustRef, *C, *D,
|
|
|
|
F.getParent());
|
|
|
|
++MustRefCount;
|
|
|
|
break;
|
|
|
|
case ModRefInfo::MustModRef:
|
|
|
|
PrintModRefResults("Both ModRef (MustAlias)", PrintMustModRef, *C, *D,
|
|
|
|
F.getParent());
|
|
|
|
++MustModRefCount;
|
|
|
|
break;
|
2010-08-05 06:56:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-02-07 05:29:49 +08:00
|
|
|
}
|
|
|
|
|
2016-02-20 11:46:03 +08:00
|
|
|
static void PrintPercent(int64_t Num, int64_t Sum) {
|
|
|
|
errs() << "(" << Num * 100LL / Sum << "." << ((Num * 1000LL / Sum) % 10)
|
|
|
|
<< "%)\n";
|
2005-03-27 07:56:33 +08:00
|
|
|
}
|
|
|
|
|
2016-02-20 11:46:03 +08:00
|
|
|
AAEvaluator::~AAEvaluator() {
|
|
|
|
if (FunctionCount == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int64_t AliasSum =
|
2015-06-17 15:21:41 +08:00
|
|
|
NoAliasCount + MayAliasCount + PartialAliasCount + MustAliasCount;
|
2009-12-24 06:49:57 +08:00
|
|
|
errs() << "===== Alias Analysis Evaluator Report =====\n";
|
2004-03-12 14:15:08 +08:00
|
|
|
if (AliasSum == 0) {
|
2009-12-24 06:49:57 +08:00
|
|
|
errs() << " Alias Analysis Evaluator Summary: No pointers!\n";
|
2005-04-22 05:13:18 +08:00
|
|
|
} else {
|
2009-12-24 06:49:57 +08:00
|
|
|
errs() << " " << AliasSum << " Total Alias Queries Performed\n";
|
2015-06-17 15:21:41 +08:00
|
|
|
errs() << " " << NoAliasCount << " no alias responses ";
|
|
|
|
PrintPercent(NoAliasCount, AliasSum);
|
|
|
|
errs() << " " << MayAliasCount << " may alias responses ";
|
|
|
|
PrintPercent(MayAliasCount, AliasSum);
|
|
|
|
errs() << " " << PartialAliasCount << " partial alias responses ";
|
|
|
|
PrintPercent(PartialAliasCount, AliasSum);
|
|
|
|
errs() << " " << MustAliasCount << " must alias responses ";
|
|
|
|
PrintPercent(MustAliasCount, AliasSum);
|
2009-12-24 06:49:57 +08:00
|
|
|
errs() << " Alias Analysis Evaluator Pointer Alias Summary: "
|
2015-06-17 15:21:41 +08:00
|
|
|
<< NoAliasCount * 100 / AliasSum << "%/"
|
|
|
|
<< MayAliasCount * 100 / AliasSum << "%/"
|
|
|
|
<< PartialAliasCount * 100 / AliasSum << "%/"
|
|
|
|
<< MustAliasCount * 100 / AliasSum << "%\n";
|
2004-03-12 14:15:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Display the summary for mod/ref analysis
|
[ModRefInfo] Add must alias info to ModRefInfo.
Summary:
Add an additional bit to ModRefInfo, ModRefInfo::Must, to be cleared for known must aliases.
Shift existing Mod/Ref/ModRef values to include an additional most
significant bit. Update wrappers that modify ModRefInfo values to
reflect the change.
Notes:
* ModRefInfo::Must is almost entirely cleared in the AAResults methods, the remaining changes are trying to preserve it.
* Only some small changes to make custom AA passes set ModRefInfo::Must (BasicAA).
* GlobalsModRef already declares a bit, who's meaning overlaps with the most significant bit in ModRefInfo (MayReadAnyGlobal). No changes to shift the value of MayReadAnyGlobal (see AlignedMap). FunctionInfo.getModRef() ajusts most significant bit so correctness is preserved, but the Must info is lost.
* There are cases where the ModRefInfo::Must is not set, e.g. 2 calls that only read will return ModRefInfo::NoModRef, though they may read from exactly the same location.
Reviewers: dberlin, hfinkel, george.burgess.iv
Subscribers: llvm-commits, sanjoy
Differential Revision: https://reviews.llvm.org/D38862
llvm-svn: 321309
2017-12-22 05:41:53 +08:00
|
|
|
int64_t ModRefSum = NoModRefCount + RefCount + ModCount + ModRefCount +
|
|
|
|
MustCount + MustRefCount + MustModCount + MustModRefCount;
|
2004-03-12 14:15:08 +08:00
|
|
|
if (ModRefSum == 0) {
|
2015-06-17 15:21:41 +08:00
|
|
|
errs() << " Alias Analysis Mod/Ref Evaluator Summary: no "
|
|
|
|
"mod/ref!\n";
|
2004-03-12 14:15:08 +08:00
|
|
|
} else {
|
2009-12-24 06:49:57 +08:00
|
|
|
errs() << " " << ModRefSum << " Total ModRef Queries Performed\n";
|
2015-06-17 15:21:41 +08:00
|
|
|
errs() << " " << NoModRefCount << " no mod/ref responses ";
|
|
|
|
PrintPercent(NoModRefCount, ModRefSum);
|
|
|
|
errs() << " " << ModCount << " mod responses ";
|
|
|
|
PrintPercent(ModCount, ModRefSum);
|
|
|
|
errs() << " " << RefCount << " ref responses ";
|
|
|
|
PrintPercent(RefCount, ModRefSum);
|
|
|
|
errs() << " " << ModRefCount << " mod & ref responses ";
|
|
|
|
PrintPercent(ModRefCount, ModRefSum);
|
[ModRefInfo] Add must alias info to ModRefInfo.
Summary:
Add an additional bit to ModRefInfo, ModRefInfo::Must, to be cleared for known must aliases.
Shift existing Mod/Ref/ModRef values to include an additional most
significant bit. Update wrappers that modify ModRefInfo values to
reflect the change.
Notes:
* ModRefInfo::Must is almost entirely cleared in the AAResults methods, the remaining changes are trying to preserve it.
* Only some small changes to make custom AA passes set ModRefInfo::Must (BasicAA).
* GlobalsModRef already declares a bit, who's meaning overlaps with the most significant bit in ModRefInfo (MayReadAnyGlobal). No changes to shift the value of MayReadAnyGlobal (see AlignedMap). FunctionInfo.getModRef() ajusts most significant bit so correctness is preserved, but the Must info is lost.
* There are cases where the ModRefInfo::Must is not set, e.g. 2 calls that only read will return ModRefInfo::NoModRef, though they may read from exactly the same location.
Reviewers: dberlin, hfinkel, george.burgess.iv
Subscribers: llvm-commits, sanjoy
Differential Revision: https://reviews.llvm.org/D38862
llvm-svn: 321309
2017-12-22 05:41:53 +08:00
|
|
|
errs() << " " << MustCount << " must responses ";
|
|
|
|
PrintPercent(MustCount, ModRefSum);
|
|
|
|
errs() << " " << MustModCount << " must mod responses ";
|
|
|
|
PrintPercent(MustModCount, ModRefSum);
|
|
|
|
errs() << " " << MustRefCount << " must ref responses ";
|
|
|
|
PrintPercent(MustRefCount, ModRefSum);
|
|
|
|
errs() << " " << MustModRefCount << " must mod & ref responses ";
|
|
|
|
PrintPercent(MustModRefCount, ModRefSum);
|
2009-12-24 06:49:57 +08:00
|
|
|
errs() << " Alias Analysis Evaluator Mod/Ref Summary: "
|
2015-06-17 15:21:41 +08:00
|
|
|
<< NoModRefCount * 100 / ModRefSum << "%/"
|
|
|
|
<< ModCount * 100 / ModRefSum << "%/" << RefCount * 100 / ModRefSum
|
[ModRefInfo] Add must alias info to ModRefInfo.
Summary:
Add an additional bit to ModRefInfo, ModRefInfo::Must, to be cleared for known must aliases.
Shift existing Mod/Ref/ModRef values to include an additional most
significant bit. Update wrappers that modify ModRefInfo values to
reflect the change.
Notes:
* ModRefInfo::Must is almost entirely cleared in the AAResults methods, the remaining changes are trying to preserve it.
* Only some small changes to make custom AA passes set ModRefInfo::Must (BasicAA).
* GlobalsModRef already declares a bit, who's meaning overlaps with the most significant bit in ModRefInfo (MayReadAnyGlobal). No changes to shift the value of MayReadAnyGlobal (see AlignedMap). FunctionInfo.getModRef() ajusts most significant bit so correctness is preserved, but the Must info is lost.
* There are cases where the ModRefInfo::Must is not set, e.g. 2 calls that only read will return ModRefInfo::NoModRef, though they may read from exactly the same location.
Reviewers: dberlin, hfinkel, george.burgess.iv
Subscribers: llvm-commits, sanjoy
Differential Revision: https://reviews.llvm.org/D38862
llvm-svn: 321309
2017-12-22 05:41:53 +08:00
|
|
|
<< "%/" << ModRefCount * 100 / ModRefSum << "%/"
|
|
|
|
<< MustCount * 100 / ModRefSum << "%/"
|
|
|
|
<< MustRefCount * 100 / ModRefSum << "%/"
|
|
|
|
<< MustModCount * 100 / ModRefSum << "%/"
|
|
|
|
<< MustModRefCount * 100 / ModRefSum << "%\n";
|
2003-02-09 07:04:50 +08:00
|
|
|
}
|
2016-02-20 11:46:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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());
|
|
|
|
}
|
2010-07-07 22:27:09 +08:00
|
|
|
|
2016-02-20 11:46:03 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
};
|
2003-02-07 05:29:49 +08:00
|
|
|
}
|
2016-02-20 11:46:03 +08:00
|
|
|
|
|
|
|
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(); }
|