diff options
Diffstat (limited to 'llvm/lib/Analysis/AliasAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/AliasAnalysis.cpp | 153 |
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; } |