From 77f3257b41bb4626bb1e40807c996144a5690ea2 Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Mon, 16 Jan 2017 15:49:07 +0000 Subject: [PATCH] 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 --- polly/include/polly/ScopInfo.h | 10 +++ polly/lib/Analysis/ScopInfo.cpp | 143 +++++++++++++++++--------------- 2 files changed, 87 insertions(+), 66 deletions(-) diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h index d9ec96d3f9d6..1ee17c2696fd 100644 --- a/polly/include/polly/ScopInfo.h +++ b/polly/include/polly/ScopInfo.h @@ -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 HasWriteAccess); + /// Return all alias groups for this SCoP. const MinMaxVectorPairVectorTy &getAliasGroups() const { return MinMaxAliasGroups; diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index 382f586f1f95..2b345f7f27ee 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -2983,73 +2983,8 @@ bool Scop::buildAliasGroups(AliasAnalysis &AA) { splitAliasGroupsByDomain(AliasGroups); - auto &F = getFunction(); for (AliasGroupTy &AG : AliasGroups) { - AliasGroupTy ReadOnlyAccesses; - AliasGroupTy ReadWriteAccesses; - SmallPtrSet 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(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 HasWriteAccess) { + AliasGroupTy ReadOnlyAccesses; + AliasGroupTy ReadWriteAccesses; + SmallPtrSet 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(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