diff options
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 35 | ||||
-rw-r--r-- | llvm/lib/Analysis/CFLAndersAliasAnalysis.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp | 42 |
3 files changed, 53 insertions, 38 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index f9ecbc04326..6d4ac96ad37 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -1001,9 +1001,9 @@ ModRefInfo BasicAAResult::getModRefInfo(ImmutableCallSite CS1, /// Provide ad-hoc rules to disambiguate accesses through two GEP operators, /// both having the exact same pointer operand. static AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1, - LocationSize V1Size, + LocationSize MaybeV1Size, const GEPOperator *GEP2, - LocationSize V2Size, + LocationSize MaybeV2Size, const DataLayout &DL) { assert(GEP1->getPointerOperand()->stripPointerCastsAndInvariantGroups() == GEP2->getPointerOperand()->stripPointerCastsAndInvariantGroups() && @@ -1019,10 +1019,13 @@ static AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1, // 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 == MemoryLocation::UnknownSize || - V2Size == MemoryLocation::UnknownSize) + if (MaybeV1Size == MemoryLocation::UnknownSize || + MaybeV2Size == MemoryLocation::UnknownSize) return MayAlias; + const uint64_t V1Size = MaybeV1Size; + const uint64_t V2Size = MaybeV2Size; + ConstantInt *C1 = dyn_cast<ConstantInt>(GEP1->getOperand(GEP1->getNumOperands() - 1)); ConstantInt *C2 = @@ -1179,11 +1182,14 @@ static AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1, // than (%alloca - 1), and so is not inbounds, a contradiction. bool BasicAAResult::isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp, const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject, - LocationSize ObjectAccessSize) { + LocationSize MaybeObjectAccessSize) { // If the object access size is unknown, or the GEP isn't inbounds, bail. - if (ObjectAccessSize == MemoryLocation::UnknownSize || !GEPOp->isInBounds()) + if (MaybeObjectAccessSize == MemoryLocation::UnknownSize || + !GEPOp->isInBounds()) return false; + const uint64_t ObjectAccessSize = MaybeObjectAccessSize; + // We need the object to be an alloca or a globalvariable, and want to know // the offset of the pointer from the object precisely, so no variable // indices are allowed. @@ -1418,7 +1424,9 @@ BasicAAResult::aliasGEP(const GEPOperator *GEP1, LocationSize V1Size, // If we know all the variables are positive, then GEP1 >= GEP1BasePtr. // If GEP1BasePtr > V2 (GEP1BaseOffset > 0) then we know the pointers // don't alias if V2Size can fit in the gap between V2 and GEP1BasePtr. - if (AllPositive && GEP1BaseOffset > 0 && V2Size <= (uint64_t)GEP1BaseOffset) + if (AllPositive && GEP1BaseOffset > 0 && + V2Size != MemoryLocation::UnknownSize && + V2Size <= (uint64_t)GEP1BaseOffset) return NoAlias; if (constantOffsetHeuristic(DecompGEP1.VarIndices, V1Size, V2Size, @@ -1853,13 +1861,16 @@ void BasicAAResult::GetIndexDifference( } bool BasicAAResult::constantOffsetHeuristic( - const SmallVectorImpl<VariableGEPIndex> &VarIndices, LocationSize V1Size, - LocationSize V2Size, int64_t BaseOffset, AssumptionCache *AC, - DominatorTree *DT) { - if (VarIndices.size() != 2 || V1Size == MemoryLocation::UnknownSize || - V2Size == MemoryLocation::UnknownSize) + const SmallVectorImpl<VariableGEPIndex> &VarIndices, + LocationSize MaybeV1Size, LocationSize MaybeV2Size, int64_t BaseOffset, + AssumptionCache *AC, DominatorTree *DT) { + if (VarIndices.size() != 2 || MaybeV1Size == MemoryLocation::UnknownSize || + MaybeV2Size == MemoryLocation::UnknownSize) return false; + const uint64_t V1Size = MaybeV1Size; + const uint64_t V2Size = MaybeV2Size; + const VariableGEPIndex &Var0 = VarIndices[0], &Var1 = VarIndices[1]; if (Var0.ZExtBits != Var1.ZExtBits || Var0.SExtBits != Var1.SExtBits || diff --git a/llvm/lib/Analysis/CFLAndersAliasAnalysis.cpp b/llvm/lib/Analysis/CFLAndersAliasAnalysis.cpp index 18ea37fd7a8..db350e2c22f 100644 --- a/llvm/lib/Analysis/CFLAndersAliasAnalysis.cpp +++ b/llvm/lib/Analysis/CFLAndersAliasAnalysis.cpp @@ -515,10 +515,9 @@ CFLAndersAAResult::FunctionInfo::getAttrs(const Value *V) const { return None; } -bool CFLAndersAAResult::FunctionInfo::mayAlias(const Value *LHS, - LocationSize LHSSize, - const Value *RHS, - LocationSize RHSSize) const { +bool CFLAndersAAResult::FunctionInfo::mayAlias( + const Value *LHS, LocationSize MaybeLHSSize, const Value *RHS, + LocationSize MaybeRHSSize) const { assert(LHS && RHS); // Check if we've seen LHS and RHS before. Sometimes LHS or RHS can be created @@ -558,10 +557,13 @@ bool CFLAndersAAResult::FunctionInfo::mayAlias(const Value *LHS, if (RangePair.first != RangePair.second) { // Be conservative about UnknownSize - if (LHSSize == MemoryLocation::UnknownSize || - RHSSize == MemoryLocation::UnknownSize) + if (MaybeLHSSize == MemoryLocation::UnknownSize || + MaybeRHSSize == MemoryLocation::UnknownSize) return true; + const uint64_t LHSSize = MaybeLHSSize; + const uint64_t RHSSize = MaybeRHSSize; + for (const auto &OVal : make_range(RangePair)) { // Be conservative about UnknownOffset if (OVal.Offset == UnknownOffset) diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index 8551083698e..0a3a00b8380 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -354,6 +354,9 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later, Earlier.Size == MemoryLocation::UnknownSize) return OW_Unknown; + const uint64_t LaterSize = Later.Size; + const uint64_t EarlierSize = Earlier.Size; + const Value *P1 = Earlier.Ptr->stripPointerCasts(); const Value *P2 = Later.Ptr->stripPointerCasts(); @@ -361,7 +364,7 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later, // the later store was larger than the earlier store. if (P1 == P2 || AA.isMustAlias(P1, P2)) { // Make sure that the Later size is >= the Earlier size. - if (Later.Size >= Earlier.Size) + if (LaterSize >= EarlierSize) return OW_Complete; } @@ -379,7 +382,7 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later, // If the "Later" store is to a recognizable object, get its size. uint64_t ObjectSize = getPointerSize(UO2, DL, TLI, F); if (ObjectSize != MemoryLocation::UnknownSize) - if (ObjectSize == Later.Size && ObjectSize >= Earlier.Size) + if (ObjectSize == LaterSize && ObjectSize >= EarlierSize) return OW_Complete; // Okay, we have stores to two completely different pointers. Try to @@ -410,8 +413,8 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later, // // We have to be careful here as *Off is signed while *.Size is unsigned. if (EarlierOff >= LaterOff && - Later.Size >= Earlier.Size && - uint64_t(EarlierOff - LaterOff) + Earlier.Size <= Later.Size) + LaterSize >= EarlierSize && + uint64_t(EarlierOff - LaterOff) + EarlierSize <= LaterSize) return OW_Complete; // We may now overlap, although the overlap is not complete. There might also @@ -420,21 +423,21 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later, // Note: The correctness of this logic depends on the fact that this function // is not even called providing DepWrite when there are any intervening reads. if (EnablePartialOverwriteTracking && - LaterOff < int64_t(EarlierOff + Earlier.Size) && - int64_t(LaterOff + Later.Size) >= EarlierOff) { + LaterOff < int64_t(EarlierOff + EarlierSize) && + int64_t(LaterOff + LaterSize) >= EarlierOff) { // Insert our part of the overlap into the map. auto &IM = IOL[DepWrite]; LLVM_DEBUG(dbgs() << "DSE: Partial overwrite: Earlier [" << EarlierOff - << ", " << int64_t(EarlierOff + Earlier.Size) + << ", " << int64_t(EarlierOff + EarlierSize) << ") Later [" << LaterOff << ", " - << int64_t(LaterOff + Later.Size) << ")\n"); + << int64_t(LaterOff + LaterSize) << ")\n"); // Make sure that we only insert non-overlapping intervals and combine // adjacent intervals. The intervals are stored in the map with the ending // offset as the key (in the half-open sense) and the starting offset as // the value. - int64_t LaterIntStart = LaterOff, LaterIntEnd = LaterOff + Later.Size; + int64_t LaterIntStart = LaterOff, LaterIntEnd = LaterOff + LaterSize; // Find any intervals ending at, or after, LaterIntStart which start // before LaterIntEnd. @@ -464,10 +467,10 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later, ILI = IM.begin(); if (ILI->second <= EarlierOff && - ILI->first >= int64_t(EarlierOff + Earlier.Size)) { + ILI->first >= int64_t(EarlierOff + EarlierSize)) { LLVM_DEBUG(dbgs() << "DSE: Full overwrite from partials: Earlier [" << EarlierOff << ", " - << int64_t(EarlierOff + Earlier.Size) + << int64_t(EarlierOff + EarlierSize) << ") Composite Later [" << ILI->second << ", " << ILI->first << ")\n"); ++NumCompletePartials; @@ -478,13 +481,13 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later, // Check for an earlier store which writes to all the memory locations that // the later store writes to. if (EnablePartialStoreMerging && LaterOff >= EarlierOff && - int64_t(EarlierOff + Earlier.Size) > LaterOff && - uint64_t(LaterOff - EarlierOff) + Later.Size <= Earlier.Size) { + int64_t(EarlierOff + EarlierSize) > LaterOff && + uint64_t(LaterOff - EarlierOff) + LaterSize <= EarlierSize) { LLVM_DEBUG(dbgs() << "DSE: Partial overwrite an earlier load [" << EarlierOff << ", " - << int64_t(EarlierOff + Earlier.Size) + << int64_t(EarlierOff + EarlierSize) << ") by a later store [" << LaterOff << ", " - << int64_t(LaterOff + Later.Size) << ")\n"); + << int64_t(LaterOff + LaterSize) << ")\n"); // TODO: Maybe come up with a better name? return OW_PartialEarlierWithFullLater; } @@ -498,8 +501,8 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later, // In this case we may want to trim the size of earlier to avoid generating // writes to addresses which will definitely be overwritten later if (!EnablePartialOverwriteTracking && - (LaterOff > EarlierOff && LaterOff < int64_t(EarlierOff + Earlier.Size) && - int64_t(LaterOff + Later.Size) >= int64_t(EarlierOff + Earlier.Size))) + (LaterOff > EarlierOff && LaterOff < int64_t(EarlierOff + EarlierSize) && + int64_t(LaterOff + LaterSize) >= int64_t(EarlierOff + EarlierSize))) return OW_End; // Finally, we also need to check if the later store overwrites the beginning @@ -512,9 +515,8 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later, // of earlier to avoid generating writes to addresses which will definitely // be overwritten later. if (!EnablePartialOverwriteTracking && - (LaterOff <= EarlierOff && int64_t(LaterOff + Later.Size) > EarlierOff)) { - assert(int64_t(LaterOff + Later.Size) < - int64_t(EarlierOff + Earlier.Size) && + (LaterOff <= EarlierOff && int64_t(LaterOff + LaterSize) > EarlierOff)) { + assert(int64_t(LaterOff + LaterSize) < int64_t(EarlierOff + EarlierSize) && "Expect to be handled as OW_Complete"); return OW_Begin; } |