[PATCH] D100260: [VPlan] Merge predicated-triangle regions, after sinking.
Ayal Zaks via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun May 23 01:26:29 PDT 2021
Ayal added a comment.
Nice optimization exercising VPlan capabilities!
Should always be a win, so ok to avoid cost-model considerations, although cost improvement is left unaccounted for.
An alternative may be to try and build larger replicating regions to begin with, but sinkScalarOperands may contribute as well.
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:152
+ if (MergeBB->getNumSuccessors() != 0 || ThenBB->getNumSuccessors() != 1 ||
+ ThenBB->getSuccessors()[0] != MergeBB)
+ return nullptr;
----------------
Can check `|| ThenBB->getSingleSuccessor() != MergeBB`
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:159
+ ReversePostOrderTraversal<VPBlockRecursiveTraversalWrapper<VPBlockBase *>>
+ RPOT(VPBlockRecursiveTraversalWrapper<VPBlockBase *>(Plan.getEntry()));
+
----------------
Is RPOT order vital, or would a simple DFS do, given that the pairs of regions handled are dom-postdom pairs?
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:175
+
+ auto *Succ = dyn_cast<VPBasicBlock>(Region->getSingleSuccessor());
+ if (!Succ || !Succ->getSingleSuccessor() || !Succ->empty())
----------------
dyn_cast_or_null would also take care of checking if Region has a single successor?
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:179
+
+ auto *SuccRegion = dyn_cast<VPRegionBlock>(Succ->getSingleSuccessor());
+ if (!SuccRegion || Region->getPredicate() != SuccRegion->getPredicate())
----------------
dyn_cast_or_null would also take care of checking if Succ has a single successor?
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:180
+ auto *SuccRegion = dyn_cast<VPRegionBlock>(Succ->getSingleSuccessor());
+ if (!SuccRegion || Region->getPredicate() != SuccRegion->getPredicate())
+ continue;
----------------
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?
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:197
+ auto *PhiR = dyn_cast<VPWidenPHIRecipe>(UI);
+ if (!PhiR || PhiR->getRecurrenceDescriptor())
+ continue;
----------------
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.
================
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))) {
----------------
Note: this takes care of fusion-admitting, lane-by-lane dependencies, right?
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:225
+ continue;
+ U->setOperand(I, IncV);
+ }
----------------
`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?
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:245
+ delete Region;
+ }
+
----------------
delete 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)
----------------
rely on order of successors?
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:194
+
+ // If a recipe is used by a first-order recurrence phi, we cannot move it.
+ if (any_of(*ThenRegion, [](VPRecipeBase &R) {
----------------
because ... it may conflict with sink-after?
comment here should probably state what it is we can move.
Could there potentially be fusion-preventing dependencies between the two regions (packing/unpacking?), or does the lack of recipes in the 'middle' block guarantee their absence?
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