[polly] r248125 - Simplify domain generation
Johannes Doerfert via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 20 09:15:32 PDT 2015
Author: jdoerfert
Date: Sun Sep 20 11:15:32 2015
New Revision: 248125
URL: http://llvm.org/viewvc/llvm-project?rev=248125&view=rev
Log:
Simplify domain generation
We now add loop carried information during the second traversal of the
region instead of in a intermediate step in-between. This makes the
generation simpler, removes code and should even be faster.
Modified:
polly/trunk/include/polly/ScopInfo.h
polly/trunk/lib/Analysis/ScopInfo.cpp
polly/trunk/test/Isl/CodeGen/phi_scalar_simple_1.ll
polly/trunk/test/ScopInfo/multiple_exiting_blocks.ll
Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=248125&r1=248124&r2=248125&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Sun Sep 20 11:15:32 2015
@@ -1015,13 +1015,11 @@ private:
/// @brief Initialize this ScopInfo .
void init(LoopInfo &LI, ScopDetection &SD, AliasAnalysis &AA);
- /// @brief Add loop carried constraints to the header blocks of loops.
+ /// @brief Add loop carried constraints to the header block of the loop @p L.
///
+ /// @param L The loop to process.
/// @param LI The LoopInfo analysis.
- /// @param SD The ScopDetection analysis to identify non-affine sub-regions.
- /// @param DT The dominator tree of the current function.
- void addLoopBoundsToHeaderDomains(LoopInfo &LI, ScopDetection &SD,
- DominatorTree &DT);
+ void addLoopBoundsToHeaderDomain(Loop *L, LoopInfo &LI);
/// @brief Compute the branching constraints for each basic block in @p R.
///
Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=248125&r1=248124&r2=248125&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Sun Sep 20 11:15:32 2015
@@ -1,4 +1,4 @@
-//===--------- ScopInfo.cpp - Create Scops from LLVM IR ------------------===//
+
//
// The LLVM Compiler Infrastructure
//
@@ -850,10 +850,10 @@ static std::pair<__isl_give isl_set *, _
partitionSetParts(__isl_take isl_set *S, unsigned Dim) {
for (unsigned u = 0, e = isl_set_n_dim(S); u < e; u++)
- S = isl_set_lower_bound_si(S, isl_dim_set, u, u == Dim ? -1 : 0);
+ S = isl_set_lower_bound_si(S, isl_dim_set, u, 0);
unsigned NumDimsS = isl_set_n_dim(S);
- isl_set *OnlyDimS = S;
+ isl_set *OnlyDimS = isl_set_copy(S);
// Remove dimensions that are greater than Dim as they are not interesting.
assert(NumDimsS >= Dim + 1);
@@ -881,7 +881,7 @@ partitionSetParts(__isl_take isl_set *S,
// Remove the artificial upper bound parameters again.
BoundedParts = isl_set_remove_dims(BoundedParts, isl_dim_param, 0, Dim);
- isl_set *UnboundedParts = isl_set_complement(isl_set_copy(BoundedParts));
+ isl_set *UnboundedParts = isl_set_subtract(S, isl_set_copy(BoundedParts));
return std::make_pair(UnboundedParts, BoundedParts);
}
@@ -1560,6 +1560,7 @@ static inline unsigned getNumBlocksInReg
static inline __isl_give isl_set *addDomainDimId(__isl_take isl_set *Domain,
unsigned Dim, Loop *L) {
+ Domain = isl_set_lower_bound_si(Domain, isl_dim_set, Dim, -1);
isl_id *DimId =
isl_id_alloc(isl_set_get_ctx(Domain), nullptr, static_cast<void *>(L));
return isl_set_set_dim_id(Domain, isl_dim_set, Dim, DimId);
@@ -1595,7 +1596,6 @@ void Scop::buildDomains(Region *R, LoopI
return;
buildDomainsWithBranchConstraints(R, LI, SD, DT);
- addLoopBoundsToHeaderDomains(LI, SD, DT);
propagateDomainConstraints(R, LI, SD, DT);
}
@@ -1832,6 +1832,9 @@ void Scop::propagateDomainConstraints(Re
// Under the union of all predecessor conditions we can reach this block.
Domain = isl_set_coalesce(isl_set_intersect(Domain, PredDom));
+ if (BBLoop && BBLoop->getHeader() == BB)
+ addLoopBoundsToHeaderDomain(BBLoop, LI);
+
// Add assumptions for error blocks.
if (containsErrorBlock(RN)) {
IsOptimized = true;
@@ -1861,125 +1864,71 @@ createNextIterationMap(__isl_take isl_sp
return NextIterationMap;
}
-/// @brief Add @p L & all children to @p Loops if they are not in @p BoxedLoops.
-static inline void
-addLoopAndSubloops(Loop *L, SmallVectorImpl<Loop *> &Loops,
- const ScopDetection::BoxedLoopsSetTy &BoxedLoops) {
- if (BoxedLoops.count(L))
- return;
-
- Loops.push_back(L);
- for (Loop *Subloop : *L)
- addLoopAndSubloops(Subloop, Loops, BoxedLoops);
-}
-
-/// @brief Add loops in @p R to @p RegionLoops if they are not in @p BoxedLoops.
-static inline void
-collectLoopsInRegion(Region &R, LoopInfo &LI,
- SmallVector<Loop *, 8> &RegionLoops,
- const ScopDetection::BoxedLoopsSetTy &BoxedLoops) {
-
- SmallVector<Loop *, 8> Loops(LI.begin(), LI.end());
- while (!Loops.empty()) {
- Loop *L = Loops.pop_back_val();
-
- if (R.contains(L))
- addLoopAndSubloops(L, RegionLoops, BoxedLoops);
- else if (L->contains(R.getEntry()))
- Loops.append(L->begin(), L->end());
- }
-}
-
-/// @brief Create a set from @p Space with @p Dim fixed to 0.
-static __isl_give isl_set *
-createFirstIterationDomain(__isl_take isl_space *Space, unsigned Dim) {
- auto *Domain = isl_set_universe(Space);
- Domain = isl_set_fix_si(Domain, isl_dim_set, Dim, 0);
- return Domain;
-}
-
-void Scop::addLoopBoundsToHeaderDomains(LoopInfo &LI, ScopDetection &SD,
- DominatorTree &DT) {
- // We iterate over all loops in the SCoP, create the condition set under which
- // we will take the back edge, and then apply these restrictions to the
- // header.
-
- Region &R = getRegion();
- SmallVector<Loop *, 8> RegionLoops;
- collectLoopsInRegion(R, LI, RegionLoops, *SD.getBoxedLoops(&R));
-
- while (!RegionLoops.empty()) {
- Loop *L = RegionLoops.pop_back_val();
- int LoopDepth = getRelativeLoopDepth(L);
- assert(LoopDepth >= 0 && "Loop in region should have at least depth one");
-
- BasicBlock *HeaderBB = L->getHeader();
- isl_set *&HeaderBBDom = DomainMap[HeaderBB];
- isl_set *FirstIteration =
- createFirstIterationDomain(isl_set_get_space(HeaderBBDom), LoopDepth);
-
- isl_map *NextIterationMap =
- createNextIterationMap(isl_set_get_space(HeaderBBDom), LoopDepth);
-
- isl_set *UnionBackedgeCondition =
- isl_set_empty(isl_set_get_space(HeaderBBDom));
-
- SmallVector<llvm::BasicBlock *, 4> LatchBlocks;
- L->getLoopLatches(LatchBlocks);
-
- for (BasicBlock *LatchBB : LatchBlocks) {
- assert(DomainMap.count(LatchBB));
- isl_set *LatchBBDom = DomainMap[LatchBB];
- isl_set *BackedgeCondition = nullptr;
-
- BranchInst *BI = cast<BranchInst>(LatchBB->getTerminator());
- if (BI->isUnconditional())
- BackedgeCondition = isl_set_copy(LatchBBDom);
- else {
- SmallVector<isl_set *, 2> ConditionSets;
- int idx = BI->getSuccessor(0) != HeaderBB;
- buildConditionSets(*this, BI, L, LatchBBDom, ConditionSets);
-
- // Free the non back edge condition set as we do not need it.
- isl_set_free(ConditionSets[1 - idx]);
+void Scop::addLoopBoundsToHeaderDomain(Loop *L, LoopInfo &LI) {
+ int LoopDepth = getRelativeLoopDepth(L);
+ assert(LoopDepth >= 0 && "Loop in region should have at least depth one");
+
+ BasicBlock *HeaderBB = L->getHeader();
+ assert(DomainMap.count(HeaderBB));
+ isl_set *&HeaderBBDom = DomainMap[HeaderBB];
+
+ isl_map *NextIterationMap =
+ createNextIterationMap(isl_set_get_space(HeaderBBDom), LoopDepth);
+
+ isl_set *UnionBackedgeCondition =
+ isl_set_empty(isl_set_get_space(HeaderBBDom));
+
+ SmallVector<llvm::BasicBlock *, 4> LatchBlocks;
+ L->getLoopLatches(LatchBlocks);
+
+ for (BasicBlock *LatchBB : LatchBlocks) {
+ assert(DomainMap.count(LatchBB));
+ isl_set *LatchBBDom = DomainMap[LatchBB];
+ isl_set *BackedgeCondition = nullptr;
+
+ BranchInst *BI = cast<BranchInst>(LatchBB->getTerminator());
+ if (BI->isUnconditional())
+ BackedgeCondition = isl_set_copy(LatchBBDom);
+ else {
+ SmallVector<isl_set *, 2> ConditionSets;
+ int idx = BI->getSuccessor(0) != HeaderBB;
+ buildConditionSets(*this, BI, L, LatchBBDom, ConditionSets);
- BackedgeCondition = ConditionSets[idx];
- }
+ // Free the non back edge condition set as we do not need it.
+ isl_set_free(ConditionSets[1 - idx]);
- int LatchLoopDepth = getRelativeLoopDepth(LI.getLoopFor(LatchBB));
- assert(LatchLoopDepth >= LoopDepth);
- BackedgeCondition =
- isl_set_project_out(BackedgeCondition, isl_dim_set, LoopDepth + 1,
- LatchLoopDepth - LoopDepth);
- UnionBackedgeCondition =
- isl_set_union(UnionBackedgeCondition, BackedgeCondition);
+ BackedgeCondition = ConditionSets[idx];
}
- isl_map *ForwardMap = isl_map_lex_le(isl_set_get_space(HeaderBBDom));
- for (int i = 0; i < LoopDepth; i++)
- ForwardMap = isl_map_equate(ForwardMap, isl_dim_in, i, isl_dim_out, i);
-
- isl_set *UnionBackedgeConditionComplement =
- isl_set_complement(UnionBackedgeCondition);
- UnionBackedgeConditionComplement = isl_set_lower_bound_si(
- UnionBackedgeConditionComplement, isl_dim_set, LoopDepth, 0);
- UnionBackedgeConditionComplement =
- isl_set_apply(UnionBackedgeConditionComplement, ForwardMap);
- HeaderBBDom =
- isl_set_subtract(HeaderBBDom, UnionBackedgeConditionComplement);
-
- auto Parts = partitionSetParts(HeaderBBDom, LoopDepth);
-
- // If a loop has an unbounded back edge condition part (here Parts.first)
- // we do not want to assume the header will even be executed for the first
- // iteration of an execution that will lead to an infinite loop. While it
- // would not be wrong to do so, it does not seem helpful.
- // TODO: Use the unbounded part to build runtime assumptions.
- FirstIteration = isl_set_subtract(FirstIteration, Parts.first);
-
- HeaderBBDom = isl_set_apply(Parts.second, NextIterationMap);
- HeaderBBDom = isl_set_coalesce(isl_set_union(HeaderBBDom, FirstIteration));
- }
+ int LatchLoopDepth = getRelativeLoopDepth(LI.getLoopFor(LatchBB));
+ assert(LatchLoopDepth >= LoopDepth);
+ BackedgeCondition =
+ isl_set_project_out(BackedgeCondition, isl_dim_set, LoopDepth + 1,
+ LatchLoopDepth - LoopDepth);
+ UnionBackedgeCondition =
+ isl_set_union(UnionBackedgeCondition, BackedgeCondition);
+ }
+
+ isl_map *ForwardMap = isl_map_lex_le(isl_set_get_space(HeaderBBDom));
+ for (int i = 0; i < LoopDepth; i++)
+ ForwardMap = isl_map_equate(ForwardMap, isl_dim_in, i, isl_dim_out, i);
+
+ isl_set *UnionBackedgeConditionComplement =
+ isl_set_complement(UnionBackedgeCondition);
+ UnionBackedgeConditionComplement = isl_set_lower_bound_si(
+ UnionBackedgeConditionComplement, isl_dim_set, LoopDepth, 0);
+ UnionBackedgeConditionComplement =
+ isl_set_apply(UnionBackedgeConditionComplement, ForwardMap);
+ HeaderBBDom = isl_set_subtract(HeaderBBDom, UnionBackedgeConditionComplement);
+ HeaderBBDom = isl_set_apply(HeaderBBDom, NextIterationMap);
+
+ auto Parts = partitionSetParts(HeaderBBDom, LoopDepth);
+ HeaderBBDom = Parts.second;
+
+ isl_set *UnboundedCtx = isl_set_params(Parts.first);
+ isl_set *BoundedCtx = isl_set_complement(UnboundedCtx);
+ // TODO: Use the unbounded part to build runtime assumptions.
+ isl_set_free(BoundedCtx);
}
void Scop::buildAliasChecks(AliasAnalysis &AA) {
Modified: polly/trunk/test/Isl/CodeGen/phi_scalar_simple_1.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/phi_scalar_simple_1.ll?rev=248125&r1=248124&r2=248125&view=diff
==============================================================================
--- polly/trunk/test/Isl/CodeGen/phi_scalar_simple_1.ll (original)
+++ polly/trunk/test/Isl/CodeGen/phi_scalar_simple_1.ll Sun Sep 20 11:15:32 2015
@@ -22,13 +22,13 @@ entry:
br label %for.cond
; CHECK-LABEL: polly.merge_new_and_old:
-; CHECK: %x.addr.0.merge = phi i32 [ %x.addr.0.final_reload, %polly.merge20 ], [ %x.addr.0, %for.cond ]
+; CHECK: %x.addr.0.merge = phi i32 [ %x.addr.0.final_reload, %polly.merge ], [ %x.addr.0, %for.cond ]
; CHECK: ret i32 %x.addr.0.merge
; CHECK-LABEL: polly.start:
; CHECK-NEXT: store i32 %x, i32* %x.addr.0.phiops
-; CHECK-LABEL: polly.merge20:
+; CHECK-LABEL: polly.merge:
; CHECK: %x.addr.0.final_reload = load i32, i32* %x.addr.0.s2a
for.cond: ; preds = %for.inc4, %entry
Modified: polly/trunk/test/ScopInfo/multiple_exiting_blocks.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multiple_exiting_blocks.ll?rev=248125&r1=248124&r2=248125&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multiple_exiting_blocks.ll (original)
+++ polly/trunk/test/ScopInfo/multiple_exiting_blocks.ll Sun Sep 20 11:15:32 2015
@@ -1,7 +1,7 @@
; RUN: opt %loadPolly -polly-scops -polly-detect-unprofitable -analyze < %s | FileCheck %s
;
; CHECK: Domain :=
-; CHECK: [N, P, Q] -> { Stmt_if_end[i0] : (i0 >= 0 and i0 <= 1 + Q and i0 <= -1 + P and i0 <= -1 + N) or (P <= -1 and i0 >= 1 + P - Q and i0 >= 0 and i0 <= 1 + Q and i0 <= -1 + N); Stmt_if_end[0] : (N >= 1 and P <= -2 and Q <= -2) or (N >= 1 and P >= 1 and Q <= -2) or (P = -1 and N >= 1) }
+; CHECK: [N, P, Q] -> { Stmt_if_end[i0] : (i0 >= 0 and i0 <= 1 + Q and i0 <= -1 + P and i0 <= -1 + N) or (P <= -1 and i0 >= 2 + P and i0 >= 0 and i0 <= 1 + Q and i0 <= -1 + N); Stmt_if_end[0] : (N >= 1 and P <= -2 and Q <= -2) or (N >= 1 and P >= 1 and Q <= -2) or (P = -1 and N >= 1) }
;
; void f(int *A, int N, int P, int Q) {
; for (int i = 0; i < N; i++) {
More information about the llvm-commits
mailing list