[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