Skip to content

Commit 6e20519

Browse files
authored
[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 #124838. PR: #129388
1 parent 1b60b83 commit 6e20519

File tree

4 files changed

+58
-30
lines changed

4 files changed

+58
-30
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2876,9 +2876,9 @@ void InnerLoopVectorizer::fixNonInductionPHIs(VPTransformState &State) {
28762876
PHINode *NewPhi = cast<PHINode>(State.get(VPPhi));
28772877
// Make sure the builder has a valid insert point.
28782878
Builder.SetInsertPoint(NewPhi);
2879-
for (unsigned Idx = 0; Idx < VPPhi->getNumOperands(); ++Idx) {
2879+
for (unsigned Idx = 0; Idx < VPPhi->getNumIncoming(); ++Idx) {
28802880
VPValue *Inc = VPPhi->getIncomingValue(Idx);
2881-
VPBasicBlock *VPBB = VPPhi->getIncomingBlock(Idx);
2881+
const VPBasicBlock *VPBB = VPPhi->getIncomingBlock(Idx);
28822882
NewPhi->addIncoming(State.get(Inc), State.CFG.VPBB2IRBB[VPBB]);
28832883
}
28842884
}

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,25 @@ InstructionCost VPBasicBlock::cost(ElementCount VF, VPCostContext &Ctx) {
789789
return Cost;
790790
}
791791

792+
const VPBasicBlock *VPBasicBlock::getCFGPredecessor(unsigned Idx) const {
793+
const VPBlockBase *Pred = nullptr;
794+
if (getNumPredecessors() > 0) {
795+
Pred = getPredecessors()[Idx];
796+
} else {
797+
auto *Region = getParent();
798+
assert(Region && !Region->isReplicator() && Region->getEntry() == this &&
799+
"must be in the entry block of a non-replicate region");
800+
assert(Idx < 2 && Region->getNumPredecessors() == 1 &&
801+
"loop region has a single predecessor (preheader), its entry block "
802+
"has 2 incoming blocks");
803+
804+
// Idx == 0 selects the predecessor of the region, Idx == 1 selects the
805+
// region itself whose exiting block feeds the phi across the backedge.
806+
Pred = Idx == 0 ? Region->getSinglePredecessor() : Region;
807+
}
808+
return Pred->getExitingBasicBlock();
809+
}
810+
792811
InstructionCost VPRegionBlock::cost(ElementCount VF, VPCostContext &Ctx) {
793812
if (!isReplicator()) {
794813
InstructionCost Cost = 0;

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,28 @@ class VPIRInstruction : public VPRecipeBase {
11711171
void extractLastLaneOfFirstOperand(VPBuilder &Builder);
11721172
};
11731173

1174+
/// Helper type to provide functions to access incoming values and blocks for
1175+
/// phi-like recipes.
1176+
class VPPhiAccessors {
1177+
protected:
1178+
/// Return a VPRecipeBase* to the current object.
1179+
virtual const VPRecipeBase *getAsRecipe() const = 0;
1180+
1181+
public:
1182+
virtual ~VPPhiAccessors() = default;
1183+
1184+
/// Returns the incoming VPValue with index \p Idx.
1185+
VPValue *getIncomingValue(unsigned Idx) const {
1186+
return getAsRecipe()->getOperand(Idx);
1187+
}
1188+
1189+
/// Returns the incoming block with index \p Idx.
1190+
const VPBasicBlock *getIncomingBlock(unsigned Idx) const;
1191+
1192+
/// Returns the number of incoming values, also number of incoming blocks.
1193+
unsigned getNumIncoming() const { return getAsRecipe()->getNumOperands(); }
1194+
};
1195+
11741196
/// An overlay for VPIRInstructions wrapping PHI nodes enabling convenient use
11751197
/// cast/dyn_cast/isa and execute() implementation. A single VPValue operand is
11761198
/// allowed, and it is used to add a new incoming value for the single
@@ -1974,10 +1996,13 @@ class VPWidenPointerInductionRecipe : public VPWidenInductionRecipe,
19741996
/// recipe is placed in an entry block to a (non-replicate) region, it must have
19751997
/// exactly 2 incoming values, the first from the predecessor of the region and
19761998
/// the second from the exiting block of the region.
1977-
class VPWidenPHIRecipe : public VPSingleDefRecipe {
1999+
class VPWidenPHIRecipe : public VPSingleDefRecipe, public VPPhiAccessors {
19782000
/// Name to use for the generated IR instruction for the widened phi.
19792001
std::string Name;
19802002

2003+
protected:
2004+
const VPRecipeBase *getAsRecipe() const override { return this; }
2005+
19812006
public:
19822007
/// Create a new VPWidenPHIRecipe for \p Phi with start value \p Start and
19832008
/// debug location \p DL.
@@ -2005,12 +2030,6 @@ class VPWidenPHIRecipe : public VPSingleDefRecipe {
20052030
void print(raw_ostream &O, const Twine &Indent,
20062031
VPSlotTracker &SlotTracker) const override;
20072032
#endif
2008-
2009-
/// Returns the \p I th incoming VPBasicBlock.
2010-
VPBasicBlock *getIncomingBlock(unsigned I);
2011-
2012-
/// Returns the \p I th incoming VPValue.
2013-
VPValue *getIncomingValue(unsigned I) { return getOperand(I); }
20142033
};
20152034

20162035
/// A recipe for handling first-order recurrence phis. The start value is the
@@ -3329,6 +3348,12 @@ class VPBasicBlock : public VPBlockBase {
33293348
/// the cloned recipes.
33303349
VPBasicBlock *clone() override;
33313350

3351+
/// Returns the predecessor block at index \p Idx with the predecessors as per
3352+
/// the corresponding plain CFG. If the block is an entry block to a region,
3353+
/// the first predecessor is the single predecessor of a region, and the
3354+
/// second predecessor is the exiting block of the region.
3355+
const VPBasicBlock *getCFGPredecessor(unsigned Idx) const;
3356+
33323357
protected:
33333358
/// Execute the recipes in the IR basic block \p BB.
33343359
void executeRecipes(VPTransformState *State, BasicBlock *BB);
@@ -3343,6 +3368,11 @@ class VPBasicBlock : public VPBlockBase {
33433368
BasicBlock *createEmptyBasicBlock(VPTransformState &State);
33443369
};
33453370

3371+
inline const VPBasicBlock *
3372+
VPPhiAccessors::getIncomingBlock(unsigned Idx) const {
3373+
return getAsRecipe()->getParent()->getCFGPredecessor(Idx);
3374+
}
3375+
33463376
/// A special type of VPBasicBlock that wraps an existing IR basic block.
33473377
/// Recipes of the block get added before the first non-phi instruction in the
33483378
/// wrapped block.

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3684,27 +3684,6 @@ void VPReductionPHIRecipe::print(raw_ostream &O, const Twine &Indent,
36843684
}
36853685
#endif
36863686

3687-
VPBasicBlock *VPWidenPHIRecipe::getIncomingBlock(unsigned I) {
3688-
VPBasicBlock *Parent = getParent();
3689-
VPBlockBase *Pred = nullptr;
3690-
if (Parent->getNumPredecessors() > 0) {
3691-
Pred = Parent->getPredecessors()[I];
3692-
} else {
3693-
auto *Region = Parent->getParent();
3694-
assert(Region && !Region->isReplicator() && Region->getEntry() == Parent &&
3695-
"must be in the entry block of a non-replicate region");
3696-
assert(
3697-
I < 2 && getNumOperands() == 2 &&
3698-
"when placed in an entry block, only 2 incoming blocks are available");
3699-
3700-
// I == 0 selects the predecessor of the region, I == 1 selects the region
3701-
// itself whose exiting block feeds the phi across the backedge.
3702-
Pred = I == 0 ? Region->getSinglePredecessor() : Region;
3703-
}
3704-
3705-
return Pred->getExitingBasicBlock();
3706-
}
3707-
37083687
void VPWidenPHIRecipe::execute(VPTransformState &State) {
37093688
assert(EnableVPlanNativePath &&
37103689
"Non-native vplans are not expected to have VPWidenPHIRecipes.");

0 commit comments

Comments
 (0)