summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/AliasAnalysis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/AliasAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/AliasAnalysis.cpp153
1 files changed, 78 insertions, 75 deletions
diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp
index 8ed48390818..3446aef3993 100644
--- a/llvm/lib/Analysis/AliasAnalysis.cpp
+++ b/llvm/lib/Analysis/AliasAnalysis.cpp
@@ -40,7 +40,6 @@
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
@@ -118,11 +117,11 @@ bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc,
return false;
}
-ModRefInfo AAResults::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) {
+ModRefInfo AAResults::getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
ModRefInfo Result = ModRefInfo::ModRef;
for (const auto &AA : AAs) {
- Result = intersectModRef(Result, AA->getArgModRefInfo(CS, ArgIdx));
+ Result = intersectModRef(Result, AA->getArgModRefInfo(Call, ArgIdx));
// Early-exit the moment we reach the bottom of the lattice.
if (isNoModRef(Result))
@@ -132,11 +131,11 @@ ModRefInfo AAResults::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) {
return Result;
}
-ModRefInfo AAResults::getModRefInfo(Instruction *I, ImmutableCallSite Call) {
+ModRefInfo AAResults::getModRefInfo(Instruction *I, const CallBase *Call2) {
// We may have two calls.
- if (auto CS = ImmutableCallSite(I)) {
+ if (const auto *Call1 = dyn_cast<CallBase>(I)) {
// Check if the two calls modify the same memory.
- return getModRefInfo(CS, Call);
+ return getModRefInfo(Call1, Call2);
} else if (I->isFenceLike()) {
// If this is a fence, just return ModRef.
return ModRefInfo::ModRef;
@@ -146,19 +145,19 @@ ModRefInfo AAResults::getModRefInfo(Instruction *I, ImmutableCallSite Call) {
// is that if the call references what this instruction
// defines, it must be clobbered by this location.
const MemoryLocation DefLoc = MemoryLocation::get(I);
- ModRefInfo MR = getModRefInfo(Call, DefLoc);
+ ModRefInfo MR = getModRefInfo(Call2, DefLoc);
if (isModOrRefSet(MR))
return setModAndRef(MR);
}
return ModRefInfo::NoModRef;
}
-ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS,
+ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
const MemoryLocation &Loc) {
ModRefInfo Result = ModRefInfo::ModRef;
for (const auto &AA : AAs) {
- Result = intersectModRef(Result, AA->getModRefInfo(CS, Loc));
+ Result = intersectModRef(Result, AA->getModRefInfo(Call, Loc));
// Early-exit the moment we reach the bottom of the lattice.
if (isNoModRef(Result))
@@ -167,7 +166,7 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS,
// Try to refine the mod-ref info further using other API entry points to the
// aggregate set of AA results.
- auto MRB = getModRefBehavior(CS);
+ auto MRB = getModRefBehavior(Call);
if (MRB == FMRB_DoesNotAccessMemory ||
MRB == FMRB_OnlyAccessesInaccessibleMem)
return ModRefInfo::NoModRef;
@@ -181,15 +180,16 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS,
bool IsMustAlias = true;
ModRefInfo AllArgsMask = ModRefInfo::NoModRef;
if (doesAccessArgPointees(MRB)) {
- for (auto AI = CS.arg_begin(), AE = CS.arg_end(); AI != AE; ++AI) {
+ for (auto AI = Call->arg_begin(), AE = Call->arg_end(); AI != AE; ++AI) {
const Value *Arg = *AI;
if (!Arg->getType()->isPointerTy())
continue;
- unsigned ArgIdx = std::distance(CS.arg_begin(), AI);
- MemoryLocation ArgLoc = MemoryLocation::getForArgument(CS, ArgIdx, TLI);
+ unsigned ArgIdx = std::distance(Call->arg_begin(), AI);
+ MemoryLocation ArgLoc =
+ MemoryLocation::getForArgument(Call, ArgIdx, TLI);
AliasResult ArgAlias = alias(ArgLoc, Loc);
if (ArgAlias != NoAlias) {
- ModRefInfo ArgMask = getArgModRefInfo(CS, ArgIdx);
+ ModRefInfo ArgMask = getArgModRefInfo(Call, ArgIdx);
AllArgsMask = unionModRef(AllArgsMask, ArgMask);
}
// Conservatively clear IsMustAlias unless only MustAlias is found.
@@ -213,12 +213,12 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS,
return Result;
}
-ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) {
+ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
+ const CallBase *Call2) {
ModRefInfo Result = ModRefInfo::ModRef;
for (const auto &AA : AAs) {
- Result = intersectModRef(Result, AA->getModRefInfo(CS1, CS2));
+ Result = intersectModRef(Result, AA->getModRefInfo(Call1, Call2));
// Early-exit the moment we reach the bottom of the lattice.
if (isNoModRef(Result))
@@ -228,59 +228,61 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1,
// Try to refine the mod-ref info further using other API entry points to the
// aggregate set of AA results.
- // If CS1 or CS2 are readnone, they don't interact.
- auto CS1B = getModRefBehavior(CS1);
- if (CS1B == FMRB_DoesNotAccessMemory)
+ // If Call1 or Call2 are readnone, they don't interact.
+ auto Call1B = getModRefBehavior(Call1);
+ if (Call1B == FMRB_DoesNotAccessMemory)
return ModRefInfo::NoModRef;
- auto CS2B = getModRefBehavior(CS2);
- if (CS2B == FMRB_DoesNotAccessMemory)
+ auto Call2B = getModRefBehavior(Call2);
+ if (Call2B == FMRB_DoesNotAccessMemory)
return ModRefInfo::NoModRef;
// If they both only read from memory, there is no dependence.
- if (onlyReadsMemory(CS1B) && onlyReadsMemory(CS2B))
+ if (onlyReadsMemory(Call1B) && onlyReadsMemory(Call2B))
return ModRefInfo::NoModRef;
- // If CS1 only reads memory, the only dependence on CS2 can be
- // from CS1 reading memory written by CS2.
- if (onlyReadsMemory(CS1B))
+ // If Call1 only reads memory, the only dependence on Call2 can be
+ // from Call1 reading memory written by Call2.
+ if (onlyReadsMemory(Call1B))
Result = clearMod(Result);
- else if (doesNotReadMemory(CS1B))
+ else if (doesNotReadMemory(Call1B))
Result = clearRef(Result);
- // If CS2 only access memory through arguments, accumulate the mod/ref
- // information from CS1's references to the memory referenced by
- // CS2's arguments.
- if (onlyAccessesArgPointees(CS2B)) {
- if (!doesAccessArgPointees(CS2B))
+ // If Call2 only access memory through arguments, accumulate the mod/ref
+ // information from Call1's references to the memory referenced by
+ // Call2's arguments.
+ if (onlyAccessesArgPointees(Call2B)) {
+ if (!doesAccessArgPointees(Call2B))
return ModRefInfo::NoModRef;
ModRefInfo R = ModRefInfo::NoModRef;
bool IsMustAlias = true;
- for (auto I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) {
+ for (auto I = Call2->arg_begin(), E = Call2->arg_end(); I != E; ++I) {
const Value *Arg = *I;
if (!Arg->getType()->isPointerTy())
continue;
- unsigned CS2ArgIdx = std::distance(CS2.arg_begin(), I);
- auto CS2ArgLoc = MemoryLocation::getForArgument(CS2, CS2ArgIdx, TLI);
-
- // ArgModRefCS2 indicates what CS2 might do to CS2ArgLoc, and the
- // dependence of CS1 on that location is the inverse:
- // - If CS2 modifies location, dependence exists if CS1 reads or writes.
- // - If CS2 only reads location, dependence exists if CS1 writes.
- ModRefInfo ArgModRefCS2 = getArgModRefInfo(CS2, CS2ArgIdx);
+ unsigned Call2ArgIdx = std::distance(Call2->arg_begin(), I);
+ auto Call2ArgLoc =
+ MemoryLocation::getForArgument(Call2, Call2ArgIdx, TLI);
+
+ // ArgModRefC2 indicates what Call2 might do to Call2ArgLoc, and the
+ // dependence of Call1 on that location is the inverse:
+ // - If Call2 modifies location, dependence exists if Call1 reads or
+ // writes.
+ // - If Call2 only reads location, dependence exists if Call1 writes.
+ ModRefInfo ArgModRefC2 = getArgModRefInfo(Call2, Call2ArgIdx);
ModRefInfo ArgMask = ModRefInfo::NoModRef;
- if (isModSet(ArgModRefCS2))
+ if (isModSet(ArgModRefC2))
ArgMask = ModRefInfo::ModRef;
- else if (isRefSet(ArgModRefCS2))
+ else if (isRefSet(ArgModRefC2))
ArgMask = ModRefInfo::Mod;
- // ModRefCS1 indicates what CS1 might do to CS2ArgLoc, and we use
+ // ModRefC1 indicates what Call1 might do to Call2ArgLoc, and we use
// above ArgMask to update dependence info.
- ModRefInfo ModRefCS1 = getModRefInfo(CS1, CS2ArgLoc);
- ArgMask = intersectModRef(ArgMask, ModRefCS1);
+ ModRefInfo ModRefC1 = getModRefInfo(Call1, Call2ArgLoc);
+ ArgMask = intersectModRef(ArgMask, ModRefC1);
// Conservatively clear IsMustAlias unless only MustAlias is found.
- IsMustAlias &= isMustSet(ModRefCS1);
+ IsMustAlias &= isMustSet(ModRefC1);
R = intersectModRef(unionModRef(R, ArgMask), Result);
if (R == Result) {
@@ -298,31 +300,32 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1,
return IsMustAlias ? setMust(R) : clearMust(R);
}
- // If CS1 only accesses memory through arguments, check if CS2 references
- // any of the memory referenced by CS1's arguments. If not, return NoModRef.
- if (onlyAccessesArgPointees(CS1B)) {
- if (!doesAccessArgPointees(CS1B))
+ // If Call1 only accesses memory through arguments, check if Call2 references
+ // any of the memory referenced by Call1's arguments. If not, return NoModRef.
+ if (onlyAccessesArgPointees(Call1B)) {
+ if (!doesAccessArgPointees(Call1B))
return ModRefInfo::NoModRef;
ModRefInfo R = ModRefInfo::NoModRef;
bool IsMustAlias = true;
- for (auto I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) {
+ for (auto I = Call1->arg_begin(), E = Call1->arg_end(); I != E; ++I) {
const Value *Arg = *I;
if (!Arg->getType()->isPointerTy())
continue;
- unsigned CS1ArgIdx = std::distance(CS1.arg_begin(), I);
- auto CS1ArgLoc = MemoryLocation::getForArgument(CS1, CS1ArgIdx, TLI);
-
- // ArgModRefCS1 indicates what CS1 might do to CS1ArgLoc; if CS1 might
- // Mod CS1ArgLoc, then we care about either a Mod or a Ref by CS2. If
- // CS1 might Ref, then we care only about a Mod by CS2.
- ModRefInfo ArgModRefCS1 = getArgModRefInfo(CS1, CS1ArgIdx);
- ModRefInfo ModRefCS2 = getModRefInfo(CS2, CS1ArgLoc);
- if ((isModSet(ArgModRefCS1) && isModOrRefSet(ModRefCS2)) ||
- (isRefSet(ArgModRefCS1) && isModSet(ModRefCS2)))
- R = intersectModRef(unionModRef(R, ArgModRefCS1), Result);
+ unsigned Call1ArgIdx = std::distance(Call1->arg_begin(), I);
+ auto Call1ArgLoc =
+ MemoryLocation::getForArgument(Call1, Call1ArgIdx, TLI);
+
+ // ArgModRefC1 indicates what Call1 might do to Call1ArgLoc; if Call1
+ // might Mod Call1ArgLoc, then we care about either a Mod or a Ref by
+ // Call2. If Call1 might Ref, then we care only about a Mod by Call2.
+ ModRefInfo ArgModRefC1 = getArgModRefInfo(Call1, Call1ArgIdx);
+ ModRefInfo ModRefC2 = getModRefInfo(Call2, Call1ArgLoc);
+ if ((isModSet(ArgModRefC1) && isModOrRefSet(ModRefC2)) ||
+ (isRefSet(ArgModRefC1) && isModSet(ModRefC2)))
+ R = intersectModRef(unionModRef(R, ArgModRefC1), Result);
// Conservatively clear IsMustAlias unless only MustAlias is found.
- IsMustAlias &= isMustSet(ModRefCS2);
+ IsMustAlias &= isMustSet(ModRefC2);
if (R == Result) {
// On early exit, not all args were checked, cannot set Must.
@@ -342,11 +345,11 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1,
return Result;
}
-FunctionModRefBehavior AAResults::getModRefBehavior(ImmutableCallSite CS) {
+FunctionModRefBehavior AAResults::getModRefBehavior(const CallBase *Call) {
FunctionModRefBehavior Result = FMRB_UnknownModRefBehavior;
for (const auto &AA : AAs) {
- Result = FunctionModRefBehavior(Result & AA->getModRefBehavior(CS));
+ Result = FunctionModRefBehavior(Result & AA->getModRefBehavior(Call));
// Early-exit the moment we reach the bottom of the lattice.
if (Result == FMRB_DoesNotAccessMemory)
@@ -558,8 +561,8 @@ ModRefInfo AAResults::callCapturesBefore(const Instruction *I,
isa<Constant>(Object))
return ModRefInfo::ModRef;
- ImmutableCallSite CS(I);
- if (!CS.getInstruction() || CS.getInstruction() == Object)
+ const auto *Call = dyn_cast<CallBase>(I);
+ if (!Call || Call == Object)
return ModRefInfo::ModRef;
if (PointerMayBeCapturedBefore(Object, /* ReturnCaptures */ true,
@@ -572,14 +575,14 @@ ModRefInfo AAResults::callCapturesBefore(const Instruction *I,
ModRefInfo R = ModRefInfo::NoModRef;
bool IsMustAlias = true;
// Set flag only if no May found and all operands processed.
- for (auto CI = CS.data_operands_begin(), CE = CS.data_operands_end();
+ for (auto CI = Call->data_operands_begin(), CE = Call->data_operands_end();
CI != CE; ++CI, ++ArgNo) {
// Only look at the no-capture or byval pointer arguments. If this
// pointer were passed to arguments that were neither of these, then it
// couldn't be no-capture.
if (!(*CI)->getType()->isPointerTy() ||
- (!CS.doesNotCapture(ArgNo) &&
- ArgNo < CS.getNumArgOperands() && !CS.isByValArgument(ArgNo)))
+ (!Call->doesNotCapture(ArgNo) && ArgNo < Call->getNumArgOperands() &&
+ !Call->isByValArgument(ArgNo)))
continue;
AliasResult AR = alias(MemoryLocation(*CI), MemoryLocation(Object));
@@ -591,9 +594,9 @@ ModRefInfo AAResults::callCapturesBefore(const Instruction *I,
IsMustAlias = false;
if (AR == NoAlias)
continue;
- if (CS.doesNotAccessMemory(ArgNo))
+ if (Call->doesNotAccessMemory(ArgNo))
continue;
- if (CS.onlyReadsMemory(ArgNo)) {
+ if (Call->onlyReadsMemory(ArgNo)) {
R = ModRefInfo::Ref;
continue;
}
@@ -775,8 +778,8 @@ AAResults llvm::createLegacyPMAAResults(Pass &P, Function &F,
}
bool llvm::isNoAliasCall(const Value *V) {
- if (auto CS = ImmutableCallSite(V))
- return CS.hasRetAttr(Attribute::NoAlias);
+ if (const auto *Call = dyn_cast<CallBase>(V))
+ return Call->hasRetAttr(Attribute::NoAlias);
return false;
}
OpenPOWER on IntegriCloud