diff options
Diffstat (limited to 'lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r-- | lib/Analysis/BasicAliasAnalysis.cpp | 155 |
1 files changed, 58 insertions, 97 deletions
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index a61faca2e54e..d11a748e4bf9 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -105,7 +105,7 @@ static uint64_t getObjectSize(const Value *V, const DataLayout &DL, uint64_t Size; if (getObjectSize(V, Size, DL, &TLI, RoundToAlign)) return Size; - return AliasAnalysis::UnknownSize; + return MemoryLocation::UnknownSize; } /// isObjectSmallerThan - Return true if we can prove that the object specified @@ -146,7 +146,7 @@ static bool isObjectSmallerThan(const Value *V, uint64_t Size, // reads a bit past the end given sufficient alignment. uint64_t ObjectSize = getObjectSize(V, DL, TLI, /*RoundToAlign*/true); - return ObjectSize != AliasAnalysis::UnknownSize && ObjectSize < Size; + return ObjectSize != MemoryLocation::UnknownSize && ObjectSize < Size; } /// isObjectSize - Return true if we can prove that the object specified @@ -154,7 +154,7 @@ static bool isObjectSmallerThan(const Value *V, uint64_t Size, static bool isObjectSize(const Value *V, uint64_t Size, const DataLayout &DL, const TargetLibraryInfo &TLI) { uint64_t ObjectSize = getObjectSize(V, DL, TLI); - return ObjectSize != AliasAnalysis::UnknownSize && ObjectSize == Size; + return ObjectSize != MemoryLocation::UnknownSize && ObjectSize == Size; } //===----------------------------------------------------------------------===// @@ -182,7 +182,7 @@ namespace { return !operator==(Other); } }; -} +} // namespace /// GetLinearExpression - Analyze the specified value as a linear expression: @@ -459,7 +459,8 @@ namespace { AU.addRequired<TargetLibraryInfoWrapperPass>(); } - AliasResult alias(const Location &LocA, const Location &LocB) override { + AliasResult alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) override { assert(AliasCache.empty() && "AliasCache must be cleared after use!"); assert(notDifferentParent(LocA.Ptr, LocB.Ptr) && "BasicAliasAnalysis doesn't support interprocedural queries."); @@ -475,18 +476,19 @@ namespace { } ModRefResult getModRefInfo(ImmutableCallSite CS, - const Location &Loc) override; + const MemoryLocation &Loc) override; ModRefResult getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) override; /// pointsToConstantMemory - Chase pointers until we find a (constant /// global) or not. - bool pointsToConstantMemory(const Location &Loc, bool OrLocal) override; + bool pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) override; /// Get the location associated with a pointer argument of a callsite. - Location getArgLocation(ImmutableCallSite CS, unsigned ArgIdx, - ModRefResult &Mask) override; + ModRefResult getArgModRefInfo(ImmutableCallSite CS, + unsigned ArgIdx) override; /// getModRefBehavior - Return the behavior when calling the given /// call site. @@ -508,7 +510,7 @@ namespace { private: // AliasCache - Track alias queries to guard against recursion. - typedef std::pair<Location, Location> LocPair; + typedef std::pair<MemoryLocation, MemoryLocation> LocPair; typedef SmallDenseMap<LocPair, AliasResult, 8> AliasCacheTy; AliasCacheTy AliasCache; @@ -592,8 +594,8 @@ ImmutablePass *llvm::createBasicAliasAnalysisPass() { /// pointsToConstantMemory - Returns whether the given pointer value /// points to memory that is local to the function, with global constants being /// considered local to all functions. -bool -BasicAliasAnalysis::pointsToConstantMemory(const Location &Loc, bool OrLocal) { +bool BasicAliasAnalysis::pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) { assert(Visited.empty() && "Visited must be cleared after use!"); unsigned MaxLookup = 8; @@ -652,6 +654,8 @@ BasicAliasAnalysis::pointsToConstantMemory(const Location &Loc, bool OrLocal) { return Worklist.empty(); } +// FIXME: This code is duplicated with MemoryLocation and should be hoisted to +// some common utility location. static bool isMemsetPattern16(const Function *MS, const TargetLibraryInfo &TLI) { if (TLI.has(LibFunc::memset_pattern16) && @@ -715,84 +719,33 @@ BasicAliasAnalysis::getModRefBehavior(const Function *F) { return ModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min); } -AliasAnalysis::Location -BasicAliasAnalysis::getArgLocation(ImmutableCallSite CS, unsigned ArgIdx, - ModRefResult &Mask) { - Location Loc = AliasAnalysis::getArgLocation(CS, ArgIdx, Mask); - const TargetLibraryInfo &TLI = - getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); - const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction()); - if (II != nullptr) +AliasAnalysis::ModRefResult +BasicAliasAnalysis::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) { + if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) switch (II->getIntrinsicID()) { - default: break; + default: + break; case Intrinsic::memset: case Intrinsic::memcpy: - case Intrinsic::memmove: { + case Intrinsic::memmove: assert((ArgIdx == 0 || ArgIdx == 1) && "Invalid argument index for memory intrinsic"); - if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2))) - Loc.Size = LenCI->getZExtValue(); - assert(Loc.Ptr == II->getArgOperand(ArgIdx) && - "Memory intrinsic location pointer not argument?"); - Mask = ArgIdx ? Ref : Mod; - break; - } - case Intrinsic::lifetime_start: - case Intrinsic::lifetime_end: - case Intrinsic::invariant_start: { - assert(ArgIdx == 1 && "Invalid argument index"); - assert(Loc.Ptr == II->getArgOperand(ArgIdx) && - "Intrinsic location pointer not argument?"); - Loc.Size = cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(); - break; - } - case Intrinsic::invariant_end: { - assert(ArgIdx == 2 && "Invalid argument index"); - assert(Loc.Ptr == II->getArgOperand(ArgIdx) && - "Intrinsic location pointer not argument?"); - Loc.Size = cast<ConstantInt>(II->getArgOperand(1))->getZExtValue(); - break; - } - case Intrinsic::arm_neon_vld1: { - assert(ArgIdx == 0 && "Invalid argument index"); - assert(Loc.Ptr == II->getArgOperand(ArgIdx) && - "Intrinsic location pointer not argument?"); - // LLVM's vld1 and vst1 intrinsics currently only support a single - // vector register. - if (DL) - Loc.Size = DL->getTypeStoreSize(II->getType()); - break; - } - case Intrinsic::arm_neon_vst1: { - assert(ArgIdx == 0 && "Invalid argument index"); - assert(Loc.Ptr == II->getArgOperand(ArgIdx) && - "Intrinsic location pointer not argument?"); - if (DL) - Loc.Size = DL->getTypeStoreSize(II->getArgOperand(1)->getType()); - break; - } + return ArgIdx ? Ref : Mod; } // We can bound the aliasing properties of memset_pattern16 just as we can // for memcpy/memset. This is particularly important because the // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 // whenever possible. - else if (CS.getCalledFunction() && - isMemsetPattern16(CS.getCalledFunction(), TLI)) { + if (CS.getCalledFunction() && + isMemsetPattern16(CS.getCalledFunction(), *TLI)) { assert((ArgIdx == 0 || ArgIdx == 1) && "Invalid argument index for memset_pattern16"); - if (ArgIdx == 1) - Loc.Size = 16; - else if (const ConstantInt *LenCI = - dyn_cast<ConstantInt>(CS.getArgument(2))) - Loc.Size = LenCI->getZExtValue(); - assert(Loc.Ptr == CS.getArgument(ArgIdx) && - "memset_pattern16 location pointer not argument?"); - Mask = ArgIdx ? Ref : Mod; + return ArgIdx ? Ref : Mod; } // FIXME: Handle memset_pattern4 and memset_pattern8 also. - return Loc; + return AliasAnalysis::getArgModRefInfo(CS, ArgIdx); } static bool isAssumeIntrinsic(ImmutableCallSite CS) { @@ -814,7 +767,7 @@ bool BasicAliasAnalysis::doInitialization(Module &M) { /// simple "address taken" analysis on local objects. AliasAnalysis::ModRefResult BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, - const Location &Loc) { + const MemoryLocation &Loc) { assert(notDifferentParent(CS.getInstruction(), Loc.Ptr) && "AliasAnalysis query involving multiple functions!"); @@ -850,7 +803,7 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, // is impossible to alias the pointer we're checking. If not, we have to // assume that the call could touch the pointer, even though it doesn't // escape. - if (!isNoAlias(Location(*CI), Location(Object))) { + if (!isNoAlias(MemoryLocation(*CI), MemoryLocation(Object))) { PassedAsArg = true; break; } @@ -902,8 +855,8 @@ aliasSameBasePointerGEPs(const GEPOperator *GEP1, uint64_t V1Size, // If we don't know the size of the accesses through both GEPs, we can't // determine whether the struct fields accessed can't alias. - if (V1Size == AliasAnalysis::UnknownSize || - V2Size == AliasAnalysis::UnknownSize) + if (V1Size == MemoryLocation::UnknownSize || + V2Size == MemoryLocation::UnknownSize) return AliasAnalysis::MayAlias; ConstantInt *C1 = @@ -1017,8 +970,9 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size, // derived pointer. if (const GEPOperator *GEP2 = dyn_cast<GEPOperator>(V2)) { // Do the base pointers alias? - AliasResult BaseAlias = aliasCheck(UnderlyingV1, UnknownSize, AAMDNodes(), - UnderlyingV2, UnknownSize, AAMDNodes()); + AliasResult BaseAlias = + aliasCheck(UnderlyingV1, MemoryLocation::UnknownSize, AAMDNodes(), + UnderlyingV2, MemoryLocation::UnknownSize, AAMDNodes()); // Check for geps of non-aliasing underlying pointers where the offsets are // identical. @@ -1109,11 +1063,12 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size, // pointer, we know they cannot alias. // If both accesses are unknown size, we can't do anything useful here. - if (V1Size == UnknownSize && V2Size == UnknownSize) + if (V1Size == MemoryLocation::UnknownSize && + V2Size == MemoryLocation::UnknownSize) return MayAlias; - AliasResult R = aliasCheck(UnderlyingV1, UnknownSize, AAMDNodes(), - V2, V2Size, V2AAInfo); + AliasResult R = aliasCheck(UnderlyingV1, MemoryLocation::UnknownSize, + AAMDNodes(), V2, V2Size, V2AAInfo); if (R != MustAlias) // If V2 may alias GEP base pointer, conservatively returns MayAlias. // If V2 is known not to alias GEP base pointer, then the two values @@ -1153,7 +1108,7 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size, // greater, we know they do not overlap. if (GEP1BaseOffset != 0 && GEP1VariableIndices.empty()) { if (GEP1BaseOffset >= 0) { - if (V2Size != UnknownSize) { + if (V2Size != MemoryLocation::UnknownSize) { if ((uint64_t)GEP1BaseOffset < V2Size) return PartialAlias; return NoAlias; @@ -1167,7 +1122,8 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size, // GEP1 V2 // We need to know that V2Size is not unknown, otherwise we might have // stripped a gep with negative index ('gep <ptr>, -1, ...). - if (V1Size != UnknownSize && V2Size != UnknownSize) { + if (V1Size != MemoryLocation::UnknownSize && + V2Size != MemoryLocation::UnknownSize) { if (-(uint64_t)GEP1BaseOffset < V1Size) return PartialAlias; return NoAlias; @@ -1218,8 +1174,9 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size, // mod Modulo. Check whether that difference guarantees that the // two locations do not alias. uint64_t ModOffset = (uint64_t)GEP1BaseOffset & (Modulo - 1); - if (V1Size != UnknownSize && V2Size != UnknownSize && - ModOffset >= V2Size && V1Size <= Modulo - ModOffset) + if (V1Size != MemoryLocation::UnknownSize && + V2Size != MemoryLocation::UnknownSize && ModOffset >= V2Size && + V1Size <= Modulo - ModOffset) return NoAlias; // If we know all the variables are positive, then GEP1 >= GEP1BasePtr. @@ -1302,8 +1259,8 @@ BasicAliasAnalysis::aliasPHI(const PHINode *PN, uint64_t PNSize, // on corresponding edges. if (const PHINode *PN2 = dyn_cast<PHINode>(V2)) if (PN2->getParent() == PN->getParent()) { - LocPair Locs(Location(PN, PNSize, PNAAInfo), - Location(V2, V2Size, V2AAInfo)); + LocPair Locs(MemoryLocation(PN, PNSize, PNAAInfo), + MemoryLocation(V2, V2Size, V2AAInfo)); if (PN > V2) std::swap(Locs.first, Locs.second); // Analyse the PHIs' inputs under the assumption that the PHIs are @@ -1457,14 +1414,16 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size, // If the size of one access is larger than the entire object on the other // side, then we know such behavior is undefined and can assume no alias. if (DL) - if ((V1Size != UnknownSize && isObjectSmallerThan(O2, V1Size, *DL, *TLI)) || - (V2Size != UnknownSize && isObjectSmallerThan(O1, V2Size, *DL, *TLI))) + if ((V1Size != MemoryLocation::UnknownSize && + isObjectSmallerThan(O2, V1Size, *DL, *TLI)) || + (V2Size != MemoryLocation::UnknownSize && + isObjectSmallerThan(O1, V2Size, *DL, *TLI))) return NoAlias; // Check the cache before climbing up use-def chains. This also terminates // otherwise infinitely recursive queries. - LocPair Locs(Location(V1, V1Size, V1AAInfo), - Location(V2, V2Size, V2AAInfo)); + LocPair Locs(MemoryLocation(V1, V1Size, V1AAInfo), + MemoryLocation(V2, V2Size, V2AAInfo)); if (V1 > V2) std::swap(Locs.first, Locs.second); std::pair<AliasCacheTy::iterator, bool> Pair = @@ -1511,13 +1470,15 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size, // accesses is accessing the entire object, then the accesses must // overlap in some way. if (DL && O1 == O2) - if ((V1Size != UnknownSize && isObjectSize(O1, V1Size, *DL, *TLI)) || - (V2Size != UnknownSize && isObjectSize(O2, V2Size, *DL, *TLI))) + if ((V1Size != MemoryLocation::UnknownSize && + isObjectSize(O1, V1Size, *DL, *TLI)) || + (V2Size != MemoryLocation::UnknownSize && + isObjectSize(O2, V2Size, *DL, *TLI))) return AliasCache[Locs] = PartialAlias; AliasResult Result = - AliasAnalysis::alias(Location(V1, V1Size, V1AAInfo), - Location(V2, V2Size, V2AAInfo)); + AliasAnalysis::alias(MemoryLocation(V1, V1Size, V1AAInfo), + MemoryLocation(V2, V2Size, V2AAInfo)); return AliasCache[Locs] = Result; } |