17330f729Sjoerg //==- AliasAnalysis.cpp - Generic Alias Analysis Interface Implementation --==//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements the generic AliasAnalysis interface which is used as the
107330f729Sjoerg // common interface used by all clients and implementations of alias analysis.
117330f729Sjoerg //
127330f729Sjoerg // This file also implements the default version of the AliasAnalysis interface
137330f729Sjoerg // that is to be used when no other implementation is specified. This does some
147330f729Sjoerg // simple tests that detect obvious cases: two different global pointers cannot
157330f729Sjoerg // alias, a global cannot alias a malloc, two different mallocs cannot alias,
167330f729Sjoerg // etc.
177330f729Sjoerg //
187330f729Sjoerg // This alias analysis implementation really isn't very good for anything, but
197330f729Sjoerg // it is very fast, and makes a nice clean default implementation. Because it
207330f729Sjoerg // handles lots of little corner cases, other, more complex, alias analysis
217330f729Sjoerg // implementations may choose to rely on this pass to resolve these simple and
227330f729Sjoerg // easy cases.
237330f729Sjoerg //
247330f729Sjoerg //===----------------------------------------------------------------------===//
257330f729Sjoerg
267330f729Sjoerg #include "llvm/Analysis/AliasAnalysis.h"
27*82d56013Sjoerg #include "llvm/ADT/Statistic.h"
287330f729Sjoerg #include "llvm/Analysis/BasicAliasAnalysis.h"
297330f729Sjoerg #include "llvm/Analysis/CFLAndersAliasAnalysis.h"
307330f729Sjoerg #include "llvm/Analysis/CFLSteensAliasAnalysis.h"
317330f729Sjoerg #include "llvm/Analysis/CaptureTracking.h"
327330f729Sjoerg #include "llvm/Analysis/GlobalsModRef.h"
337330f729Sjoerg #include "llvm/Analysis/MemoryLocation.h"
347330f729Sjoerg #include "llvm/Analysis/ObjCARCAliasAnalysis.h"
357330f729Sjoerg #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
367330f729Sjoerg #include "llvm/Analysis/ScopedNoAliasAA.h"
377330f729Sjoerg #include "llvm/Analysis/TargetLibraryInfo.h"
387330f729Sjoerg #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
397330f729Sjoerg #include "llvm/Analysis/ValueTracking.h"
407330f729Sjoerg #include "llvm/IR/Argument.h"
417330f729Sjoerg #include "llvm/IR/Attributes.h"
427330f729Sjoerg #include "llvm/IR/BasicBlock.h"
437330f729Sjoerg #include "llvm/IR/Instruction.h"
447330f729Sjoerg #include "llvm/IR/Instructions.h"
457330f729Sjoerg #include "llvm/IR/Module.h"
467330f729Sjoerg #include "llvm/IR/Type.h"
477330f729Sjoerg #include "llvm/IR/Value.h"
48*82d56013Sjoerg #include "llvm/InitializePasses.h"
497330f729Sjoerg #include "llvm/Pass.h"
507330f729Sjoerg #include "llvm/Support/AtomicOrdering.h"
517330f729Sjoerg #include "llvm/Support/Casting.h"
527330f729Sjoerg #include "llvm/Support/CommandLine.h"
537330f729Sjoerg #include <algorithm>
547330f729Sjoerg #include <cassert>
557330f729Sjoerg #include <functional>
567330f729Sjoerg #include <iterator>
577330f729Sjoerg
58*82d56013Sjoerg #define DEBUG_TYPE "aa"
59*82d56013Sjoerg
607330f729Sjoerg using namespace llvm;
617330f729Sjoerg
62*82d56013Sjoerg STATISTIC(NumNoAlias, "Number of NoAlias results");
63*82d56013Sjoerg STATISTIC(NumMayAlias, "Number of MayAlias results");
64*82d56013Sjoerg STATISTIC(NumMustAlias, "Number of MustAlias results");
65*82d56013Sjoerg
66*82d56013Sjoerg namespace llvm {
677330f729Sjoerg /// Allow disabling BasicAA from the AA results. This is particularly useful
687330f729Sjoerg /// when testing to isolate a single AA implementation.
69*82d56013Sjoerg cl::opt<bool> DisableBasicAA("disable-basic-aa", cl::Hidden, cl::init(false));
70*82d56013Sjoerg } // namespace llvm
71*82d56013Sjoerg
72*82d56013Sjoerg #ifndef NDEBUG
73*82d56013Sjoerg /// Print a trace of alias analysis queries and their results.
74*82d56013Sjoerg static cl::opt<bool> EnableAATrace("aa-trace", cl::Hidden, cl::init(false));
75*82d56013Sjoerg #else
76*82d56013Sjoerg static const bool EnableAATrace = false;
77*82d56013Sjoerg #endif
787330f729Sjoerg
AAResults(AAResults && Arg)797330f729Sjoerg AAResults::AAResults(AAResults &&Arg)
807330f729Sjoerg : TLI(Arg.TLI), AAs(std::move(Arg.AAs)), AADeps(std::move(Arg.AADeps)) {
817330f729Sjoerg for (auto &AA : AAs)
827330f729Sjoerg AA->setAAResults(this);
837330f729Sjoerg }
847330f729Sjoerg
~AAResults()857330f729Sjoerg AAResults::~AAResults() {
867330f729Sjoerg // FIXME; It would be nice to at least clear out the pointers back to this
877330f729Sjoerg // aggregation here, but we end up with non-nesting lifetimes in the legacy
887330f729Sjoerg // pass manager that prevent this from working. In the legacy pass manager
897330f729Sjoerg // we'll end up with dangling references here in some cases.
907330f729Sjoerg #if 0
917330f729Sjoerg for (auto &AA : AAs)
927330f729Sjoerg AA->setAAResults(nullptr);
937330f729Sjoerg #endif
947330f729Sjoerg }
957330f729Sjoerg
invalidate(Function & F,const PreservedAnalyses & PA,FunctionAnalysisManager::Invalidator & Inv)967330f729Sjoerg bool AAResults::invalidate(Function &F, const PreservedAnalyses &PA,
977330f729Sjoerg FunctionAnalysisManager::Invalidator &Inv) {
987330f729Sjoerg // AAResults preserves the AAManager by default, due to the stateless nature
997330f729Sjoerg // of AliasAnalysis. There is no need to check whether it has been preserved
1007330f729Sjoerg // explicitly. Check if any module dependency was invalidated and caused the
1017330f729Sjoerg // AAManager to be invalidated. Invalidate ourselves in that case.
1027330f729Sjoerg auto PAC = PA.getChecker<AAManager>();
1037330f729Sjoerg if (!PAC.preservedWhenStateless())
1047330f729Sjoerg return true;
1057330f729Sjoerg
1067330f729Sjoerg // Check if any of the function dependencies were invalidated, and invalidate
1077330f729Sjoerg // ourselves in that case.
1087330f729Sjoerg for (AnalysisKey *ID : AADeps)
1097330f729Sjoerg if (Inv.invalidate(ID, F, PA))
1107330f729Sjoerg return true;
1117330f729Sjoerg
1127330f729Sjoerg // Everything we depend on is still fine, so are we. Nothing to invalidate.
1137330f729Sjoerg return false;
1147330f729Sjoerg }
1157330f729Sjoerg
1167330f729Sjoerg //===----------------------------------------------------------------------===//
1177330f729Sjoerg // Default chaining methods
1187330f729Sjoerg //===----------------------------------------------------------------------===//
1197330f729Sjoerg
alias(const MemoryLocation & LocA,const MemoryLocation & LocB)1207330f729Sjoerg AliasResult AAResults::alias(const MemoryLocation &LocA,
1217330f729Sjoerg const MemoryLocation &LocB) {
1227330f729Sjoerg AAQueryInfo AAQIP;
1237330f729Sjoerg return alias(LocA, LocB, AAQIP);
1247330f729Sjoerg }
1257330f729Sjoerg
alias(const MemoryLocation & LocA,const MemoryLocation & LocB,AAQueryInfo & AAQI)1267330f729Sjoerg AliasResult AAResults::alias(const MemoryLocation &LocA,
1277330f729Sjoerg const MemoryLocation &LocB, AAQueryInfo &AAQI) {
128*82d56013Sjoerg AliasResult Result = AliasResult::MayAlias;
129*82d56013Sjoerg
130*82d56013Sjoerg if (EnableAATrace) {
131*82d56013Sjoerg for (unsigned I = 0; I < AAQI.Depth; ++I)
132*82d56013Sjoerg dbgs() << " ";
133*82d56013Sjoerg dbgs() << "Start " << *LocA.Ptr << " @ " << LocA.Size << ", "
134*82d56013Sjoerg << *LocB.Ptr << " @ " << LocB.Size << "\n";
1357330f729Sjoerg }
136*82d56013Sjoerg
137*82d56013Sjoerg AAQI.Depth++;
138*82d56013Sjoerg for (const auto &AA : AAs) {
139*82d56013Sjoerg Result = AA->alias(LocA, LocB, AAQI);
140*82d56013Sjoerg if (Result != AliasResult::MayAlias)
141*82d56013Sjoerg break;
142*82d56013Sjoerg }
143*82d56013Sjoerg AAQI.Depth--;
144*82d56013Sjoerg
145*82d56013Sjoerg if (EnableAATrace) {
146*82d56013Sjoerg for (unsigned I = 0; I < AAQI.Depth; ++I)
147*82d56013Sjoerg dbgs() << " ";
148*82d56013Sjoerg dbgs() << "End " << *LocA.Ptr << " @ " << LocA.Size << ", "
149*82d56013Sjoerg << *LocB.Ptr << " @ " << LocB.Size << " = " << Result << "\n";
150*82d56013Sjoerg }
151*82d56013Sjoerg
152*82d56013Sjoerg if (AAQI.Depth == 0) {
153*82d56013Sjoerg if (Result == AliasResult::NoAlias)
154*82d56013Sjoerg ++NumNoAlias;
155*82d56013Sjoerg else if (Result == AliasResult::MustAlias)
156*82d56013Sjoerg ++NumMustAlias;
157*82d56013Sjoerg else
158*82d56013Sjoerg ++NumMayAlias;
159*82d56013Sjoerg }
160*82d56013Sjoerg return Result;
1617330f729Sjoerg }
1627330f729Sjoerg
pointsToConstantMemory(const MemoryLocation & Loc,bool OrLocal)1637330f729Sjoerg bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc,
1647330f729Sjoerg bool OrLocal) {
1657330f729Sjoerg AAQueryInfo AAQIP;
1667330f729Sjoerg return pointsToConstantMemory(Loc, AAQIP, OrLocal);
1677330f729Sjoerg }
1687330f729Sjoerg
pointsToConstantMemory(const MemoryLocation & Loc,AAQueryInfo & AAQI,bool OrLocal)1697330f729Sjoerg bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc,
1707330f729Sjoerg AAQueryInfo &AAQI, bool OrLocal) {
1717330f729Sjoerg for (const auto &AA : AAs)
1727330f729Sjoerg if (AA->pointsToConstantMemory(Loc, AAQI, OrLocal))
1737330f729Sjoerg return true;
1747330f729Sjoerg
1757330f729Sjoerg return false;
1767330f729Sjoerg }
1777330f729Sjoerg
getArgModRefInfo(const CallBase * Call,unsigned ArgIdx)1787330f729Sjoerg ModRefInfo AAResults::getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
1797330f729Sjoerg ModRefInfo Result = ModRefInfo::ModRef;
1807330f729Sjoerg
1817330f729Sjoerg for (const auto &AA : AAs) {
1827330f729Sjoerg Result = intersectModRef(Result, AA->getArgModRefInfo(Call, ArgIdx));
1837330f729Sjoerg
1847330f729Sjoerg // Early-exit the moment we reach the bottom of the lattice.
1857330f729Sjoerg if (isNoModRef(Result))
1867330f729Sjoerg return ModRefInfo::NoModRef;
1877330f729Sjoerg }
1887330f729Sjoerg
1897330f729Sjoerg return Result;
1907330f729Sjoerg }
1917330f729Sjoerg
getModRefInfo(Instruction * I,const CallBase * Call2)1927330f729Sjoerg ModRefInfo AAResults::getModRefInfo(Instruction *I, const CallBase *Call2) {
1937330f729Sjoerg AAQueryInfo AAQIP;
1947330f729Sjoerg return getModRefInfo(I, Call2, AAQIP);
1957330f729Sjoerg }
1967330f729Sjoerg
getModRefInfo(Instruction * I,const CallBase * Call2,AAQueryInfo & AAQI)1977330f729Sjoerg ModRefInfo AAResults::getModRefInfo(Instruction *I, const CallBase *Call2,
1987330f729Sjoerg AAQueryInfo &AAQI) {
1997330f729Sjoerg // We may have two calls.
2007330f729Sjoerg if (const auto *Call1 = dyn_cast<CallBase>(I)) {
2017330f729Sjoerg // Check if the two calls modify the same memory.
2027330f729Sjoerg return getModRefInfo(Call1, Call2, AAQI);
2037330f729Sjoerg } else if (I->isFenceLike()) {
2047330f729Sjoerg // If this is a fence, just return ModRef.
2057330f729Sjoerg return ModRefInfo::ModRef;
2067330f729Sjoerg } else {
2077330f729Sjoerg // Otherwise, check if the call modifies or references the
2087330f729Sjoerg // location this memory access defines. The best we can say
2097330f729Sjoerg // is that if the call references what this instruction
2107330f729Sjoerg // defines, it must be clobbered by this location.
2117330f729Sjoerg const MemoryLocation DefLoc = MemoryLocation::get(I);
2127330f729Sjoerg ModRefInfo MR = getModRefInfo(Call2, DefLoc, AAQI);
2137330f729Sjoerg if (isModOrRefSet(MR))
2147330f729Sjoerg return setModAndRef(MR);
2157330f729Sjoerg }
2167330f729Sjoerg return ModRefInfo::NoModRef;
2177330f729Sjoerg }
2187330f729Sjoerg
getModRefInfo(const CallBase * Call,const MemoryLocation & Loc)2197330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
2207330f729Sjoerg const MemoryLocation &Loc) {
2217330f729Sjoerg AAQueryInfo AAQIP;
2227330f729Sjoerg return getModRefInfo(Call, Loc, AAQIP);
2237330f729Sjoerg }
2247330f729Sjoerg
getModRefInfo(const CallBase * Call,const MemoryLocation & Loc,AAQueryInfo & AAQI)2257330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
2267330f729Sjoerg const MemoryLocation &Loc,
2277330f729Sjoerg AAQueryInfo &AAQI) {
2287330f729Sjoerg ModRefInfo Result = ModRefInfo::ModRef;
2297330f729Sjoerg
2307330f729Sjoerg for (const auto &AA : AAs) {
2317330f729Sjoerg Result = intersectModRef(Result, AA->getModRefInfo(Call, Loc, AAQI));
2327330f729Sjoerg
2337330f729Sjoerg // Early-exit the moment we reach the bottom of the lattice.
2347330f729Sjoerg if (isNoModRef(Result))
2357330f729Sjoerg return ModRefInfo::NoModRef;
2367330f729Sjoerg }
2377330f729Sjoerg
2387330f729Sjoerg // Try to refine the mod-ref info further using other API entry points to the
2397330f729Sjoerg // aggregate set of AA results.
2407330f729Sjoerg auto MRB = getModRefBehavior(Call);
241*82d56013Sjoerg if (onlyAccessesInaccessibleMem(MRB))
2427330f729Sjoerg return ModRefInfo::NoModRef;
2437330f729Sjoerg
2447330f729Sjoerg if (onlyReadsMemory(MRB))
2457330f729Sjoerg Result = clearMod(Result);
2467330f729Sjoerg else if (doesNotReadMemory(MRB))
2477330f729Sjoerg Result = clearRef(Result);
2487330f729Sjoerg
2497330f729Sjoerg if (onlyAccessesArgPointees(MRB) || onlyAccessesInaccessibleOrArgMem(MRB)) {
2507330f729Sjoerg bool IsMustAlias = true;
2517330f729Sjoerg ModRefInfo AllArgsMask = ModRefInfo::NoModRef;
2527330f729Sjoerg if (doesAccessArgPointees(MRB)) {
2537330f729Sjoerg for (auto AI = Call->arg_begin(), AE = Call->arg_end(); AI != AE; ++AI) {
2547330f729Sjoerg const Value *Arg = *AI;
2557330f729Sjoerg if (!Arg->getType()->isPointerTy())
2567330f729Sjoerg continue;
2577330f729Sjoerg unsigned ArgIdx = std::distance(Call->arg_begin(), AI);
2587330f729Sjoerg MemoryLocation ArgLoc =
2597330f729Sjoerg MemoryLocation::getForArgument(Call, ArgIdx, TLI);
260*82d56013Sjoerg AliasResult ArgAlias = alias(ArgLoc, Loc, AAQI);
261*82d56013Sjoerg if (ArgAlias != AliasResult::NoAlias) {
2627330f729Sjoerg ModRefInfo ArgMask = getArgModRefInfo(Call, ArgIdx);
2637330f729Sjoerg AllArgsMask = unionModRef(AllArgsMask, ArgMask);
2647330f729Sjoerg }
2657330f729Sjoerg // Conservatively clear IsMustAlias unless only MustAlias is found.
266*82d56013Sjoerg IsMustAlias &= (ArgAlias == AliasResult::MustAlias);
2677330f729Sjoerg }
2687330f729Sjoerg }
2697330f729Sjoerg // Return NoModRef if no alias found with any argument.
2707330f729Sjoerg if (isNoModRef(AllArgsMask))
2717330f729Sjoerg return ModRefInfo::NoModRef;
2727330f729Sjoerg // Logical & between other AA analyses and argument analysis.
2737330f729Sjoerg Result = intersectModRef(Result, AllArgsMask);
2747330f729Sjoerg // If only MustAlias found above, set Must bit.
2757330f729Sjoerg Result = IsMustAlias ? setMust(Result) : clearMust(Result);
2767330f729Sjoerg }
2777330f729Sjoerg
2787330f729Sjoerg // If Loc is a constant memory location, the call definitely could not
2797330f729Sjoerg // modify the memory location.
280*82d56013Sjoerg if (isModSet(Result) && pointsToConstantMemory(Loc, AAQI, /*OrLocal*/ false))
2817330f729Sjoerg Result = clearMod(Result);
2827330f729Sjoerg
2837330f729Sjoerg return Result;
2847330f729Sjoerg }
2857330f729Sjoerg
getModRefInfo(const CallBase * Call1,const CallBase * Call2)2867330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
2877330f729Sjoerg const CallBase *Call2) {
2887330f729Sjoerg AAQueryInfo AAQIP;
2897330f729Sjoerg return getModRefInfo(Call1, Call2, AAQIP);
2907330f729Sjoerg }
2917330f729Sjoerg
getModRefInfo(const CallBase * Call1,const CallBase * Call2,AAQueryInfo & AAQI)2927330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
2937330f729Sjoerg const CallBase *Call2, AAQueryInfo &AAQI) {
2947330f729Sjoerg ModRefInfo Result = ModRefInfo::ModRef;
2957330f729Sjoerg
2967330f729Sjoerg for (const auto &AA : AAs) {
2977330f729Sjoerg Result = intersectModRef(Result, AA->getModRefInfo(Call1, Call2, AAQI));
2987330f729Sjoerg
2997330f729Sjoerg // Early-exit the moment we reach the bottom of the lattice.
3007330f729Sjoerg if (isNoModRef(Result))
3017330f729Sjoerg return ModRefInfo::NoModRef;
3027330f729Sjoerg }
3037330f729Sjoerg
3047330f729Sjoerg // Try to refine the mod-ref info further using other API entry points to the
3057330f729Sjoerg // aggregate set of AA results.
3067330f729Sjoerg
3077330f729Sjoerg // If Call1 or Call2 are readnone, they don't interact.
3087330f729Sjoerg auto Call1B = getModRefBehavior(Call1);
3097330f729Sjoerg if (Call1B == FMRB_DoesNotAccessMemory)
3107330f729Sjoerg return ModRefInfo::NoModRef;
3117330f729Sjoerg
3127330f729Sjoerg auto Call2B = getModRefBehavior(Call2);
3137330f729Sjoerg if (Call2B == FMRB_DoesNotAccessMemory)
3147330f729Sjoerg return ModRefInfo::NoModRef;
3157330f729Sjoerg
3167330f729Sjoerg // If they both only read from memory, there is no dependence.
3177330f729Sjoerg if (onlyReadsMemory(Call1B) && onlyReadsMemory(Call2B))
3187330f729Sjoerg return ModRefInfo::NoModRef;
3197330f729Sjoerg
3207330f729Sjoerg // If Call1 only reads memory, the only dependence on Call2 can be
3217330f729Sjoerg // from Call1 reading memory written by Call2.
3227330f729Sjoerg if (onlyReadsMemory(Call1B))
3237330f729Sjoerg Result = clearMod(Result);
3247330f729Sjoerg else if (doesNotReadMemory(Call1B))
3257330f729Sjoerg Result = clearRef(Result);
3267330f729Sjoerg
3277330f729Sjoerg // If Call2 only access memory through arguments, accumulate the mod/ref
3287330f729Sjoerg // information from Call1's references to the memory referenced by
3297330f729Sjoerg // Call2's arguments.
3307330f729Sjoerg if (onlyAccessesArgPointees(Call2B)) {
3317330f729Sjoerg if (!doesAccessArgPointees(Call2B))
3327330f729Sjoerg return ModRefInfo::NoModRef;
3337330f729Sjoerg ModRefInfo R = ModRefInfo::NoModRef;
3347330f729Sjoerg bool IsMustAlias = true;
3357330f729Sjoerg for (auto I = Call2->arg_begin(), E = Call2->arg_end(); I != E; ++I) {
3367330f729Sjoerg const Value *Arg = *I;
3377330f729Sjoerg if (!Arg->getType()->isPointerTy())
3387330f729Sjoerg continue;
3397330f729Sjoerg unsigned Call2ArgIdx = std::distance(Call2->arg_begin(), I);
3407330f729Sjoerg auto Call2ArgLoc =
3417330f729Sjoerg MemoryLocation::getForArgument(Call2, Call2ArgIdx, TLI);
3427330f729Sjoerg
3437330f729Sjoerg // ArgModRefC2 indicates what Call2 might do to Call2ArgLoc, and the
3447330f729Sjoerg // dependence of Call1 on that location is the inverse:
3457330f729Sjoerg // - If Call2 modifies location, dependence exists if Call1 reads or
3467330f729Sjoerg // writes.
3477330f729Sjoerg // - If Call2 only reads location, dependence exists if Call1 writes.
3487330f729Sjoerg ModRefInfo ArgModRefC2 = getArgModRefInfo(Call2, Call2ArgIdx);
3497330f729Sjoerg ModRefInfo ArgMask = ModRefInfo::NoModRef;
3507330f729Sjoerg if (isModSet(ArgModRefC2))
3517330f729Sjoerg ArgMask = ModRefInfo::ModRef;
3527330f729Sjoerg else if (isRefSet(ArgModRefC2))
3537330f729Sjoerg ArgMask = ModRefInfo::Mod;
3547330f729Sjoerg
3557330f729Sjoerg // ModRefC1 indicates what Call1 might do to Call2ArgLoc, and we use
3567330f729Sjoerg // above ArgMask to update dependence info.
357*82d56013Sjoerg ModRefInfo ModRefC1 = getModRefInfo(Call1, Call2ArgLoc, AAQI);
3587330f729Sjoerg ArgMask = intersectModRef(ArgMask, ModRefC1);
3597330f729Sjoerg
3607330f729Sjoerg // Conservatively clear IsMustAlias unless only MustAlias is found.
3617330f729Sjoerg IsMustAlias &= isMustSet(ModRefC1);
3627330f729Sjoerg
3637330f729Sjoerg R = intersectModRef(unionModRef(R, ArgMask), Result);
3647330f729Sjoerg if (R == Result) {
3657330f729Sjoerg // On early exit, not all args were checked, cannot set Must.
3667330f729Sjoerg if (I + 1 != E)
3677330f729Sjoerg IsMustAlias = false;
3687330f729Sjoerg break;
3697330f729Sjoerg }
3707330f729Sjoerg }
3717330f729Sjoerg
3727330f729Sjoerg if (isNoModRef(R))
3737330f729Sjoerg return ModRefInfo::NoModRef;
3747330f729Sjoerg
3757330f729Sjoerg // If MustAlias found above, set Must bit.
3767330f729Sjoerg return IsMustAlias ? setMust(R) : clearMust(R);
3777330f729Sjoerg }
3787330f729Sjoerg
3797330f729Sjoerg // If Call1 only accesses memory through arguments, check if Call2 references
3807330f729Sjoerg // any of the memory referenced by Call1's arguments. If not, return NoModRef.
3817330f729Sjoerg if (onlyAccessesArgPointees(Call1B)) {
3827330f729Sjoerg if (!doesAccessArgPointees(Call1B))
3837330f729Sjoerg return ModRefInfo::NoModRef;
3847330f729Sjoerg ModRefInfo R = ModRefInfo::NoModRef;
3857330f729Sjoerg bool IsMustAlias = true;
3867330f729Sjoerg for (auto I = Call1->arg_begin(), E = Call1->arg_end(); I != E; ++I) {
3877330f729Sjoerg const Value *Arg = *I;
3887330f729Sjoerg if (!Arg->getType()->isPointerTy())
3897330f729Sjoerg continue;
3907330f729Sjoerg unsigned Call1ArgIdx = std::distance(Call1->arg_begin(), I);
3917330f729Sjoerg auto Call1ArgLoc =
3927330f729Sjoerg MemoryLocation::getForArgument(Call1, Call1ArgIdx, TLI);
3937330f729Sjoerg
3947330f729Sjoerg // ArgModRefC1 indicates what Call1 might do to Call1ArgLoc; if Call1
3957330f729Sjoerg // might Mod Call1ArgLoc, then we care about either a Mod or a Ref by
3967330f729Sjoerg // Call2. If Call1 might Ref, then we care only about a Mod by Call2.
3977330f729Sjoerg ModRefInfo ArgModRefC1 = getArgModRefInfo(Call1, Call1ArgIdx);
398*82d56013Sjoerg ModRefInfo ModRefC2 = getModRefInfo(Call2, Call1ArgLoc, AAQI);
3997330f729Sjoerg if ((isModSet(ArgModRefC1) && isModOrRefSet(ModRefC2)) ||
4007330f729Sjoerg (isRefSet(ArgModRefC1) && isModSet(ModRefC2)))
4017330f729Sjoerg R = intersectModRef(unionModRef(R, ArgModRefC1), Result);
4027330f729Sjoerg
4037330f729Sjoerg // Conservatively clear IsMustAlias unless only MustAlias is found.
4047330f729Sjoerg IsMustAlias &= isMustSet(ModRefC2);
4057330f729Sjoerg
4067330f729Sjoerg if (R == Result) {
4077330f729Sjoerg // On early exit, not all args were checked, cannot set Must.
4087330f729Sjoerg if (I + 1 != E)
4097330f729Sjoerg IsMustAlias = false;
4107330f729Sjoerg break;
4117330f729Sjoerg }
4127330f729Sjoerg }
4137330f729Sjoerg
4147330f729Sjoerg if (isNoModRef(R))
4157330f729Sjoerg return ModRefInfo::NoModRef;
4167330f729Sjoerg
4177330f729Sjoerg // If MustAlias found above, set Must bit.
4187330f729Sjoerg return IsMustAlias ? setMust(R) : clearMust(R);
4197330f729Sjoerg }
4207330f729Sjoerg
4217330f729Sjoerg return Result;
4227330f729Sjoerg }
4237330f729Sjoerg
getModRefBehavior(const CallBase * Call)4247330f729Sjoerg FunctionModRefBehavior AAResults::getModRefBehavior(const CallBase *Call) {
4257330f729Sjoerg FunctionModRefBehavior Result = FMRB_UnknownModRefBehavior;
4267330f729Sjoerg
4277330f729Sjoerg for (const auto &AA : AAs) {
4287330f729Sjoerg Result = FunctionModRefBehavior(Result & AA->getModRefBehavior(Call));
4297330f729Sjoerg
4307330f729Sjoerg // Early-exit the moment we reach the bottom of the lattice.
4317330f729Sjoerg if (Result == FMRB_DoesNotAccessMemory)
4327330f729Sjoerg return Result;
4337330f729Sjoerg }
4347330f729Sjoerg
4357330f729Sjoerg return Result;
4367330f729Sjoerg }
4377330f729Sjoerg
getModRefBehavior(const Function * F)4387330f729Sjoerg FunctionModRefBehavior AAResults::getModRefBehavior(const Function *F) {
4397330f729Sjoerg FunctionModRefBehavior Result = FMRB_UnknownModRefBehavior;
4407330f729Sjoerg
4417330f729Sjoerg for (const auto &AA : AAs) {
4427330f729Sjoerg Result = FunctionModRefBehavior(Result & AA->getModRefBehavior(F));
4437330f729Sjoerg
4447330f729Sjoerg // Early-exit the moment we reach the bottom of the lattice.
4457330f729Sjoerg if (Result == FMRB_DoesNotAccessMemory)
4467330f729Sjoerg return Result;
4477330f729Sjoerg }
4487330f729Sjoerg
4497330f729Sjoerg return Result;
4507330f729Sjoerg }
4517330f729Sjoerg
operator <<(raw_ostream & OS,AliasResult AR)4527330f729Sjoerg raw_ostream &llvm::operator<<(raw_ostream &OS, AliasResult AR) {
4537330f729Sjoerg switch (AR) {
454*82d56013Sjoerg case AliasResult::NoAlias:
4557330f729Sjoerg OS << "NoAlias";
4567330f729Sjoerg break;
457*82d56013Sjoerg case AliasResult::MustAlias:
4587330f729Sjoerg OS << "MustAlias";
4597330f729Sjoerg break;
460*82d56013Sjoerg case AliasResult::MayAlias:
4617330f729Sjoerg OS << "MayAlias";
4627330f729Sjoerg break;
463*82d56013Sjoerg case AliasResult::PartialAlias:
4647330f729Sjoerg OS << "PartialAlias";
465*82d56013Sjoerg if (AR.hasOffset())
466*82d56013Sjoerg OS << " (off " << AR.getOffset() << ")";
4677330f729Sjoerg break;
4687330f729Sjoerg }
4697330f729Sjoerg return OS;
4707330f729Sjoerg }
4717330f729Sjoerg
4727330f729Sjoerg //===----------------------------------------------------------------------===//
4737330f729Sjoerg // Helper method implementation
4747330f729Sjoerg //===----------------------------------------------------------------------===//
4757330f729Sjoerg
getModRefInfo(const LoadInst * L,const MemoryLocation & Loc)4767330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const LoadInst *L,
4777330f729Sjoerg const MemoryLocation &Loc) {
4787330f729Sjoerg AAQueryInfo AAQIP;
4797330f729Sjoerg return getModRefInfo(L, Loc, AAQIP);
4807330f729Sjoerg }
getModRefInfo(const LoadInst * L,const MemoryLocation & Loc,AAQueryInfo & AAQI)4817330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const LoadInst *L,
4827330f729Sjoerg const MemoryLocation &Loc,
4837330f729Sjoerg AAQueryInfo &AAQI) {
4847330f729Sjoerg // Be conservative in the face of atomic.
4857330f729Sjoerg if (isStrongerThan(L->getOrdering(), AtomicOrdering::Unordered))
4867330f729Sjoerg return ModRefInfo::ModRef;
4877330f729Sjoerg
4887330f729Sjoerg // If the load address doesn't alias the given address, it doesn't read
4897330f729Sjoerg // or write the specified memory.
4907330f729Sjoerg if (Loc.Ptr) {
4917330f729Sjoerg AliasResult AR = alias(MemoryLocation::get(L), Loc, AAQI);
492*82d56013Sjoerg if (AR == AliasResult::NoAlias)
4937330f729Sjoerg return ModRefInfo::NoModRef;
494*82d56013Sjoerg if (AR == AliasResult::MustAlias)
4957330f729Sjoerg return ModRefInfo::MustRef;
4967330f729Sjoerg }
4977330f729Sjoerg // Otherwise, a load just reads.
4987330f729Sjoerg return ModRefInfo::Ref;
4997330f729Sjoerg }
5007330f729Sjoerg
getModRefInfo(const StoreInst * S,const MemoryLocation & Loc)5017330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const StoreInst *S,
5027330f729Sjoerg const MemoryLocation &Loc) {
5037330f729Sjoerg AAQueryInfo AAQIP;
5047330f729Sjoerg return getModRefInfo(S, Loc, AAQIP);
5057330f729Sjoerg }
getModRefInfo(const StoreInst * S,const MemoryLocation & Loc,AAQueryInfo & AAQI)5067330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const StoreInst *S,
5077330f729Sjoerg const MemoryLocation &Loc,
5087330f729Sjoerg AAQueryInfo &AAQI) {
5097330f729Sjoerg // Be conservative in the face of atomic.
5107330f729Sjoerg if (isStrongerThan(S->getOrdering(), AtomicOrdering::Unordered))
5117330f729Sjoerg return ModRefInfo::ModRef;
5127330f729Sjoerg
5137330f729Sjoerg if (Loc.Ptr) {
5147330f729Sjoerg AliasResult AR = alias(MemoryLocation::get(S), Loc, AAQI);
5157330f729Sjoerg // If the store address cannot alias the pointer in question, then the
5167330f729Sjoerg // specified memory cannot be modified by the store.
517*82d56013Sjoerg if (AR == AliasResult::NoAlias)
5187330f729Sjoerg return ModRefInfo::NoModRef;
5197330f729Sjoerg
5207330f729Sjoerg // If the pointer is a pointer to constant memory, then it could not have
5217330f729Sjoerg // been modified by this store.
5227330f729Sjoerg if (pointsToConstantMemory(Loc, AAQI))
5237330f729Sjoerg return ModRefInfo::NoModRef;
5247330f729Sjoerg
5257330f729Sjoerg // If the store address aliases the pointer as must alias, set Must.
526*82d56013Sjoerg if (AR == AliasResult::MustAlias)
5277330f729Sjoerg return ModRefInfo::MustMod;
5287330f729Sjoerg }
5297330f729Sjoerg
5307330f729Sjoerg // Otherwise, a store just writes.
5317330f729Sjoerg return ModRefInfo::Mod;
5327330f729Sjoerg }
5337330f729Sjoerg
getModRefInfo(const FenceInst * S,const MemoryLocation & Loc)5347330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const FenceInst *S, const MemoryLocation &Loc) {
5357330f729Sjoerg AAQueryInfo AAQIP;
5367330f729Sjoerg return getModRefInfo(S, Loc, AAQIP);
5377330f729Sjoerg }
5387330f729Sjoerg
getModRefInfo(const FenceInst * S,const MemoryLocation & Loc,AAQueryInfo & AAQI)5397330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const FenceInst *S,
5407330f729Sjoerg const MemoryLocation &Loc,
5417330f729Sjoerg AAQueryInfo &AAQI) {
5427330f729Sjoerg // If we know that the location is a constant memory location, the fence
5437330f729Sjoerg // cannot modify this location.
5447330f729Sjoerg if (Loc.Ptr && pointsToConstantMemory(Loc, AAQI))
5457330f729Sjoerg return ModRefInfo::Ref;
5467330f729Sjoerg return ModRefInfo::ModRef;
5477330f729Sjoerg }
5487330f729Sjoerg
getModRefInfo(const VAArgInst * V,const MemoryLocation & Loc)5497330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const VAArgInst *V,
5507330f729Sjoerg const MemoryLocation &Loc) {
5517330f729Sjoerg AAQueryInfo AAQIP;
5527330f729Sjoerg return getModRefInfo(V, Loc, AAQIP);
5537330f729Sjoerg }
5547330f729Sjoerg
getModRefInfo(const VAArgInst * V,const MemoryLocation & Loc,AAQueryInfo & AAQI)5557330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const VAArgInst *V,
5567330f729Sjoerg const MemoryLocation &Loc,
5577330f729Sjoerg AAQueryInfo &AAQI) {
5587330f729Sjoerg if (Loc.Ptr) {
5597330f729Sjoerg AliasResult AR = alias(MemoryLocation::get(V), Loc, AAQI);
5607330f729Sjoerg // If the va_arg address cannot alias the pointer in question, then the
5617330f729Sjoerg // specified memory cannot be accessed by the va_arg.
562*82d56013Sjoerg if (AR == AliasResult::NoAlias)
5637330f729Sjoerg return ModRefInfo::NoModRef;
5647330f729Sjoerg
5657330f729Sjoerg // If the pointer is a pointer to constant memory, then it could not have
5667330f729Sjoerg // been modified by this va_arg.
5677330f729Sjoerg if (pointsToConstantMemory(Loc, AAQI))
5687330f729Sjoerg return ModRefInfo::NoModRef;
5697330f729Sjoerg
5707330f729Sjoerg // If the va_arg aliases the pointer as must alias, set Must.
571*82d56013Sjoerg if (AR == AliasResult::MustAlias)
5727330f729Sjoerg return ModRefInfo::MustModRef;
5737330f729Sjoerg }
5747330f729Sjoerg
5757330f729Sjoerg // Otherwise, a va_arg reads and writes.
5767330f729Sjoerg return ModRefInfo::ModRef;
5777330f729Sjoerg }
5787330f729Sjoerg
getModRefInfo(const CatchPadInst * CatchPad,const MemoryLocation & Loc)5797330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const CatchPadInst *CatchPad,
5807330f729Sjoerg const MemoryLocation &Loc) {
5817330f729Sjoerg AAQueryInfo AAQIP;
5827330f729Sjoerg return getModRefInfo(CatchPad, Loc, AAQIP);
5837330f729Sjoerg }
5847330f729Sjoerg
getModRefInfo(const CatchPadInst * CatchPad,const MemoryLocation & Loc,AAQueryInfo & AAQI)5857330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const CatchPadInst *CatchPad,
5867330f729Sjoerg const MemoryLocation &Loc,
5877330f729Sjoerg AAQueryInfo &AAQI) {
5887330f729Sjoerg if (Loc.Ptr) {
5897330f729Sjoerg // If the pointer is a pointer to constant memory,
5907330f729Sjoerg // then it could not have been modified by this catchpad.
5917330f729Sjoerg if (pointsToConstantMemory(Loc, AAQI))
5927330f729Sjoerg return ModRefInfo::NoModRef;
5937330f729Sjoerg }
5947330f729Sjoerg
5957330f729Sjoerg // Otherwise, a catchpad reads and writes.
5967330f729Sjoerg return ModRefInfo::ModRef;
5977330f729Sjoerg }
5987330f729Sjoerg
getModRefInfo(const CatchReturnInst * CatchRet,const MemoryLocation & Loc)5997330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const CatchReturnInst *CatchRet,
6007330f729Sjoerg const MemoryLocation &Loc) {
6017330f729Sjoerg AAQueryInfo AAQIP;
6027330f729Sjoerg return getModRefInfo(CatchRet, Loc, AAQIP);
6037330f729Sjoerg }
6047330f729Sjoerg
getModRefInfo(const CatchReturnInst * CatchRet,const MemoryLocation & Loc,AAQueryInfo & AAQI)6057330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const CatchReturnInst *CatchRet,
6067330f729Sjoerg const MemoryLocation &Loc,
6077330f729Sjoerg AAQueryInfo &AAQI) {
6087330f729Sjoerg if (Loc.Ptr) {
6097330f729Sjoerg // If the pointer is a pointer to constant memory,
6107330f729Sjoerg // then it could not have been modified by this catchpad.
6117330f729Sjoerg if (pointsToConstantMemory(Loc, AAQI))
6127330f729Sjoerg return ModRefInfo::NoModRef;
6137330f729Sjoerg }
6147330f729Sjoerg
6157330f729Sjoerg // Otherwise, a catchret reads and writes.
6167330f729Sjoerg return ModRefInfo::ModRef;
6177330f729Sjoerg }
6187330f729Sjoerg
getModRefInfo(const AtomicCmpXchgInst * CX,const MemoryLocation & Loc)6197330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const AtomicCmpXchgInst *CX,
6207330f729Sjoerg const MemoryLocation &Loc) {
6217330f729Sjoerg AAQueryInfo AAQIP;
6227330f729Sjoerg return getModRefInfo(CX, Loc, AAQIP);
6237330f729Sjoerg }
6247330f729Sjoerg
getModRefInfo(const AtomicCmpXchgInst * CX,const MemoryLocation & Loc,AAQueryInfo & AAQI)6257330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const AtomicCmpXchgInst *CX,
6267330f729Sjoerg const MemoryLocation &Loc,
6277330f729Sjoerg AAQueryInfo &AAQI) {
6287330f729Sjoerg // Acquire/Release cmpxchg has properties that matter for arbitrary addresses.
6297330f729Sjoerg if (isStrongerThanMonotonic(CX->getSuccessOrdering()))
6307330f729Sjoerg return ModRefInfo::ModRef;
6317330f729Sjoerg
6327330f729Sjoerg if (Loc.Ptr) {
6337330f729Sjoerg AliasResult AR = alias(MemoryLocation::get(CX), Loc, AAQI);
6347330f729Sjoerg // If the cmpxchg address does not alias the location, it does not access
6357330f729Sjoerg // it.
636*82d56013Sjoerg if (AR == AliasResult::NoAlias)
6377330f729Sjoerg return ModRefInfo::NoModRef;
6387330f729Sjoerg
6397330f729Sjoerg // If the cmpxchg address aliases the pointer as must alias, set Must.
640*82d56013Sjoerg if (AR == AliasResult::MustAlias)
6417330f729Sjoerg return ModRefInfo::MustModRef;
6427330f729Sjoerg }
6437330f729Sjoerg
6447330f729Sjoerg return ModRefInfo::ModRef;
6457330f729Sjoerg }
6467330f729Sjoerg
getModRefInfo(const AtomicRMWInst * RMW,const MemoryLocation & Loc)6477330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW,
6487330f729Sjoerg const MemoryLocation &Loc) {
6497330f729Sjoerg AAQueryInfo AAQIP;
6507330f729Sjoerg return getModRefInfo(RMW, Loc, AAQIP);
6517330f729Sjoerg }
6527330f729Sjoerg
getModRefInfo(const AtomicRMWInst * RMW,const MemoryLocation & Loc,AAQueryInfo & AAQI)6537330f729Sjoerg ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW,
6547330f729Sjoerg const MemoryLocation &Loc,
6557330f729Sjoerg AAQueryInfo &AAQI) {
6567330f729Sjoerg // Acquire/Release atomicrmw has properties that matter for arbitrary addresses.
6577330f729Sjoerg if (isStrongerThanMonotonic(RMW->getOrdering()))
6587330f729Sjoerg return ModRefInfo::ModRef;
6597330f729Sjoerg
6607330f729Sjoerg if (Loc.Ptr) {
6617330f729Sjoerg AliasResult AR = alias(MemoryLocation::get(RMW), Loc, AAQI);
6627330f729Sjoerg // If the atomicrmw address does not alias the location, it does not access
6637330f729Sjoerg // it.
664*82d56013Sjoerg if (AR == AliasResult::NoAlias)
6657330f729Sjoerg return ModRefInfo::NoModRef;
6667330f729Sjoerg
6677330f729Sjoerg // If the atomicrmw address aliases the pointer as must alias, set Must.
668*82d56013Sjoerg if (AR == AliasResult::MustAlias)
6697330f729Sjoerg return ModRefInfo::MustModRef;
6707330f729Sjoerg }
6717330f729Sjoerg
6727330f729Sjoerg return ModRefInfo::ModRef;
6737330f729Sjoerg }
6747330f729Sjoerg
getModRefInfo(const Instruction * I,const Optional<MemoryLocation> & OptLoc,AAQueryInfo & AAQIP)675*82d56013Sjoerg ModRefInfo AAResults::getModRefInfo(const Instruction *I,
676*82d56013Sjoerg const Optional<MemoryLocation> &OptLoc,
677*82d56013Sjoerg AAQueryInfo &AAQIP) {
678*82d56013Sjoerg if (OptLoc == None) {
679*82d56013Sjoerg if (const auto *Call = dyn_cast<CallBase>(I)) {
680*82d56013Sjoerg return createModRefInfo(getModRefBehavior(Call));
681*82d56013Sjoerg }
682*82d56013Sjoerg }
683*82d56013Sjoerg
684*82d56013Sjoerg const MemoryLocation &Loc = OptLoc.getValueOr(MemoryLocation());
685*82d56013Sjoerg
686*82d56013Sjoerg switch (I->getOpcode()) {
687*82d56013Sjoerg case Instruction::VAArg:
688*82d56013Sjoerg return getModRefInfo((const VAArgInst *)I, Loc, AAQIP);
689*82d56013Sjoerg case Instruction::Load:
690*82d56013Sjoerg return getModRefInfo((const LoadInst *)I, Loc, AAQIP);
691*82d56013Sjoerg case Instruction::Store:
692*82d56013Sjoerg return getModRefInfo((const StoreInst *)I, Loc, AAQIP);
693*82d56013Sjoerg case Instruction::Fence:
694*82d56013Sjoerg return getModRefInfo((const FenceInst *)I, Loc, AAQIP);
695*82d56013Sjoerg case Instruction::AtomicCmpXchg:
696*82d56013Sjoerg return getModRefInfo((const AtomicCmpXchgInst *)I, Loc, AAQIP);
697*82d56013Sjoerg case Instruction::AtomicRMW:
698*82d56013Sjoerg return getModRefInfo((const AtomicRMWInst *)I, Loc, AAQIP);
699*82d56013Sjoerg case Instruction::Call:
700*82d56013Sjoerg return getModRefInfo((const CallInst *)I, Loc, AAQIP);
701*82d56013Sjoerg case Instruction::Invoke:
702*82d56013Sjoerg return getModRefInfo((const InvokeInst *)I, Loc, AAQIP);
703*82d56013Sjoerg case Instruction::CatchPad:
704*82d56013Sjoerg return getModRefInfo((const CatchPadInst *)I, Loc, AAQIP);
705*82d56013Sjoerg case Instruction::CatchRet:
706*82d56013Sjoerg return getModRefInfo((const CatchReturnInst *)I, Loc, AAQIP);
707*82d56013Sjoerg default:
708*82d56013Sjoerg return ModRefInfo::NoModRef;
709*82d56013Sjoerg }
710*82d56013Sjoerg }
711*82d56013Sjoerg
7127330f729Sjoerg /// Return information about whether a particular call site modifies
7137330f729Sjoerg /// or reads the specified memory location \p MemLoc before instruction \p I
714*82d56013Sjoerg /// in a BasicBlock.
7157330f729Sjoerg /// FIXME: this is really just shoring-up a deficiency in alias analysis.
7167330f729Sjoerg /// BasicAA isn't willing to spend linear time determining whether an alloca
7177330f729Sjoerg /// was captured before or after this particular call, while we are. However,
7187330f729Sjoerg /// with a smarter AA in place, this test is just wasting compile time.
callCapturesBefore(const Instruction * I,const MemoryLocation & MemLoc,DominatorTree * DT,AAQueryInfo & AAQI)7197330f729Sjoerg ModRefInfo AAResults::callCapturesBefore(const Instruction *I,
7207330f729Sjoerg const MemoryLocation &MemLoc,
7217330f729Sjoerg DominatorTree *DT,
722*82d56013Sjoerg AAQueryInfo &AAQI) {
7237330f729Sjoerg if (!DT)
7247330f729Sjoerg return ModRefInfo::ModRef;
7257330f729Sjoerg
726*82d56013Sjoerg const Value *Object = getUnderlyingObject(MemLoc.Ptr);
727*82d56013Sjoerg if (!isIdentifiedFunctionLocal(Object))
7287330f729Sjoerg return ModRefInfo::ModRef;
7297330f729Sjoerg
7307330f729Sjoerg const auto *Call = dyn_cast<CallBase>(I);
7317330f729Sjoerg if (!Call || Call == Object)
7327330f729Sjoerg return ModRefInfo::ModRef;
7337330f729Sjoerg
7347330f729Sjoerg if (PointerMayBeCapturedBefore(Object, /* ReturnCaptures */ true,
7357330f729Sjoerg /* StoreCaptures */ true, I, DT,
736*82d56013Sjoerg /* include Object */ true))
7377330f729Sjoerg return ModRefInfo::ModRef;
7387330f729Sjoerg
7397330f729Sjoerg unsigned ArgNo = 0;
7407330f729Sjoerg ModRefInfo R = ModRefInfo::NoModRef;
7417330f729Sjoerg bool IsMustAlias = true;
7427330f729Sjoerg // Set flag only if no May found and all operands processed.
7437330f729Sjoerg for (auto CI = Call->data_operands_begin(), CE = Call->data_operands_end();
7447330f729Sjoerg CI != CE; ++CI, ++ArgNo) {
7457330f729Sjoerg // Only look at the no-capture or byval pointer arguments. If this
7467330f729Sjoerg // pointer were passed to arguments that were neither of these, then it
7477330f729Sjoerg // couldn't be no-capture.
7487330f729Sjoerg if (!(*CI)->getType()->isPointerTy() ||
7497330f729Sjoerg (!Call->doesNotCapture(ArgNo) && ArgNo < Call->getNumArgOperands() &&
7507330f729Sjoerg !Call->isByValArgument(ArgNo)))
7517330f729Sjoerg continue;
7527330f729Sjoerg
753*82d56013Sjoerg AliasResult AR = alias(
754*82d56013Sjoerg MemoryLocation::getBeforeOrAfter(*CI),
755*82d56013Sjoerg MemoryLocation::getBeforeOrAfter(Object), AAQI);
7567330f729Sjoerg // If this is a no-capture pointer argument, see if we can tell that it
7577330f729Sjoerg // is impossible to alias the pointer we're checking. If not, we have to
7587330f729Sjoerg // assume that the call could touch the pointer, even though it doesn't
7597330f729Sjoerg // escape.
760*82d56013Sjoerg if (AR != AliasResult::MustAlias)
7617330f729Sjoerg IsMustAlias = false;
762*82d56013Sjoerg if (AR == AliasResult::NoAlias)
7637330f729Sjoerg continue;
7647330f729Sjoerg if (Call->doesNotAccessMemory(ArgNo))
7657330f729Sjoerg continue;
7667330f729Sjoerg if (Call->onlyReadsMemory(ArgNo)) {
7677330f729Sjoerg R = ModRefInfo::Ref;
7687330f729Sjoerg continue;
7697330f729Sjoerg }
7707330f729Sjoerg // Not returning MustModRef since we have not seen all the arguments.
7717330f729Sjoerg return ModRefInfo::ModRef;
7727330f729Sjoerg }
7737330f729Sjoerg return IsMustAlias ? setMust(R) : clearMust(R);
7747330f729Sjoerg }
7757330f729Sjoerg
7767330f729Sjoerg /// canBasicBlockModify - Return true if it is possible for execution of the
7777330f729Sjoerg /// specified basic block to modify the location Loc.
7787330f729Sjoerg ///
canBasicBlockModify(const BasicBlock & BB,const MemoryLocation & Loc)7797330f729Sjoerg bool AAResults::canBasicBlockModify(const BasicBlock &BB,
7807330f729Sjoerg const MemoryLocation &Loc) {
7817330f729Sjoerg return canInstructionRangeModRef(BB.front(), BB.back(), Loc, ModRefInfo::Mod);
7827330f729Sjoerg }
7837330f729Sjoerg
7847330f729Sjoerg /// canInstructionRangeModRef - Return true if it is possible for the
7857330f729Sjoerg /// execution of the specified instructions to mod\ref (according to the
7867330f729Sjoerg /// mode) the location Loc. The instructions to consider are all
7877330f729Sjoerg /// of the instructions in the range of [I1,I2] INCLUSIVE.
7887330f729Sjoerg /// I1 and I2 must be in the same basic block.
canInstructionRangeModRef(const Instruction & I1,const Instruction & I2,const MemoryLocation & Loc,const ModRefInfo Mode)7897330f729Sjoerg bool AAResults::canInstructionRangeModRef(const Instruction &I1,
7907330f729Sjoerg const Instruction &I2,
7917330f729Sjoerg const MemoryLocation &Loc,
7927330f729Sjoerg const ModRefInfo Mode) {
7937330f729Sjoerg assert(I1.getParent() == I2.getParent() &&
7947330f729Sjoerg "Instructions not in same basic block!");
7957330f729Sjoerg BasicBlock::const_iterator I = I1.getIterator();
7967330f729Sjoerg BasicBlock::const_iterator E = I2.getIterator();
7977330f729Sjoerg ++E; // Convert from inclusive to exclusive range.
7987330f729Sjoerg
7997330f729Sjoerg for (; I != E; ++I) // Check every instruction in range
8007330f729Sjoerg if (isModOrRefSet(intersectModRef(getModRefInfo(&*I, Loc), Mode)))
8017330f729Sjoerg return true;
8027330f729Sjoerg return false;
8037330f729Sjoerg }
8047330f729Sjoerg
8057330f729Sjoerg // Provide a definition for the root virtual destructor.
8067330f729Sjoerg AAResults::Concept::~Concept() = default;
8077330f729Sjoerg
8087330f729Sjoerg // Provide a definition for the static object used to identify passes.
8097330f729Sjoerg AnalysisKey AAManager::Key;
8107330f729Sjoerg
8117330f729Sjoerg namespace {
8127330f729Sjoerg
8137330f729Sjoerg
8147330f729Sjoerg } // end anonymous namespace
8157330f729Sjoerg
ExternalAAWrapperPass()816*82d56013Sjoerg ExternalAAWrapperPass::ExternalAAWrapperPass() : ImmutablePass(ID) {
817*82d56013Sjoerg initializeExternalAAWrapperPassPass(*PassRegistry::getPassRegistry());
818*82d56013Sjoerg }
819*82d56013Sjoerg
ExternalAAWrapperPass(CallbackT CB)820*82d56013Sjoerg ExternalAAWrapperPass::ExternalAAWrapperPass(CallbackT CB)
821*82d56013Sjoerg : ImmutablePass(ID), CB(std::move(CB)) {
822*82d56013Sjoerg initializeExternalAAWrapperPassPass(*PassRegistry::getPassRegistry());
823*82d56013Sjoerg }
824*82d56013Sjoerg
8257330f729Sjoerg char ExternalAAWrapperPass::ID = 0;
8267330f729Sjoerg
8277330f729Sjoerg INITIALIZE_PASS(ExternalAAWrapperPass, "external-aa", "External Alias Analysis",
8287330f729Sjoerg false, true)
8297330f729Sjoerg
8307330f729Sjoerg ImmutablePass *
createExternalAAWrapperPass(ExternalAAWrapperPass::CallbackT Callback)8317330f729Sjoerg llvm::createExternalAAWrapperPass(ExternalAAWrapperPass::CallbackT Callback) {
8327330f729Sjoerg return new ExternalAAWrapperPass(std::move(Callback));
8337330f729Sjoerg }
8347330f729Sjoerg
AAResultsWrapperPass()8357330f729Sjoerg AAResultsWrapperPass::AAResultsWrapperPass() : FunctionPass(ID) {
8367330f729Sjoerg initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry());
8377330f729Sjoerg }
8387330f729Sjoerg
8397330f729Sjoerg char AAResultsWrapperPass::ID = 0;
8407330f729Sjoerg
8417330f729Sjoerg INITIALIZE_PASS_BEGIN(AAResultsWrapperPass, "aa",
8427330f729Sjoerg "Function Alias Analysis Results", false, true)
INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass)8437330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass)
8447330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(CFLAndersAAWrapperPass)
8457330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(CFLSteensAAWrapperPass)
8467330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(ExternalAAWrapperPass)
8477330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
8487330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(ObjCARCAAWrapperPass)
8497330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass)
8507330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(ScopedNoAliasAAWrapperPass)
8517330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(TypeBasedAAWrapperPass)
8527330f729Sjoerg INITIALIZE_PASS_END(AAResultsWrapperPass, "aa",
8537330f729Sjoerg "Function Alias Analysis Results", false, true)
8547330f729Sjoerg
8557330f729Sjoerg FunctionPass *llvm::createAAResultsWrapperPass() {
8567330f729Sjoerg return new AAResultsWrapperPass();
8577330f729Sjoerg }
8587330f729Sjoerg
8597330f729Sjoerg /// Run the wrapper pass to rebuild an aggregation over known AA passes.
8607330f729Sjoerg ///
8617330f729Sjoerg /// This is the legacy pass manager's interface to the new-style AA results
8627330f729Sjoerg /// aggregation object. Because this is somewhat shoe-horned into the legacy
8637330f729Sjoerg /// pass manager, we hard code all the specific alias analyses available into
8647330f729Sjoerg /// it. While the particular set enabled is configured via commandline flags,
8657330f729Sjoerg /// adding a new alias analysis to LLVM will require adding support for it to
8667330f729Sjoerg /// this list.
runOnFunction(Function & F)8677330f729Sjoerg bool AAResultsWrapperPass::runOnFunction(Function &F) {
8687330f729Sjoerg // NB! This *must* be reset before adding new AA results to the new
8697330f729Sjoerg // AAResults object because in the legacy pass manager, each instance
8707330f729Sjoerg // of these will refer to the *same* immutable analyses, registering and
8717330f729Sjoerg // unregistering themselves with them. We need to carefully tear down the
8727330f729Sjoerg // previous object first, in this case replacing it with an empty one, before
8737330f729Sjoerg // registering new results.
8747330f729Sjoerg AAR.reset(
8757330f729Sjoerg new AAResults(getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F)));
8767330f729Sjoerg
8777330f729Sjoerg // BasicAA is always available for function analyses. Also, we add it first
8787330f729Sjoerg // so that it can trump TBAA results when it proves MustAlias.
8797330f729Sjoerg // FIXME: TBAA should have an explicit mode to support this and then we
8807330f729Sjoerg // should reconsider the ordering here.
8817330f729Sjoerg if (!DisableBasicAA)
8827330f729Sjoerg AAR->addAAResult(getAnalysis<BasicAAWrapperPass>().getResult());
8837330f729Sjoerg
8847330f729Sjoerg // Populate the results with the currently available AAs.
8857330f729Sjoerg if (auto *WrapperPass = getAnalysisIfAvailable<ScopedNoAliasAAWrapperPass>())
8867330f729Sjoerg AAR->addAAResult(WrapperPass->getResult());
8877330f729Sjoerg if (auto *WrapperPass = getAnalysisIfAvailable<TypeBasedAAWrapperPass>())
8887330f729Sjoerg AAR->addAAResult(WrapperPass->getResult());
8897330f729Sjoerg if (auto *WrapperPass =
8907330f729Sjoerg getAnalysisIfAvailable<objcarc::ObjCARCAAWrapperPass>())
8917330f729Sjoerg AAR->addAAResult(WrapperPass->getResult());
8927330f729Sjoerg if (auto *WrapperPass = getAnalysisIfAvailable<GlobalsAAWrapperPass>())
8937330f729Sjoerg AAR->addAAResult(WrapperPass->getResult());
8947330f729Sjoerg if (auto *WrapperPass = getAnalysisIfAvailable<SCEVAAWrapperPass>())
8957330f729Sjoerg AAR->addAAResult(WrapperPass->getResult());
8967330f729Sjoerg if (auto *WrapperPass = getAnalysisIfAvailable<CFLAndersAAWrapperPass>())
8977330f729Sjoerg AAR->addAAResult(WrapperPass->getResult());
8987330f729Sjoerg if (auto *WrapperPass = getAnalysisIfAvailable<CFLSteensAAWrapperPass>())
8997330f729Sjoerg AAR->addAAResult(WrapperPass->getResult());
9007330f729Sjoerg
9017330f729Sjoerg // If available, run an external AA providing callback over the results as
9027330f729Sjoerg // well.
9037330f729Sjoerg if (auto *WrapperPass = getAnalysisIfAvailable<ExternalAAWrapperPass>())
9047330f729Sjoerg if (WrapperPass->CB)
9057330f729Sjoerg WrapperPass->CB(*this, F, *AAR);
9067330f729Sjoerg
9077330f729Sjoerg // Analyses don't mutate the IR, so return false.
9087330f729Sjoerg return false;
9097330f729Sjoerg }
9107330f729Sjoerg
getAnalysisUsage(AnalysisUsage & AU) const9117330f729Sjoerg void AAResultsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
9127330f729Sjoerg AU.setPreservesAll();
913*82d56013Sjoerg AU.addRequiredTransitive<BasicAAWrapperPass>();
914*82d56013Sjoerg AU.addRequiredTransitive<TargetLibraryInfoWrapperPass>();
9157330f729Sjoerg
9167330f729Sjoerg // We also need to mark all the alias analysis passes we will potentially
9177330f729Sjoerg // probe in runOnFunction as used here to ensure the legacy pass manager
9187330f729Sjoerg // preserves them. This hard coding of lists of alias analyses is specific to
9197330f729Sjoerg // the legacy pass manager.
9207330f729Sjoerg AU.addUsedIfAvailable<ScopedNoAliasAAWrapperPass>();
9217330f729Sjoerg AU.addUsedIfAvailable<TypeBasedAAWrapperPass>();
9227330f729Sjoerg AU.addUsedIfAvailable<objcarc::ObjCARCAAWrapperPass>();
9237330f729Sjoerg AU.addUsedIfAvailable<GlobalsAAWrapperPass>();
9247330f729Sjoerg AU.addUsedIfAvailable<SCEVAAWrapperPass>();
9257330f729Sjoerg AU.addUsedIfAvailable<CFLAndersAAWrapperPass>();
9267330f729Sjoerg AU.addUsedIfAvailable<CFLSteensAAWrapperPass>();
927*82d56013Sjoerg AU.addUsedIfAvailable<ExternalAAWrapperPass>();
928*82d56013Sjoerg }
929*82d56013Sjoerg
run(Function & F,FunctionAnalysisManager & AM)930*82d56013Sjoerg AAManager::Result AAManager::run(Function &F, FunctionAnalysisManager &AM) {
931*82d56013Sjoerg Result R(AM.getResult<TargetLibraryAnalysis>(F));
932*82d56013Sjoerg for (auto &Getter : ResultGetters)
933*82d56013Sjoerg (*Getter)(F, AM, R);
934*82d56013Sjoerg return R;
9357330f729Sjoerg }
9367330f729Sjoerg
createLegacyPMAAResults(Pass & P,Function & F,BasicAAResult & BAR)9377330f729Sjoerg AAResults llvm::createLegacyPMAAResults(Pass &P, Function &F,
9387330f729Sjoerg BasicAAResult &BAR) {
9397330f729Sjoerg AAResults AAR(P.getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F));
9407330f729Sjoerg
9417330f729Sjoerg // Add in our explicitly constructed BasicAA results.
9427330f729Sjoerg if (!DisableBasicAA)
9437330f729Sjoerg AAR.addAAResult(BAR);
9447330f729Sjoerg
9457330f729Sjoerg // Populate the results with the other currently available AAs.
9467330f729Sjoerg if (auto *WrapperPass =
9477330f729Sjoerg P.getAnalysisIfAvailable<ScopedNoAliasAAWrapperPass>())
9487330f729Sjoerg AAR.addAAResult(WrapperPass->getResult());
9497330f729Sjoerg if (auto *WrapperPass = P.getAnalysisIfAvailable<TypeBasedAAWrapperPass>())
9507330f729Sjoerg AAR.addAAResult(WrapperPass->getResult());
9517330f729Sjoerg if (auto *WrapperPass =
9527330f729Sjoerg P.getAnalysisIfAvailable<objcarc::ObjCARCAAWrapperPass>())
9537330f729Sjoerg AAR.addAAResult(WrapperPass->getResult());
9547330f729Sjoerg if (auto *WrapperPass = P.getAnalysisIfAvailable<GlobalsAAWrapperPass>())
9557330f729Sjoerg AAR.addAAResult(WrapperPass->getResult());
9567330f729Sjoerg if (auto *WrapperPass = P.getAnalysisIfAvailable<CFLAndersAAWrapperPass>())
9577330f729Sjoerg AAR.addAAResult(WrapperPass->getResult());
9587330f729Sjoerg if (auto *WrapperPass = P.getAnalysisIfAvailable<CFLSteensAAWrapperPass>())
9597330f729Sjoerg AAR.addAAResult(WrapperPass->getResult());
960*82d56013Sjoerg if (auto *WrapperPass = P.getAnalysisIfAvailable<ExternalAAWrapperPass>())
961*82d56013Sjoerg if (WrapperPass->CB)
962*82d56013Sjoerg WrapperPass->CB(P, F, AAR);
9637330f729Sjoerg
9647330f729Sjoerg return AAR;
9657330f729Sjoerg }
9667330f729Sjoerg
isNoAliasCall(const Value * V)9677330f729Sjoerg bool llvm::isNoAliasCall(const Value *V) {
9687330f729Sjoerg if (const auto *Call = dyn_cast<CallBase>(V))
9697330f729Sjoerg return Call->hasRetAttr(Attribute::NoAlias);
9707330f729Sjoerg return false;
9717330f729Sjoerg }
9727330f729Sjoerg
isNoAliasOrByValArgument(const Value * V)973*82d56013Sjoerg static bool isNoAliasOrByValArgument(const Value *V) {
9747330f729Sjoerg if (const Argument *A = dyn_cast<Argument>(V))
975*82d56013Sjoerg return A->hasNoAliasAttr() || A->hasByValAttr();
9767330f729Sjoerg return false;
9777330f729Sjoerg }
9787330f729Sjoerg
isIdentifiedObject(const Value * V)9797330f729Sjoerg bool llvm::isIdentifiedObject(const Value *V) {
9807330f729Sjoerg if (isa<AllocaInst>(V))
9817330f729Sjoerg return true;
9827330f729Sjoerg if (isa<GlobalValue>(V) && !isa<GlobalAlias>(V))
9837330f729Sjoerg return true;
9847330f729Sjoerg if (isNoAliasCall(V))
9857330f729Sjoerg return true;
986*82d56013Sjoerg if (isNoAliasOrByValArgument(V))
987*82d56013Sjoerg return true;
9887330f729Sjoerg return false;
9897330f729Sjoerg }
9907330f729Sjoerg
isIdentifiedFunctionLocal(const Value * V)9917330f729Sjoerg bool llvm::isIdentifiedFunctionLocal(const Value *V) {
992*82d56013Sjoerg return isa<AllocaInst>(V) || isNoAliasCall(V) || isNoAliasOrByValArgument(V);
9937330f729Sjoerg }
9947330f729Sjoerg
getAAResultsAnalysisUsage(AnalysisUsage & AU)9957330f729Sjoerg void llvm::getAAResultsAnalysisUsage(AnalysisUsage &AU) {
9967330f729Sjoerg // This function needs to be in sync with llvm::createLegacyPMAAResults -- if
9977330f729Sjoerg // more alias analyses are added to llvm::createLegacyPMAAResults, they need
9987330f729Sjoerg // to be added here also.
9997330f729Sjoerg AU.addRequired<TargetLibraryInfoWrapperPass>();
10007330f729Sjoerg AU.addUsedIfAvailable<ScopedNoAliasAAWrapperPass>();
10017330f729Sjoerg AU.addUsedIfAvailable<TypeBasedAAWrapperPass>();
10027330f729Sjoerg AU.addUsedIfAvailable<objcarc::ObjCARCAAWrapperPass>();
10037330f729Sjoerg AU.addUsedIfAvailable<GlobalsAAWrapperPass>();
10047330f729Sjoerg AU.addUsedIfAvailable<CFLAndersAAWrapperPass>();
10057330f729Sjoerg AU.addUsedIfAvailable<CFLSteensAAWrapperPass>();
1006*82d56013Sjoerg AU.addUsedIfAvailable<ExternalAAWrapperPass>();
10077330f729Sjoerg }
1008