[llvm] 6e20519 - [VPlan] Add VPPhiAccessors to provide interface for phi recipes (NFC) (#129388)
via llvm-commits
llvm-commits at lists.llvm.org
Sun May 4 05:47:46 PDT 2025
Author: Florian Hahn
Date: 2025-05-04T13:47:42+01:00
New Revision: 6e205197178376cfbe3dc5f568bc880b23d4bc8b
URL: https://github.com/llvm/llvm-project/commit/6e205197178376cfbe3dc5f568bc880b23d4bc8b
DIFF: https://github.com/llvm/llvm-project/commit/6e205197178376cfbe3dc5f568bc880b23d4bc8b.diff
LOG: [VPlan] Add VPPhiAccessors to provide interface for phi recipes (NFC) (#129388)
Add a VPPhiAccessors class to provide interfaces to access incoming
values and blocks.
The first user is VPWidenPhiRecipe, with the other phi-like recipes
following soon.
This will also be used to verify def-use chains where users are phi-like
recipes, simplifying https://github.com/llvm/llvm-project/pull/124838.
PR: https://github.com/llvm/llvm-project/pull/129388
Added:
Modified:
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
llvm/lib/Transforms/Vectorize/VPlan.cpp
llvm/lib/Transforms/Vectorize/VPlan.h
llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 2632dac9900ef..13bbfb77e06ce 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -2876,9 +2876,9 @@ void InnerLoopVectorizer::fixNonInductionPHIs(VPTransformState &State) {
PHINode *NewPhi = cast<PHINode>(State.get(VPPhi));
// Make sure the builder has a valid insert point.
Builder.SetInsertPoint(NewPhi);
- for (unsigned Idx = 0; Idx < VPPhi->getNumOperands(); ++Idx) {
+ for (unsigned Idx = 0; Idx < VPPhi->getNumIncoming(); ++Idx) {
VPValue *Inc = VPPhi->getIncomingValue(Idx);
- VPBasicBlock *VPBB = VPPhi->getIncomingBlock(Idx);
+ const VPBasicBlock *VPBB = VPPhi->getIncomingBlock(Idx);
NewPhi->addIncoming(State.get(Inc), State.CFG.VPBB2IRBB[VPBB]);
}
}
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp
index 749ef4fe83bc8..465f13c49f48b 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp
@@ -789,6 +789,25 @@ InstructionCost VPBasicBlock::cost(ElementCount VF, VPCostContext &Ctx) {
return Cost;
}
+const VPBasicBlock *VPBasicBlock::getCFGPredecessor(unsigned Idx) const {
+ const VPBlockBase *Pred = nullptr;
+ if (getNumPredecessors() > 0) {
+ Pred = getPredecessors()[Idx];
+ } else {
+ auto *Region = getParent();
+ assert(Region && !Region->isReplicator() && Region->getEntry() == this &&
+ "must be in the entry block of a non-replicate region");
+ assert(Idx < 2 && Region->getNumPredecessors() == 1 &&
+ "loop region has a single predecessor (preheader), its entry block "
+ "has 2 incoming blocks");
+
+ // Idx == 0 selects the predecessor of the region, Idx == 1 selects the
+ // region itself whose exiting block feeds the phi across the backedge.
+ Pred = Idx == 0 ? Region->getSinglePredecessor() : Region;
+ }
+ return Pred->getExitingBasicBlock();
+}
+
InstructionCost VPRegionBlock::cost(ElementCount VF, VPCostContext &Ctx) {
if (!isReplicator()) {
InstructionCost Cost = 0;
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 89c77f2189b1f..c77c944c01a36 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -1171,6 +1171,28 @@ class VPIRInstruction : public VPRecipeBase {
void extractLastLaneOfFirstOperand(VPBuilder &Builder);
};
+/// Helper type to provide functions to access incoming values and blocks for
+/// phi-like recipes.
+class VPPhiAccessors {
+protected:
+ /// Return a VPRecipeBase* to the current object.
+ virtual const VPRecipeBase *getAsRecipe() const = 0;
+
+public:
+ virtual ~VPPhiAccessors() = default;
+
+ /// Returns the incoming VPValue with index \p Idx.
+ VPValue *getIncomingValue(unsigned Idx) const {
+ return getAsRecipe()->getOperand(Idx);
+ }
+
+ /// Returns the incoming block with index \p Idx.
+ const VPBasicBlock *getIncomingBlock(unsigned Idx) const;
+
+ /// Returns the number of incoming values, also number of incoming blocks.
+ unsigned getNumIncoming() const { return getAsRecipe()->getNumOperands(); }
+};
+
/// An overlay for VPIRInstructions wrapping PHI nodes enabling convenient use
/// cast/dyn_cast/isa and execute() implementation. A single VPValue operand is
/// allowed, and it is used to add a new incoming value for the single
@@ -1974,10 +1996,13 @@ class VPWidenPointerInductionRecipe : public VPWidenInductionRecipe,
/// recipe is placed in an entry block to a (non-replicate) region, it must have
/// exactly 2 incoming values, the first from the predecessor of the region and
/// the second from the exiting block of the region.
-class VPWidenPHIRecipe : public VPSingleDefRecipe {
+class VPWidenPHIRecipe : public VPSingleDefRecipe, public VPPhiAccessors {
/// Name to use for the generated IR instruction for the widened phi.
std::string Name;
+protected:
+ const VPRecipeBase *getAsRecipe() const override { return this; }
+
public:
/// Create a new VPWidenPHIRecipe for \p Phi with start value \p Start and
/// debug location \p DL.
@@ -2005,12 +2030,6 @@ class VPWidenPHIRecipe : public VPSingleDefRecipe {
void print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const override;
#endif
-
- /// Returns the \p I th incoming VPBasicBlock.
- VPBasicBlock *getIncomingBlock(unsigned I);
-
- /// Returns the \p I th incoming VPValue.
- VPValue *getIncomingValue(unsigned I) { return getOperand(I); }
};
/// A recipe for handling first-order recurrence phis. The start value is the
@@ -3329,6 +3348,12 @@ class VPBasicBlock : public VPBlockBase {
/// the cloned recipes.
VPBasicBlock *clone() override;
+ /// Returns the predecessor block at index \p Idx with the predecessors as per
+ /// the corresponding plain CFG. If the block is an entry block to a region,
+ /// the first predecessor is the single predecessor of a region, and the
+ /// second predecessor is the exiting block of the region.
+ const VPBasicBlock *getCFGPredecessor(unsigned Idx) const;
+
protected:
/// Execute the recipes in the IR basic block \p BB.
void executeRecipes(VPTransformState *State, BasicBlock *BB);
@@ -3343,6 +3368,11 @@ class VPBasicBlock : public VPBlockBase {
BasicBlock *createEmptyBasicBlock(VPTransformState &State);
};
+inline const VPBasicBlock *
+VPPhiAccessors::getIncomingBlock(unsigned Idx) const {
+ return getAsRecipe()->getParent()->getCFGPredecessor(Idx);
+}
+
/// A special type of VPBasicBlock that wraps an existing IR basic block.
/// Recipes of the block get added before the first non-phi instruction in the
/// wrapped block.
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index 2108fbadb51d8..7c01dec80da4e 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -3684,27 +3684,6 @@ void VPReductionPHIRecipe::print(raw_ostream &O, const Twine &Indent,
}
#endif
-VPBasicBlock *VPWidenPHIRecipe::getIncomingBlock(unsigned I) {
- VPBasicBlock *Parent = getParent();
- VPBlockBase *Pred = nullptr;
- if (Parent->getNumPredecessors() > 0) {
- Pred = Parent->getPredecessors()[I];
- } else {
- auto *Region = Parent->getParent();
- assert(Region && !Region->isReplicator() && Region->getEntry() == Parent &&
- "must be in the entry block of a non-replicate region");
- assert(
- I < 2 && getNumOperands() == 2 &&
- "when placed in an entry block, only 2 incoming blocks are available");
-
- // I == 0 selects the predecessor of the region, I == 1 selects the region
- // itself whose exiting block feeds the phi across the backedge.
- Pred = I == 0 ? Region->getSinglePredecessor() : Region;
- }
-
- return Pred->getExitingBasicBlock();
-}
-
void VPWidenPHIRecipe::execute(VPTransformState &State) {
assert(EnableVPlanNativePath &&
"Non-native vplans are not expected to have VPWidenPHIRecipes.");
More information about the llvm-commits
mailing list