[PATCH] D100751: [VPlan] Properly handle sinking of replicate regions.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 19 04:09:15 PDT 2021


fhahn created this revision.
fhahn added reviewers: rengolin, Ayal, dmgreen, gilr.
Herald added subscribers: tschuett, psnobl, rogfer01, bollu, hiraditya.
fhahn requested review of this revision.
Herald added a subscriber: vkmr.
Herald added a project: LLVM.

This patch updates the code that sinks recipes required for first-order
recurrences to properly handle replicate-regions. At the moment, the
code would just move the replicate recipe out of its replicate-region,
producing an invalid VPlan.

When sinking a recipe in a replicate-region, we have to sink the whole
region. To do that, we first need to split the block at the target
recipe and move the region in between.

This patch also adds a splitAt helper to VPBasicBlock to split a
VPBasicBlock at a given iterator.

I think we also need to deal with the case when the target is a
replicate region also. I'll put up a patch once I constructed a test
for that scenario.

Fixes PR50009.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D100751

Files:
  llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
  llvm/lib/Transforms/Vectorize/VPlan.cpp
  llvm/lib/Transforms/Vectorize/VPlan.h


Index: llvm/lib/Transforms/Vectorize/VPlan.h
===================================================================
--- llvm/lib/Transforms/Vectorize/VPlan.h
+++ llvm/lib/Transforms/Vectorize/VPlan.h
@@ -1509,6 +1509,11 @@
 
   void dropAllReferences(VPValue *NewValue) override;
 
+  /// Split current block at \p SplitAt by inserting a new block between the
+  /// current block and its successors and mobing all recipes starting at
+  /// SplitAt to the new block. Returns the new block.
+  VPBasicBlock *splitAt(iterator SplitAt);
+
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
   /// Print this VPBsicBlock to \p O, prefixing all lines with \p Indent. \p
   /// SlotTracker is used to print unnamed VPValue's using consequtive numbers.
Index: llvm/lib/Transforms/Vectorize/VPlan.cpp
===================================================================
--- llvm/lib/Transforms/Vectorize/VPlan.cpp
+++ llvm/lib/Transforms/Vectorize/VPlan.cpp
@@ -403,6 +403,31 @@
   }
 }
 
+VPBasicBlock *VPBasicBlock::splitAt(iterator SplitAt) {
+  assert(SplitAt->getParent() == this);
+
+  SmallVector<VPBlockBase *, 2> Succs(getSuccessors().begin(),
+                                      getSuccessors().end());
+  // First, disconnect the current block from its successors.
+  for (VPBlockBase *Succ : Succs)
+    VPBlockUtils::disconnectBlocks(this, Succ);
+
+  // Create new empty block after the block to split.
+  auto *SplitBlock = new VPBasicBlock(getName() + ".split");
+  VPBlockUtils::insertBlockAfter(SplitBlock, this);
+
+  // Add successors for block to split to new block.
+  for (VPBlockBase *Succ : Succs)
+    VPBlockUtils::connectBlocks(SplitBlock, Succ);
+
+  // Finally, move the recipes starting at SplitAt to new block.
+  for (VPRecipeBase &ToMove :
+       make_early_inc_range(make_range(SplitAt, this->end())))
+    ToMove.moveBefore(*SplitBlock, SplitBlock->end());
+
+  return SplitBlock;
+}
+
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
 void VPBasicBlock::print(raw_ostream &O, const Twine &Indent,
                          VPSlotTracker &SlotTracker) const {
Index: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
===================================================================
--- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -8976,6 +8976,35 @@
         continue;
       }
     }
+
+    // If the source is a predicate replicate recipe, we need to move the whole
+    // replicate region, which should only contain a single recipe in the main
+    // block.
+    auto *RepR = dyn_cast<VPReplicateRecipe>(Sink);
+    if (RepR && RepR->isPredicated()) {
+      auto *Region =
+          dyn_cast_or_null<VPRegionBlock>(RepR->getParent()->getParent());
+      assert(Region->isReplicator() && RepR->getParent()->size() == 1 &&
+             "parent must be a replicator with a single recipe");
+      auto *SplitBlock =
+          Target->getParent()->splitAt(std::next(Target->getIterator()));
+
+      auto *Pred = Region->getSinglePredecessor();
+      auto *Succ = Region->getSingleSuccessor();
+      VPBlockUtils::disconnectBlocks(Pred, Region);
+      VPBlockUtils::disconnectBlocks(Region, Succ);
+      VPBlockUtils::connectBlocks(Pred, Succ);
+
+      auto *SplitPred = SplitBlock->getSinglePredecessor();
+
+      VPBlockUtils::disconnectBlocks(SplitPred, SplitBlock);
+      VPBlockUtils::connectBlocks(SplitPred, Region);
+      VPBlockUtils::connectBlocks(Region, SplitBlock);
+      if (VPBB == SplitPred)
+        VPBB = SplitBlock;
+      continue;
+    }
+
     Sink->moveAfter(Target);
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D100751.338477.patch
Type: text/x-patch
Size: 3605 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210419/98e8fea2/attachment.bin>


More information about the llvm-commits mailing list