forked from OSchip/llvm-project
ScopInfo: split out construction of a single alias group [NFC]
The loop body in buildAliasGroups is still too large to easily scan it. Hence, we split the loop body out into a separate function to improve readability. llvm-svn: 292138
This commit is contained in:
parent
e95222343c
commit
77f3257b41
|
@ -2308,6 +2308,16 @@ public:
|
|||
/// @param AliasGroups The alias groups to split
|
||||
void splitAliasGroupsByDomain(AliasGroupVectorTy &AliasGroups);
|
||||
|
||||
/// Build a given alias group and its access data.
|
||||
///
|
||||
/// @param AliasGroup The alias group to build.
|
||||
/// @param HasWriteAccess A set of base pointer values for through which
|
||||
/// memory is not only read, but also written.
|
||||
///
|
||||
/// @returns True if __no__ error occurred, false otherwise.
|
||||
bool buildAliasGroup(Scop::AliasGroupTy &AliasGroup,
|
||||
DenseSet<Value *> HasWriteAccess);
|
||||
|
||||
/// Return all alias groups for this SCoP.
|
||||
const MinMaxVectorPairVectorTy &getAliasGroups() const {
|
||||
return MinMaxAliasGroups;
|
||||
|
|
|
@ -2983,73 +2983,8 @@ bool Scop::buildAliasGroups(AliasAnalysis &AA) {
|
|||
|
||||
splitAliasGroupsByDomain(AliasGroups);
|
||||
|
||||
auto &F = getFunction();
|
||||
for (AliasGroupTy &AG : AliasGroups) {
|
||||
AliasGroupTy ReadOnlyAccesses;
|
||||
AliasGroupTy ReadWriteAccesses;
|
||||
SmallPtrSet<const Value *, 4> NonReadOnlyBaseValues;
|
||||
|
||||
if (AG.size() < 2)
|
||||
continue;
|
||||
|
||||
for (MemoryAccess *Access : AG) {
|
||||
emitOptimizationRemarkAnalysis(
|
||||
F.getContext(), DEBUG_TYPE, F,
|
||||
Access->getAccessInstruction()->getDebugLoc(),
|
||||
"Possibly aliasing pointer, use restrict keyword.");
|
||||
|
||||
Value *BaseAddr = Access->getBaseAddr();
|
||||
if (HasWriteAccess.count(BaseAddr)) {
|
||||
NonReadOnlyBaseValues.insert(BaseAddr);
|
||||
ReadWriteAccesses.push_back(Access);
|
||||
} else {
|
||||
ReadOnlyAccesses.push_back(Access);
|
||||
}
|
||||
}
|
||||
|
||||
// If we don't have read only pointers check if there are at least two
|
||||
// non read only pointers, otherwise clear the alias group.
|
||||
if (ReadOnlyAccesses.empty() && NonReadOnlyBaseValues.size() <= 1)
|
||||
continue;
|
||||
|
||||
// If we don't have non read only pointers clear the alias group.
|
||||
if (NonReadOnlyBaseValues.empty())
|
||||
continue;
|
||||
|
||||
// Check if we have non-affine accesses left, if so bail out as we cannot
|
||||
// generate a good access range yet.
|
||||
for (MemoryAccess *MA : AG) {
|
||||
if (!MA->isAffine()) {
|
||||
invalidate(ALIASING, MA->getAccessInstruction()->getDebugLoc());
|
||||
return false;
|
||||
}
|
||||
if (MemoryAccess *BasePtrMA = lookupBasePtrAccess(MA))
|
||||
addRequiredInvariantLoad(
|
||||
cast<LoadInst>(BasePtrMA->getAccessInstruction()));
|
||||
}
|
||||
|
||||
MinMaxAliasGroups.emplace_back();
|
||||
MinMaxVectorPairTy &pair = MinMaxAliasGroups.back();
|
||||
MinMaxVectorTy &MinMaxAccessesNonReadOnly = pair.first;
|
||||
MinMaxVectorTy &MinMaxAccessesReadOnly = pair.second;
|
||||
|
||||
bool Valid;
|
||||
Valid = calculateMinMaxAccess(ReadWriteAccesses, *this,
|
||||
MinMaxAccessesNonReadOnly);
|
||||
|
||||
if (!Valid)
|
||||
return false;
|
||||
|
||||
// Bail out if the number of values we need to compare is too large.
|
||||
// This is important as the number of comparisons grows quadratically with
|
||||
// the number of values we need to compare.
|
||||
if (MinMaxAccessesNonReadOnly.size() + ReadOnlyAccesses.size() >
|
||||
RunTimeChecksMaxArraysPerGroup)
|
||||
return false;
|
||||
|
||||
Valid =
|
||||
calculateMinMaxAccess(ReadOnlyAccesses, *this, MinMaxAccessesReadOnly);
|
||||
|
||||
bool Valid = buildAliasGroup(AG, HasWriteAccess);
|
||||
if (!Valid)
|
||||
return false;
|
||||
}
|
||||
|
@ -3057,6 +2992,82 @@ bool Scop::buildAliasGroups(AliasAnalysis &AA) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Scop::buildAliasGroup(Scop::AliasGroupTy &AliasGroup,
|
||||
DenseSet<Value *> HasWriteAccess) {
|
||||
AliasGroupTy ReadOnlyAccesses;
|
||||
AliasGroupTy ReadWriteAccesses;
|
||||
SmallPtrSet<const Value *, 4> NonReadOnlyBaseValues;
|
||||
|
||||
auto &F = getFunction();
|
||||
|
||||
if (AliasGroup.size() < 2)
|
||||
return true;
|
||||
|
||||
for (MemoryAccess *Access : AliasGroup) {
|
||||
emitOptimizationRemarkAnalysis(
|
||||
F.getContext(), DEBUG_TYPE, F,
|
||||
Access->getAccessInstruction()->getDebugLoc(),
|
||||
"Possibly aliasing pointer, use restrict keyword.");
|
||||
|
||||
Value *BaseAddr = Access->getBaseAddr();
|
||||
if (HasWriteAccess.count(BaseAddr)) {
|
||||
NonReadOnlyBaseValues.insert(BaseAddr);
|
||||
ReadWriteAccesses.push_back(Access);
|
||||
} else {
|
||||
ReadOnlyAccesses.push_back(Access);
|
||||
}
|
||||
}
|
||||
|
||||
// If we don't have read only pointers check if there are at least two
|
||||
// non read only pointers, otherwise clear the alias group.
|
||||
if (ReadOnlyAccesses.empty() && NonReadOnlyBaseValues.size() <= 1)
|
||||
return true;
|
||||
|
||||
// If we don't have non read only pointers clear the alias group.
|
||||
if (NonReadOnlyBaseValues.empty())
|
||||
return true;
|
||||
|
||||
// Check if we have non-affine accesses left, if so bail out as we cannot
|
||||
// generate a good access range yet.
|
||||
for (MemoryAccess *MA : AliasGroup) {
|
||||
if (!MA->isAffine()) {
|
||||
invalidate(ALIASING, MA->getAccessInstruction()->getDebugLoc());
|
||||
return false;
|
||||
}
|
||||
if (MemoryAccess *BasePtrMA = lookupBasePtrAccess(MA))
|
||||
addRequiredInvariantLoad(
|
||||
cast<LoadInst>(BasePtrMA->getAccessInstruction()));
|
||||
}
|
||||
|
||||
MinMaxAliasGroups.emplace_back();
|
||||
MinMaxVectorPairTy &pair = MinMaxAliasGroups.back();
|
||||
MinMaxVectorTy &MinMaxAccessesReadWrite = pair.first;
|
||||
MinMaxVectorTy &MinMaxAccessesReadOnly = pair.second;
|
||||
|
||||
bool Valid;
|
||||
|
||||
Valid =
|
||||
calculateMinMaxAccess(ReadWriteAccesses, *this, MinMaxAccessesReadWrite);
|
||||
|
||||
if (!Valid)
|
||||
return false;
|
||||
|
||||
// Bail out if the number of values we need to compare is too large.
|
||||
// This is important as the number of comparisons grows quadratically with
|
||||
// the number of values we need to compare.
|
||||
if (MinMaxAccessesReadWrite.size() + ReadOnlyAccesses.size() >
|
||||
RunTimeChecksMaxArraysPerGroup)
|
||||
return false;
|
||||
|
||||
Valid =
|
||||
calculateMinMaxAccess(ReadOnlyAccesses, *this, MinMaxAccessesReadOnly);
|
||||
|
||||
if (!Valid)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Get the smallest loop that contains @p S but is not in @p S.
|
||||
static Loop *getLoopSurroundingScop(Scop &S, LoopInfo &LI) {
|
||||
// Start with the smallest loop containing the entry and expand that
|
||||
|
|
Loading…
Reference in New Issue