ArrayRef<const SCEV *> DimensionSizes, enum MemoryKind Kind,
const DataLayout &DL, Scop *S);
+ /// @brief Update the element type of the ScopArrayInfo object.
+ ///
+ /// Memory accesses referencing this ScopArrayInfo object may use
+ /// different element sizes. This function ensures the canonical element type
+ /// stored is small enough to model accesses to the current element type as
+ /// well as to @p NewElementType.
+ ///
+ /// @param NewElementType An element type that is used to access this array.
+ void updateElementType(Type *NewElementType);
+
/// @brief Update the sizes of the ScopArrayInfo object.
///
/// A ScopArrayInfo object may be created without all outer dimensions being
/// this ScopArrayInfo object. It verifies that sizes are compatible and adds
/// additional outer array dimensions, if needed.
///
- /// Similarly, memory accesses referencing this ScopArrayInfo object may use
- /// different element sizes. This function ensures the canonical element type
- /// stored is small enough to model all memory accesses.
- ///
/// @param Sizes A vector of array sizes where the rightmost array
/// sizes need to match the innermost array sizes already
/// defined in SAI.
- /// @param ElementType The element type of this memory access.
- bool updateSizes(ArrayRef<const SCEV *> Sizes, Type *ElementType);
+ bool updateSizes(ArrayRef<const SCEV *> Sizes);
/// @brief Destructor to free the isl id of the base pointer.
~ScopArrayInfo();
getIslCompatibleName("MemRef_", BasePtr, Kind == MK_PHI ? "__phi" : "");
Id = isl_id_alloc(Ctx, BasePtrName.c_str(), this);
- updateSizes(Sizes, ElementType);
+ updateSizes(Sizes);
BasePtrOriginSAI = identifyBasePtrOriginSAI(S, BasePtr);
if (BasePtrOriginSAI)
const_cast<ScopArrayInfo *>(BasePtrOriginSAI)->addDerivedSAI(this);
return Space;
}
-bool ScopArrayInfo::updateSizes(ArrayRef<const SCEV *> NewSizes,
- Type *NewElementType) {
+void ScopArrayInfo::updateElementType(Type *NewElementType) {
+ if (NewElementType == ElementType)
+ return;
+
auto OldElementSize = DL.getTypeAllocSizeInBits(ElementType);
auto NewElementSize = DL.getTypeAllocSizeInBits(NewElementType);
- if (NewElementSize != OldElementSize) {
- if (NewElementSize % OldElementSize == 0 &&
- NewElementSize < OldElementSize) {
- ElementType = NewElementType;
- } else {
- auto GCD = GreatestCommonDivisor64(NewElementSize, OldElementSize);
- ElementType = IntegerType::get(ElementType->getContext(), GCD);
- }
+ if (NewElementSize == OldElementSize)
+ return;
+
+ if (NewElementSize % OldElementSize == 0 && NewElementSize < OldElementSize) {
+ ElementType = NewElementType;
+ } else {
+ auto GCD = GreatestCommonDivisor64(NewElementSize, OldElementSize);
+ ElementType = IntegerType::get(ElementType->getContext(), GCD);
}
+}
+bool ScopArrayInfo::updateSizes(ArrayRef<const SCEV *> NewSizes) {
int SharedDims = std::min(NewSizes.size(), DimensionSizes.size());
int ExtraDimsNew = NewSizes.size() - SharedDims;
int ExtraDimsOld = DimensionSizes.size() - SharedDims;
SAI.reset(new ScopArrayInfo(BasePtr, ElementType, getIslCtx(), Sizes, Kind,
DL, this));
} else {
+ SAI->updateElementType(ElementType);
// In case of mismatching array sizes, we bail out by setting the run-time
// context to false.
- if (!SAI->updateSizes(Sizes, ElementType))
+ if (!SAI->updateSizes(Sizes))
invalidate(DELINEARIZATION, DebugLoc());
}
return SAI.get();