ScopInfo: Introduce ArrayKind

Since 252422 we do not only distinguish two ScopArrayInfo kinds, PHI nodes
and others, but work with three kind of ScopArrayInfo objects. SCALAR, PHI and
ARRAY objects. Instead of keeping two boolean flags isPHI and isScalar and
wonder what an ScopArrayInfo object of kind (!isScalar && isPHI) is, we
list now explicitly the three different possible types of memory objects.

This change also allows us to remove the confusing nested pairs that have
been used in ArrayInfoMapTy.

llvm-svn: 252620
This commit is contained in:
Tobias Grosser 2015-11-10 17:31:31 +00:00
parent 45c40fff66
commit 6abc75af4c
3 changed files with 50 additions and 29 deletions

View File

@ -84,16 +84,29 @@ typedef std::map<const BasicBlock *, AccFuncSetType> AccFuncMapType;
///
class ScopArrayInfo {
public:
/// @brief The type of a memory access.
enum ARRAYKIND {
// Scalar references to SSA values.
KIND_SCALAR,
// Scalar references used to model PHI nodes
KIND_PHI,
// References to (multi-dimensional) arrays
KIND_ARRAY,
};
/// @brief Construct a ScopArrayInfo object.
///
/// @param BasePtr The array base pointer.
/// @param ElementType The type of the elements stored in the array.
/// @param IslCtx The isl context used to create the base pointer id.
/// @param DimensionSizes A vector containing the size of each dimension.
/// @param IsPHI Is this a PHI node specific array info object.
/// @param Kind The kind of the array object.
/// @param S The scop this array object belongs to.
ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *IslCtx,
ArrayRef<const SCEV *> DimensionSizes, bool IsPHI, Scop *S);
ArrayRef<const SCEV *> DimensionSizes, enum ARRAYKIND Kind,
Scop *S);
/// @brief Update the sizes of the ScopArrayInfo object.
///
@ -170,7 +183,7 @@ public:
/// original PHI node as virtual base pointer, we have this additional
/// attribute to distinguish the PHI node specific array modeling from the
/// normal scalar array modeling.
bool isPHI() const { return IsPHI; };
bool isPHI() const { return Kind == KIND_PHI; };
/// @brief Dump a readable representation to stderr.
void dump() const;
@ -216,8 +229,10 @@ private:
/// @brief The sizes of each dimension as isl_pw_aff.
SmallVector<isl_pw_aff *, 4> DimensionSizesPw;
/// @brief Is this PHI node specific storage?
bool IsPHI;
/// @brief The type of this scop array info object.
///
/// We distinguish between SCALAR, PHI and ARRAY objects.
enum ARRAYKIND Kind;
/// @brief The scop this SAI object belongs to.
Scop &S;
@ -1076,7 +1091,7 @@ private:
/// @brief The affinator used to translate SCEVs to isl expressions.
SCEVAffinator Affinator;
typedef MapVector<std::pair<AssertingVH<const Value>, std::pair<int, int>>,
typedef MapVector<std::pair<AssertingVH<const Value>, int>,
std::unique_ptr<ScopArrayInfo>> ArrayInfoMapTy;
/// @brief A map to remember ScopArrayInfo objects for all base pointers.
///
@ -1510,20 +1525,18 @@ public:
/// @brief Return the (possibly new) ScopArrayInfo object for @p Access.
///
/// @param ElementType The type of the elements stored in this array.
/// @param IsPHI Is this ScopArrayInfo object modeling special
/// PHI node storage.
/// @param Kind The kind of array info object.
const ScopArrayInfo *getOrCreateScopArrayInfo(Value *BasePtr,
Type *ElementType,
ArrayRef<const SCEV *> Sizes,
bool IsPHI = false);
ScopArrayInfo::ARRAYKIND Kind);
/// @brief Return the cached ScopArrayInfo object for @p BasePtr.
///
/// @param BasePtr The base pointer the object has been stored for.
/// @param IsScalar Are we looking for a scalar or memory access location.
/// @param IsPHI Are we looking for special PHI storage.
const ScopArrayInfo *getScopArrayInfo(Value *BasePtr, bool IsScalar,
bool IsPHI = false);
/// @param Kind The kind of array info object.
const ScopArrayInfo *getScopArrayInfo(Value *BasePtr,
ScopArrayInfo::ARRAYKIND Kind);
void setContext(isl_set *NewContext);

