Make LocationSize a proper Optional type; NFC
This is the second in a series of changes intended to make
https://reviews.llvm.org/D44748 more easily reviewable. Please see that
patch for more context. The first change being r344012.
Since I was requested to do all of this with post-commit review, this is
about as small as I can make this patch.
This patch makes LocationSize into an actual type that wraps a uint64_t;
users are required to call getValue() in order to get the size now. If
the LocationSize has an Unknown size (e.g. if LocSize ==
MemoryLocation::UnknownSize), getValue() will assert.
This also adds DenseMap specializations for LocationInfo, which required
taking two more values from the set of values LocationInfo can
represent. Hence, heavy users of multi-exabyte arrays or structs may
observe slightly lower-quality code as a result of this change.
The intent is for getValue()s to be very close to a corresponding
hasValue() (which is often spelled `!= MemoryLocation::UnknownSize`).
Sadly, small diff context appears to crop that out sometimes, and the
last change in DSE does require a bit of nonlocal reasoning about
control-flow. :/
This also removes an assert, since it's now redundant with the assert in
getValue().
llvm-svn: 344013
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 6d4ac96..072a50a 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1023,8 +1023,8 @@
MaybeV2Size == MemoryLocation::UnknownSize)
return MayAlias;
- const uint64_t V1Size = MaybeV1Size;
- const uint64_t V2Size = MaybeV2Size;
+ const uint64_t V1Size = MaybeV1Size.getValue();
+ const uint64_t V2Size = MaybeV2Size.getValue();
ConstantInt *C1 =
dyn_cast<ConstantInt>(GEP1->getOperand(GEP1->getNumOperands() - 1));
@@ -1188,7 +1188,7 @@
!GEPOp->isInBounds())
return false;
- const uint64_t ObjectAccessSize = MaybeObjectAccessSize;
+ const uint64_t ObjectAccessSize = MaybeObjectAccessSize.getValue();
// 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
@@ -1352,7 +1352,7 @@
if (GEP1BaseOffset != 0 && DecompGEP1.VarIndices.empty()) {
if (GEP1BaseOffset >= 0) {
if (V2Size != MemoryLocation::UnknownSize) {
- if ((uint64_t)GEP1BaseOffset < V2Size)
+ if ((uint64_t)GEP1BaseOffset < V2Size.getValue())
return PartialAlias;
return NoAlias;
}
@@ -1367,7 +1367,7 @@
// stripped a gep with negative index ('gep <ptr>, -1, ...).
if (V1Size != MemoryLocation::UnknownSize &&
V2Size != MemoryLocation::UnknownSize) {
- if (-(uint64_t)GEP1BaseOffset < V1Size)
+ if (-(uint64_t)GEP1BaseOffset < V1Size.getValue())
return PartialAlias;
return NoAlias;
}
@@ -1417,8 +1417,9 @@
// two locations do not alias.
uint64_t ModOffset = (uint64_t)GEP1BaseOffset & (Modulo - 1);
if (V1Size != MemoryLocation::UnknownSize &&
- V2Size != MemoryLocation::UnknownSize && ModOffset >= V2Size &&
- V1Size <= Modulo - ModOffset)
+ V2Size != MemoryLocation::UnknownSize &&
+ ModOffset >= V2Size.getValue() &&
+ V1Size.getValue() <= Modulo - ModOffset)
return NoAlias;
// If we know all the variables are positive, then GEP1 >= GEP1BasePtr.
@@ -1426,7 +1427,7 @@
// don't alias if V2Size can fit in the gap between V2 and GEP1BasePtr.
if (AllPositive && GEP1BaseOffset > 0 &&
V2Size != MemoryLocation::UnknownSize &&
- V2Size <= (uint64_t)GEP1BaseOffset)
+ V2Size.getValue() <= (uint64_t)GEP1BaseOffset)
return NoAlias;
if (constantOffsetHeuristic(DecompGEP1.VarIndices, V1Size, V2Size,
@@ -1715,9 +1716,11 @@
// side, then we know such behavior is undefined and can assume no alias.
bool NullIsValidLocation = NullPointerIsDefined(&F);
if ((V1Size != MemoryLocation::UnknownSize &&
- isObjectSmallerThan(O2, V1Size, DL, TLI, NullIsValidLocation)) ||
+ isObjectSmallerThan(O2, V1Size.getValue(), DL, TLI,
+ NullIsValidLocation)) ||
(V2Size != MemoryLocation::UnknownSize &&
- isObjectSmallerThan(O1, V2Size, DL, TLI, NullIsValidLocation)))
+ isObjectSmallerThan(O1, V2Size.getValue(), DL, TLI,
+ NullIsValidLocation)))
return NoAlias;
// Check the cache before climbing up use-def chains. This also terminates
@@ -1777,8 +1780,8 @@
if (O1 == O2)
if (V1Size != MemoryLocation::UnknownSize &&
V2Size != MemoryLocation::UnknownSize &&
- (isObjectSize(O1, V1Size, DL, TLI, NullIsValidLocation) ||
- isObjectSize(O2, V2Size, DL, TLI, NullIsValidLocation)))
+ (isObjectSize(O1, V1Size.getValue(), DL, TLI, NullIsValidLocation) ||
+ isObjectSize(O2, V2Size.getValue(), DL, TLI, NullIsValidLocation)))
return AliasCache[Locs] = PartialAlias;
// Recurse back into the best AA results we have, potentially with refined
@@ -1868,8 +1871,8 @@
MaybeV2Size == MemoryLocation::UnknownSize)
return false;
- const uint64_t V1Size = MaybeV1Size;
- const uint64_t V2Size = MaybeV2Size;
+ const uint64_t V1Size = MaybeV1Size.getValue();
+ const uint64_t V2Size = MaybeV2Size.getValue();
const VariableGEPIndex &Var0 = VarIndices[0], &Var1 = VarIndices[1];
diff --git a/llvm/lib/Analysis/CFLAndersAliasAnalysis.cpp b/llvm/lib/Analysis/CFLAndersAliasAnalysis.cpp
index db350e2..b43b48e 100644
--- a/llvm/lib/Analysis/CFLAndersAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/CFLAndersAliasAnalysis.cpp
@@ -561,8 +561,8 @@
MaybeRHSSize == MemoryLocation::UnknownSize)
return true;
- const uint64_t LHSSize = MaybeLHSSize;
- const uint64_t RHSSize = MaybeRHSSize;
+ const uint64_t LHSSize = MaybeLHSSize.getValue();
+ const uint64_t RHSSize = MaybeRHSSize.getValue();
for (const auto &OVal : make_range(RangePair)) {
// Be conservative about UnknownOffset
diff --git a/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp b/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
index 7bea994..61f6254 100644
--- a/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
@@ -43,8 +43,12 @@
if (SE.getEffectiveSCEVType(AS->getType()) ==
SE.getEffectiveSCEVType(BS->getType())) {
unsigned BitWidth = SE.getTypeSizeInBits(AS->getType());
- APInt ASizeInt(BitWidth, LocA.Size);
- APInt BSizeInt(BitWidth, LocB.Size);
+ APInt ASizeInt(BitWidth, LocA.Size.hasValue()
+ ? LocA.Size.getValue()
+ : MemoryLocation::UnknownSize);
+ APInt BSizeInt(BitWidth, LocB.Size.hasValue()
+ ? LocB.Size.getValue()
+ : MemoryLocation::UnknownSize);
// Compute the difference between the two pointers.
const SCEV *BA = SE.getMinusSCEV(BS, AS);