[clang] [lld] [libc] [flang] [lldb] [libcxx] [clang-tools-extra] [llvm] [compiler-rt] [VPlan] Implement cloning of VPlans. (PR #73158)
Florian Hahn via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 26 03:18:34 PST 2024
================
@@ -982,6 +1037,92 @@ void VPlan::updateDominatorTree(DominatorTree *DT, BasicBlock *LoopHeaderBB,
assert(DT->verify(DominatorTree::VerificationLevel::Fast));
}
+static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry,
+ DenseMap<VPValue *, VPValue *> &Old2NewVPValues) {
+ // Update the operands of all cloned recipes starting at NewEntry. This
+ // traverses all reachable blocks. This is done in two steps, to handle cycles
+ // in PHI recipes.
+ ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<VPBlockBase *>>
+ OldDeepRPOT(Entry);
+ ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<VPBlockBase *>>
+ NewDeepRPOT(NewEntry);
+ // First, collect all mappings from old to new VPValues defined by cloned
+ // recipes.
+ for (const auto &[OldBB, NewBB] :
+ zip(VPBlockUtils::blocksOnly<VPBasicBlock>(OldDeepRPOT),
+ VPBlockUtils::blocksOnly<VPBasicBlock>(NewDeepRPOT))) {
+ assert(OldBB->getRecipeList().size() == NewBB->getRecipeList().size() &&
+ "blocks must have the same number of recipes");
+
+ for (const auto &[OldR, NewR] : zip(*OldBB, *NewBB)) {
+ assert(OldR.getNumOperands() == NewR.getNumOperands() &&
+ "recipes must have the same number of operands");
+ assert(OldR.getNumDefinedValues() == NewR.getNumDefinedValues() &&
+ "recipes must define the same number of operands");
+ for (const auto &[OldV, NewV] :
+ zip(OldR.definedValues(), NewR.definedValues()))
+ Old2NewVPValues[OldV] = NewV;
+ }
+ }
+
+ // Update all operands to use cloned VPValues.
+ for (VPBasicBlock *NewBB :
+ VPBlockUtils::blocksOnly<VPBasicBlock>(NewDeepRPOT)) {
+ for (VPRecipeBase &NewR : *NewBB)
+ for (unsigned I = 0, E = NewR.getNumOperands(); I != E; ++I) {
+ VPValue *NewOp = Old2NewVPValues.lookup(NewR.getOperand(I));
+ NewR.setOperand(I, NewOp);
+ }
+ }
+}
+
+VPlan *VPlan::clone() {
+ DenseMap<VPValue *, VPValue *> Old2NewVPValues;
+
+ // Clone blocks.
+ VPBlockBase *NewPreheader = cloneVPB(Preheader);
+ const auto &[NewEntry, __] = cloneSESE(getEntry());
+
+ // Create VPlan, clone live-ins and remap operands in the cloned blocks.
+ auto *NewPlan =
+ new VPlan(cast<VPBasicBlock>(NewPreheader), cast<VPBasicBlock>(NewEntry));
+ for (VPValue *OldLiveIn : VPLiveInsToFree) {
+ VPValue *NewLiveIn = new VPValue(OldLiveIn->getLiveInIRValue());
+ NewPlan->VPLiveInsToFree.push_back(NewLiveIn);
+ Old2NewVPValues[OldLiveIn] = NewLiveIn;
+ }
+ Old2NewVPValues[&VectorTripCount] = &NewPlan->VectorTripCount;
+ Old2NewVPValues[&VFxUF] = &NewPlan->VFxUF;
+ if (BackedgeTakenCount) {
+ NewPlan->BackedgeTakenCount = new VPValue();
+ Old2NewVPValues[BackedgeTakenCount] = NewPlan->BackedgeTakenCount;
+ }
+ assert(TripCount && "trip count must be set");
+ if (TripCount->isLiveIn())
+ Old2NewVPValues[TripCount] = new VPValue(TripCount->getLiveInIRValue());
+ // else NewTripCount will be created and inserted into Old2NewVPValues when
+ // TripCount is cloned. In any case NewPlan->TripCount is updated below.
+
+ remapOperands(Preheader, NewPreheader, Old2NewVPValues);
+ remapOperands(Entry, NewEntry, Old2NewVPValues);
+
+ // Clone live-outs.
+ for (const auto &[_, LO] : LiveOuts)
+ NewPlan->addLiveOut(LO->getPhi(), Old2NewVPValues[LO->getOperand(0)]);
+
+ // Initialize remaining fields of cloned VPlan.
+ NewEntry->setPlan(NewPlan);
+ NewPreheader->setPlan(NewPlan);
----------------
fhahn wrote:
Removed, thanks!
https://github.com/llvm/llvm-project/pull/73158
More information about the cfe-commits
mailing list