summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Grosser <tobias@grosser.es>2016-09-03 21:55:25 +0000
committerTobias Grosser <tobias@grosser.es>2016-09-03 21:55:25 +0000
commit8d4cb1a06071250c82ac301a81496f979055484d (patch)
tree3e4ee0a5abbb679796ba9ccd515424ec1866be85
parent241e6c70865b52d72f7e6a28194932d01c12989c (diff)
downloadbcm5719-llvm-8d4cb1a06071250c82ac301a81496f979055484d.tar.gz
bcm5719-llvm-8d4cb1a06071250c82ac301a81496f979055484d.zip
ScopInfo: Do not derive assumptions from all GEP pointer instructions
... but instead rely on the assumptions that we derive for load/store instructions. Before we were able to delinearize arrays, we used GEP pointer instructions to derive information about the likely range of induction variables, which gave us more freedom during loop scheduling. Today, this is not needed any more as we delinearize multi-dimensional memory accesses and as part of this process also "assume" that all accesses to these arrays remain inbounds. The old derive-assumptions-from-GEP code has consequently become mostly redundant. We drop it both to clean up our code, but also to improve compile time. This change reduces the scop construction time for 3mm in no-asserts mode on my machine from 48 to 37 ms. llvm-svn: 280601
-rw-r--r--polly/include/polly/ScopInfo.h32
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp75
2 files changed, 0 insertions, 107 deletions
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h
index 2337021e595..cb8c48aff62 100644
--- a/polly/include/polly/ScopInfo.h
+++ b/polly/include/polly/ScopInfo.h
@@ -1193,38 +1193,6 @@ private:
llvm::SmallVectorImpl<MemoryAccess *> &Loads);
//@}
- /// Derive assumptions about parameter values from GetElementPtrInst
- ///
- /// In case a GEP instruction references into a fixed size array e.g., an
- /// access A[i][j] into an array A[100x100], LLVM-IR does not guarantee that
- /// the subscripts always compute values that are within array bounds. In this
- /// function we derive the set of parameter values for which all accesses are
- /// within bounds and add the assumption that the scop is only every executed
- /// with this set of parameter values.
- ///
- /// Example:
- ///
- /// void foo(float A[][20], long n, long m {
- /// for (long i = 0; i < n; i++)
- /// for (long j = 0; j < m; j++)
- /// A[i][j] = ...
- ///
- /// This loop yields out-of-bound accesses if m is at least 20 and at the same
- /// time at least one iteration of the outer loop is executed. Hence, we
- /// assume:
- ///
- /// n <= 0 or m <= 20.
- ///
- /// TODO: The location where the GEP instruction is executed is not
- /// necessarily the location where the memory is actually accessed. As a
- /// result scanning for GEP[s] is imprecise. Even though this is not a
- /// correctness problem, this imprecision may result in missed optimizations
- /// or non-optimal run-time checks.
- void deriveAssumptionsFromGEP(GetElementPtrInst *Inst, LoopInfo &LI);
-
- /// Derive assumptions about parameter values.
- void deriveAssumptions(LoopInfo &LI);
-
public:
~ScopStmt();
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index 61edeaf2841..ee5e94ae826 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -1397,79 +1397,6 @@ void ScopStmt::buildDomain() {
Domain = isl_set_set_tuple_id(Domain, Id);
}
-void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP, LoopInfo &LI) {
- isl_ctx *Ctx = Parent.getIslCtx();
- isl_local_space *LSpace = isl_local_space_from_space(getDomainSpace());
- ScalarEvolution &SE = *Parent.getSE();
-
- // The set of loads that are required to be invariant.
- auto &ScopRIL = Parent.getRequiredInvariantLoads();
-
- std::vector<const SCEV *> Subscripts;
- std::vector<int> Sizes;
-
- std::tie(Subscripts, Sizes) = getIndexExpressionsFromGEP(GEP, SE);
-
- int IndexOffset = Subscripts.size() - Sizes.size();
-
- assert(IndexOffset <= 1 && "Unexpected large index offset");
-
- auto *NotExecuted = isl_set_complement(isl_set_params(getDomain()));
- for (size_t i = 0; i < Sizes.size(); i++) {
- auto *Expr = Subscripts[i + IndexOffset];
- auto Size = Sizes[i];
-
- auto *Scope = LI.getLoopFor(getEntryBlock());
- InvariantLoadsSetTy AccessILS;
- if (!isAffineExpr(&Parent.getRegion(), Scope, Expr, SE, &AccessILS))
- continue;
-
- bool NonAffine = false;
- for (LoadInst *LInst : AccessILS)
- if (!ScopRIL.count(LInst))
- NonAffine = true;
-
- if (NonAffine)
- continue;
-
- isl_pw_aff *AccessOffset = getPwAff(Expr);
- AccessOffset =
- isl_pw_aff_set_tuple_id(AccessOffset, isl_dim_in, getDomainId());
-
- isl_pw_aff *DimSize = isl_pw_aff_from_aff(isl_aff_val_on_domain(
- isl_local_space_copy(LSpace), isl_val_int_from_si(Ctx, Size)));
-
- isl_set *OutOfBound = isl_pw_aff_ge_set(AccessOffset, DimSize);
- OutOfBound = isl_set_intersect(getDomain(), OutOfBound);
- OutOfBound = isl_set_params(OutOfBound);
- isl_set *InBound = isl_set_complement(OutOfBound);
-
- // A => B == !A or B
- isl_set *InBoundIfExecuted =
- isl_set_union(isl_set_copy(NotExecuted), InBound);
-
- InBoundIfExecuted = isl_set_coalesce(InBoundIfExecuted);
- Parent.recordAssumption(INBOUNDS, InBoundIfExecuted, GEP->getDebugLoc(),
- AS_ASSUMPTION);
- }
-
- isl_local_space_free(LSpace);
- isl_set_free(NotExecuted);
-}
-
-void ScopStmt::deriveAssumptions(LoopInfo &LI) {
- for (auto *MA : *this) {
- if (!MA->isArrayKind())
- continue;
-
- MemAccInst Acc(MA->getAccessInstruction());
- auto *GEP = dyn_cast_or_null<GetElementPtrInst>(Acc.getPointerOperand());
-
- if (GEP)
- deriveAssumptionsFromGEP(GEP, LI);
- }
-}
-
void ScopStmt::collectSurroundingLoops() {
for (unsigned u = 0, e = isl_set_n_dim(Domain); u < e; u++) {
isl_id *DimId = isl_set_get_dim_id(Domain, isl_dim_set, u);
@@ -1499,8 +1426,6 @@ void ScopStmt::init(LoopInfo &LI) {
collectSurroundingLoops();
buildAccessRelations();
- deriveAssumptions(LI);
-
if (DetectReductions)
checkForReductions();
}
OpenPOWER on IntegriCloud