[flang-commits] [lld] [llvm] [clang] [libc] [compiler-rt] [libcxx] [flang] [lldb] [clang-tools-extra] [VPlan] Implement cloning of VPlans. (PR #73158)

via flang-commits flang-commits at lists.llvm.org
Thu Jan 25 06:42:49 PST 2024


================
@@ -614,6 +614,61 @@ void VPBasicBlock::print(raw_ostream &O, const Twine &Indent,
   printSuccessors(O, Indent);
 }
 #endif
+static void cloneCFG(VPBlockBase *Entry,
+                     DenseMap<VPBlockBase *, VPBlockBase *> &Old2NewVPBlocks);
+
+static VPBlockBase *cloneVPB(VPBlockBase *BB) {
+  if (auto *VPBB = dyn_cast<VPBasicBlock>(BB)) {
+    auto *NewBlock = new VPBasicBlock(VPBB->getName());
+    for (VPRecipeBase &R : *VPBB)
+      NewBlock->appendRecipe(R.clone());
+    return NewBlock;
+  }
+
+  auto *VPR = cast<VPRegionBlock>(BB);
+  DenseMap<VPBlockBase *, VPBlockBase *> Old2NewVPBlocks;
+  DenseMap<VPValue *, VPValue *> Old2NewVPValues;
+  cloneCFG(VPR->getEntry(), Old2NewVPBlocks);
+  VPBlockBase *NewEntry = Old2NewVPBlocks[VPR->getEntry()];
+  auto *NewRegion =
+      new VPRegionBlock(NewEntry, Old2NewVPBlocks[VPR->getExiting()],
+                        VPR->getName(), VPR->isReplicator());
+  for (VPBlockBase *Block : vp_depth_first_shallow(NewEntry))
+    Block->setParent(NewRegion);
+  return NewRegion;
+}
+
+// Clone the CFG for all nodes reachable from \p Entry, this includes cloning
+// the blocks and their recipes. Operands of cloned recipes will NOT be updated.
+// Remapping of operands must be done separately.
+static void cloneCFG(VPBlockBase *Entry,
+                     DenseMap<VPBlockBase *, VPBlockBase *> &Old2NewVPBlocks) {
+  ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>> RPOT(
+      Entry);
+  for (VPBlockBase *BB : RPOT) {
+    VPBlockBase *NewBB = cloneVPB(BB);
+    for (VPBlockBase *Pred : BB->getPredecessors())
+      VPBlockUtils::connectBlocks(Old2NewVPBlocks[Pred], NewBB);
+
+    Old2NewVPBlocks[BB] = NewBB;
+  }
+
+#if !defined(NDEBUG)
+  // Verify that the order of predecessors and successors matches in the cloned
+  // version.
+  ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>>
+      NewRPOT(Old2NewVPBlocks[Entry]);
+  for (const auto &[OldBB, NewBB] : zip(RPOT, NewRPOT)) {
+    for (const auto &[OldPred, NewPred] :
+         zip(OldBB->getPredecessors(), NewBB->getPredecessors()))
+      assert(NewPred == Old2NewVPBlocks[OldPred] && "Different predecessors");
+
+    for (const auto &[OldSucc, NewSucc] :
+         zip(OldBB->successors(), NewBB->successors()))
+      assert(NewSucc == Old2NewVPBlocks[OldSucc] && "Different successors");
+  }
+#endif
----------------
ayalz wrote:

Return `Old2NewVPBlocks[Entry]` along with (the last) `NewBB`, or along with `Old2NewVPBlocks[Exit]` where Exit = *RPOT->end()?

https://github.com/llvm/llvm-project/pull/73158


More information about the flang-commits mailing list