View File

@ -150,14 +150,16 @@ static const ScopArrayInfo *identifyBasePtrOriginSAI(Scop *S, Value *BasePtr) {
if (!OriginBaseSCEVUnknown)
return nullptr;
return S->getScopArrayInfo(OriginBaseSCEVUnknown->getValue(), false);
return S->getScopArrayInfo(OriginBaseSCEVUnknown->getValue(),
ScopArrayInfo::KIND_ARRAY);
}
ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *Ctx,
ArrayRef<const SCEV *> Sizes, bool IsPHI, Scop *S)
: BasePtr(BasePtr), ElementType(ElementType), IsPHI(IsPHI), S(*S) {
ArrayRef<const SCEV *> Sizes, enum ARRAYKIND Kind,
Scop *S)
: BasePtr(BasePtr), ElementType(ElementType), Kind(Kind), S(*S) {
std::string BasePtrName =
getIslCompatibleName("MemRef_", BasePtr, IsPHI ? "__phi" : "");
getIslCompatibleName("MemRef_", BasePtr, Kind == KIND_PHI ? "__phi" : "");
Id = isl_id_alloc(Ctx, BasePtrName.c_str(), this);
updateSizes(Sizes);
@ -830,8 +832,16 @@ void ScopStmt::buildAccessRelations() {
for (MemoryAccess *Access : MemAccs) {
Type *ElementType = Access->getAccessValue()->getType();
ScopArrayInfo::ARRAYKIND Ty;
if (Access->isPHI())
Ty = ScopArrayInfo::KIND_PHI;
else if (Access->isImplicit())
Ty = ScopArrayInfo::KIND_SCALAR;
else
Ty = ScopArrayInfo::KIND_ARRAY;
const ScopArrayInfo *SAI = getParent()->getOrCreateScopArrayInfo(
Access->getBaseAddr(), ElementType, Access->Sizes, Access->isPHI());
Access->getBaseAddr(), ElementType, Access->Sizes, Ty);
Access->buildAccessRelation(SAI);
}
@ -2771,13 +2781,12 @@ void Scop::hoistInvariantLoads() {
const ScopArrayInfo *
Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *AccessType,
ArrayRef<const SCEV *> Sizes, bool IsPHI) {
bool IsScalar = Sizes.empty();
auto ScalarTypePair = std::make_pair(IsScalar, IsPHI);
auto &SAI = ScopArrayInfoMap[std::make_pair(BasePtr, ScalarTypePair)];
ArrayRef<const SCEV *> Sizes,
ScopArrayInfo::ARRAYKIND Kind) {
auto &SAI = ScopArrayInfoMap[std::make_pair(BasePtr, Kind)];
if (!SAI) {
SAI.reset(new ScopArrayInfo(BasePtr, AccessType, getIslCtx(), Sizes, IsPHI,
this));
SAI.reset(
new ScopArrayInfo(BasePtr, AccessType, getIslCtx(), Sizes, Kind, this));
} else {
// In case of mismatching array sizes, we bail out by setting the run-time
// context to false.
@ -2787,10 +2796,9 @@ Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *AccessType,
return SAI.get();
}
const ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr, bool IsScalar,
bool IsPHI) {
auto ScalarTypePair = std::make_pair(IsScalar, IsPHI);
auto *SAI = ScopArrayInfoMap[std::make_pair(BasePtr, ScalarTypePair)].get();
const ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr,
ScopArrayInfo::ARRAYKIND Kind) {
auto *SAI = ScopArrayInfoMap[std::make_pair(BasePtr, Kind)].get();
assert(SAI && "No ScopArrayInfo available for this base pointer");
return SAI;
}

View File

@ -964,7 +964,7 @@ bool IslNodeBuilder::preloadInvariantEquivClass(
// If the base pointer of this class is dependent on another one we have to
// make sure it was preloaded already.
auto *SAI = S.getScopArrayInfo(MA->getBaseAddr(), false);
auto *SAI = S.getScopArrayInfo(MA->getBaseAddr(), ScopArrayInfo::KIND_ARRAY);
if (const auto *BaseIAClass = S.lookupInvariantEquivClass(SAI->getBasePtr()))
if (!preloadInvariantEquivClass(*BaseIAClass))
return false;