[PATCH] D100260: [VPlan] Merge predicated-triangle regions, after sinking.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 12 14:32:27 PDT 2021


fhahn added inline comments.


================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:159
+  ReversePostOrderTraversal<VPBlockRecursiveTraversalWrapper<VPBlockBase *>>
+      RPOT(VPBlockRecursiveTraversalWrapper<VPBlockBase *>(Plan.getEntry()));
+
----------------
Ayal wrote:
> Is RPOT order vital, or would a simple DFS do, given that the pairs of regions handled are dom-postdom pairs?
No that's not needed. Updated to collect the relevant blocks using `VPBlockUtils::blocksOnly<VPRegionBlock>`


================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:180
+    auto *SuccRegion = dyn_cast<VPRegionBlock>(Succ->getSingleSuccessor());
+    if (!SuccRegion || Region->getPredicate() != SuccRegion->getPredicate())
+      continue;
----------------
Ayal wrote:
> Ayal wrote:
> > This may be somewhat misleading, and currently untestable: replicated regions are (currently) formed for unpredicatable instructions, by 'legacy' vectorizer which does not model block predicates at all. Assert the predicates are null?
> OTOH, need to check that both VPBranchOnMaskRecipes use the same mask. Potentially have getPredicate() retrieve this mask? Test that two regions having distinct masks are not merged.
`getPredicate` was wrong. Currently `CondBit` is kept up-to-date. I updated the code to use it. Perhaps we should remove the CondBit field and implement `getCondBit` with a lookup of `branch-on-mask` recipes as follow-up?


================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:197
+            auto *PhiR = dyn_cast<VPWidenPHIRecipe>(UI);
+            if (!PhiR || PhiR->getRecurrenceDescriptor())
+              continue;
----------------
Ayal wrote:
> Ayal wrote:
> > May be good to name this lambda, e.g., IsImmovableRecipe.
> > 
> > Check first-order recurrence (more) directly, by
> > 
> > ```
> >   if (PhiR && !PhiR->getRecurrenceDescriptor())
> >     return true
> > ```
> > ?
> > Would be good to have a clear API for such a query, if not a dedicated isa<> recipe.
> > 
> ThenRegion is expected to have no phi recipes, let alone header phi recipes, but only replicate recipes? Perhaps something potentially worth Verifying.
> 
> May be clearer to rename variables Region1/ThenBB1/MergeBB1, Region2/ThenBB2/MergeBB2, MiddleBB
> ThenRegion is expected to have no phi recipes, let alone header phi recipes, but only replicate recipes? Perhaps something potentially worth Verifying.

Added the assertion.

> May be clearer to rename variables Region1/ThenBB1/MergeBB1, Region2/ThenBB2/MergeBB2, MiddleBB

Great idea, the suggested names are much clearer!


================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:215
+    // merge block. Update all users inside the successor region to use the
+    // original values.
+    for (VPRecipeBase &ToMove : make_early_inc_range(reverse(*MergeRegion))) {
----------------
Ayal wrote:
> Note: this takes care of fusion-admitting, lane-by-lane dependencies, right?
Yes, it updates the uses outside the merged region.



================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:216
+    // original values.
+    for (VPRecipeBase &ToMove : make_early_inc_range(reverse(*MergeRegion))) {
+      VPValue *IncV = cast<VPPredInstPHIRecipe>(&ToMove)->getOperand(0);
----------------
Ayal wrote:
> Is the reverse required? Could repeatedly take (r)begin until empty.
> 
> Initially each MergeRegion has a single PredInstPHIRecipe, but multiple recipes would appear after merging, right? Worth testing merging three regions into one, if not done so already.
I added a test `merge_3_replicate_region`, which exposed a problem with multiple `VPPredInstPHIRecipes` in the same block. I put up D104188 to fix that.


================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:225
+            continue;
+          U->setOperand(I, IncV);
+        }
----------------
Ayal wrote:
> `I` could appear as multiple operands of `U`, so avoid early-exit on first match, right? Perhaps worth a test.
> 
> Assert that at-least one such operand was found and (re)set?
Yes, there could be multiple uses of  `ToMove` in `U`. I still need to add a test case for that.


================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:245
+    delete Region;
+  }
+
----------------
Ayal wrote:
> delete DeletedBlocks?
moved the deletion outside to clean up all blocks in DeletedBlocks.


================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:153
+  auto *ThenBB = dyn_cast<VPBasicBlock>(EntryBB->getSuccessors()[0]);
+  auto *MergeBB = dyn_cast<VPBasicBlock>(EntryBB->getSuccessors()[1]);
+  if (!ThenBB || !MergeBB)
----------------
Ayal wrote:
> rely on order of successors?
Yes. I updated the code to check if the single successor of `ThenBB` is `MergeBB`. If that's not the case, they are swapped and must pass the check below.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100260/new/

https://reviews.llvm.org/D100260



More information about the llvm-commits mailing list