summaryrefslogtreecommitdiffstats
path: root/polly/lib/Analysis/ScopInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'polly/lib/Analysis/ScopInfo.cpp')
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp119
1 files changed, 1 insertions, 118 deletions
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index 00ede96ada3..b5f80bfc14a 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -110,22 +110,13 @@ STATISTIC(NumSingletonWrites, "Number of singleton writes after ScopInfo");
STATISTIC(NumSingletonWritesInLoops,
"Number of singleton writes nested in affine loops after ScopInfo");
-// The maximal number of basic sets we allow during domain construction to
-// be created. More complex scops will result in very high compile time and
-// are also unlikely to result in good code
-static int const MaxDisjunctsInDomain = 20;
+int const polly::MaxDisjunctsInDomain = 20;
// The number of disjunct in the context after which we stop to add more
// disjuncts. This parameter is there to avoid exponential growth in the
// number of disjunct when adding non-convex sets to the context.
static int const MaxDisjunctsInContext = 4;
-// The maximal number of dimensions we allow during invariant load construction.
-// More complex access ranges will result in very high compile time and are also
-// unlikely to result in good code. This value is very high and should only
-// trigger for corner cases (e.g., the "dct_luma" function in h264, SPEC2006).
-static int const MaxDimensionsInAccessRange = 9;
-
static cl::opt<int>
OptComputeOut("polly-analysis-computeout",
cl::desc("Bound the scop analysis by a maximal amount of "
@@ -2993,20 +2984,6 @@ MemoryAccess *Scop::lookupBasePtrAccess(MemoryAccess *MA) {
return BasePtrStmt->getArrayAccessOrNULLFor(PointerBaseInst);
}
-bool Scop::hasNonHoistableBasePtrInScop(MemoryAccess *MA,
- isl::union_map Writes) {
- if (auto *BasePtrMA = lookupBasePtrAccess(MA)) {
- return getNonHoistableCtx(BasePtrMA, Writes).is_null();
- }
-
- Value *BaseAddr = MA->getOriginalBaseAddr();
- if (auto *BasePtrInst = dyn_cast<Instruction>(BaseAddr))
- if (!isa<LoadInst>(BasePtrInst))
- return contains(BasePtrInst);
-
- return false;
-}
-
bool Scop::buildAliasChecks(AliasAnalysis &AA) {
if (!PollyUseRuntimeAliasChecks)
return true;
@@ -3684,100 +3661,6 @@ void Scop::addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs) {
}
}
-/// Check if an access range is too complex.
-///
-/// An access range is too complex, if it contains either many disjuncts or
-/// very complex expressions. As a simple heuristic, we assume if a set to
-/// be too complex if the sum of existentially quantified dimensions and
-/// set dimensions is larger than a threshold. This reliably detects both
-/// sets with many disjuncts as well as sets with many divisions as they
-/// arise in h264.
-///
-/// @param AccessRange The range to check for complexity.
-///
-/// @returns True if the access range is too complex.
-static bool isAccessRangeTooComplex(isl::set AccessRange) {
- unsigned NumTotalDims = 0;
-
- for (isl::basic_set BSet : AccessRange.get_basic_set_list()) {
- NumTotalDims += BSet.dim(isl::dim::div);
- NumTotalDims += BSet.dim(isl::dim::set);
- }
-
- if (NumTotalDims > MaxDimensionsInAccessRange)
- return true;
-
- return false;
-}
-
-isl::set Scop::getNonHoistableCtx(MemoryAccess *Access, isl::union_map Writes) {
- // TODO: Loads that are not loop carried, hence are in a statement with
- // zero iterators, are by construction invariant, though we
- // currently "hoist" them anyway. This is necessary because we allow
- // them to be treated as parameters (e.g., in conditions) and our code
- // generation would otherwise use the old value.
-
- auto &Stmt = *Access->getStatement();
- BasicBlock *BB = Stmt.getEntryBlock();
-
- if (Access->isScalarKind() || Access->isWrite() || !Access->isAffine() ||
- Access->isMemoryIntrinsic())
- return nullptr;
-
- // Skip accesses that have an invariant base pointer which is defined but
- // not loaded inside the SCoP. This can happened e.g., if a readnone call
- // returns a pointer that is used as a base address. However, as we want
- // to hoist indirect pointers, we allow the base pointer to be defined in
- // the region if it is also a memory access. Each ScopArrayInfo object
- // that has a base pointer origin has a base pointer that is loaded and
- // that it is invariant, thus it will be hoisted too. However, if there is
- // no base pointer origin we check that the base pointer is defined
- // outside the region.
- auto *LI = cast<LoadInst>(Access->getAccessInstruction());
- if (hasNonHoistableBasePtrInScop(Access, Writes))
- return nullptr;
-
- isl::map AccessRelation = Access->getAccessRelation();
- assert(!AccessRelation.is_empty());
-
- if (AccessRelation.involves_dims(isl::dim::in, 0, Stmt.getNumIterators()))
- return nullptr;
-
- AccessRelation = AccessRelation.intersect_domain(Stmt.getDomain());
- isl::set SafeToLoad;
-
- auto &DL = getFunction().getParent()->getDataLayout();
- if (isSafeToLoadUnconditionally(LI->getPointerOperand(), LI->getAlignment(),
- DL)) {
- SafeToLoad = isl::set::universe(AccessRelation.get_space().range());
- } else if (BB != LI->getParent()) {
- // Skip accesses in non-affine subregions as they might not be executed
- // under the same condition as the entry of the non-affine subregion.
- return nullptr;
- } else {
- SafeToLoad = AccessRelation.range();
- }
-
- if (isAccessRangeTooComplex(AccessRelation.range()))
- return nullptr;
-
- isl::union_map Written = Writes.intersect_range(SafeToLoad);
- isl::set WrittenCtx = Written.params();
- bool IsWritten = !WrittenCtx.is_empty();
-
- if (!IsWritten)
- return WrittenCtx;
-
- WrittenCtx = WrittenCtx.remove_divs();
- bool TooComplex = WrittenCtx.n_basic_set() >= MaxDisjunctsInDomain;
- if (TooComplex || !isRequiredInvariantLoad(LI))
- return nullptr;
-
- addAssumption(INVARIANTLOAD, WrittenCtx, LI->getDebugLoc(), AS_RESTRICTION,
- LI->getParent());
- return WrittenCtx;
-}
-
ScopArrayInfo *Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *ElementType,
ArrayRef<const SCEV *> Sizes,
MemoryKind Kind,
OpenPOWER on IntegriCloud