[libcxx-commits] [lld] [llvm] [clang] [libc] [compiler-rt] [libcxx] [flang] [lldb] [clang-tools-extra] [VPlan] Implement cloning of VPlans. (PR #73158)
via libcxx-commits
libcxx-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 libcxx-commits
mailing list