Skip to content

Commit 98683b0

Browse files
committed
[VPlan] Construct VPBlendRecipe from VPWidenPHIRecipe (NFC).
Update VPRecipeBuilder to construct VPBlendRecipe from VPWidenPHIRecipe, starting to thread recipes through the builder instead of the underlying IR instruction up-front. Landing first part of approved #139475 separately as NFC as suggested.
1 parent ec406e8 commit 98683b0

File tree

2 files changed

+25
-21
lines changed

2 files changed

+25
-21
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8539,10 +8539,7 @@ VPWidenIntOrFpInductionRecipe *VPRecipeBuilder::tryToOptimizeInductionTruncate(
85398539
return nullptr;
85408540
}
85418541

8542-
VPBlendRecipe *VPRecipeBuilder::tryToBlend(PHINode *Phi,
8543-
ArrayRef<VPValue *> Operands) {
8544-
unsigned NumIncoming = Phi->getNumIncomingValues();
8545-
8542+
VPBlendRecipe *VPRecipeBuilder::tryToBlend(VPWidenPHIRecipe *PhiR) {
85468543
// We know that all PHIs in non-header blocks are converted into selects, so
85478544
// we don't have to worry about the insertion order and we can just use the
85488545
// builder. At this point we generate the predication tree. There may be
@@ -8552,17 +8549,19 @@ VPBlendRecipe *VPRecipeBuilder::tryToBlend(PHINode *Phi,
85528549
// Map incoming IR BasicBlocks to incoming VPValues, for lookup below.
85538550
// TODO: Add operands and masks in order from the VPlan predecessors.
85548551
DenseMap<BasicBlock *, VPValue *> VPIncomingValues;
8552+
auto *Phi = cast<PHINode>(PhiR->getUnderlyingInstr());
85558553
for (const auto &[Idx, Pred] : enumerate(predecessors(Phi->getParent())))
8556-
VPIncomingValues[Pred] = Operands[Idx];
8554+
VPIncomingValues[Pred] = PhiR->getOperand(Idx);
85578555

8556+
unsigned NumIncoming = PhiR->getNumIncoming();
85588557
SmallVector<VPValue *, 2> OperandsWithMask;
85598558
for (unsigned In = 0; In < NumIncoming; In++) {
85608559
BasicBlock *Pred = Phi->getIncomingBlock(In);
85618560
OperandsWithMask.push_back(VPIncomingValues.lookup(Pred));
85628561
VPValue *EdgeMask = getEdgeMask(Pred, Phi->getParent());
85638562
if (!EdgeMask) {
85648563
assert(In == 0 && "Both null and non-null edge masks found");
8565-
assert(all_equal(Operands) &&
8564+
assert(all_equal(PhiR->operands()) &&
85668565
"Distinct incoming values with one having a full mask");
85678566
break;
85688567
}
@@ -8955,15 +8954,21 @@ bool VPRecipeBuilder::getScaledReductions(
89558954
return false;
89568955
}
89578956

8958-
VPRecipeBase *VPRecipeBuilder::tryToCreateWidenRecipe(
8959-
Instruction *Instr, ArrayRef<VPValue *> Operands, VFRange &Range) {
8957+
VPRecipeBase *VPRecipeBuilder::tryToCreateWidenRecipe(VPSingleDefRecipe *R,
8958+
VFRange &Range) {
89608959
// First, check for specific widening recipes that deal with inductions, Phi
89618960
// nodes, calls and memory operations.
89628961
VPRecipeBase *Recipe;
8963-
if (auto *Phi = dyn_cast<PHINode>(Instr)) {
8964-
if (Phi->getParent() != OrigLoop->getHeader())
8965-
return tryToBlend(Phi, Operands);
8966-
8962+
Instruction *Instr = R->getUnderlyingInstr();
8963+
SmallVector<VPValue *, 4> Operands(R->operands());
8964+
if (auto *PhiR = dyn_cast<VPWidenPHIRecipe>(R)) {
8965+
VPBasicBlock *Parent = PhiR->getParent();
8966+
VPRegionBlock *LoopRegionOf = Parent->getEnclosingLoopRegion();
8967+
// Handle phis in non-header blocks.
8968+
if (!LoopRegionOf || LoopRegionOf->getEntry() != Parent)
8969+
return tryToBlend(PhiR);
8970+
8971+
auto *Phi = cast<PHINode>(R->getUnderlyingInstr());
89678972
assert(Operands.size() == 2 && "Must have 2 operands for header phis");
89688973
if ((Recipe = tryToOptimizeInductionPHI(Phi, Operands, Range)))
89698974
return Recipe;
@@ -9528,11 +9533,12 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range,
95289533
continue;
95299534
}
95309535

9531-
SmallVector<VPValue *, 4> Operands(R.operands());
95329536
VPRecipeBase *Recipe =
9533-
RecipeBuilder.tryToCreateWidenRecipe(Instr, Operands, Range);
9534-
if (!Recipe)
9537+
RecipeBuilder.tryToCreateWidenRecipe(SingleDef, Range);
9538+
if (!Recipe) {
9539+
SmallVector<VPValue *, 4> Operands(R.operands());
95359540
Recipe = RecipeBuilder.handleReplication(Instr, Operands, Range);
9541+
}
95369542

95379543
RecipeBuilder.setRecipe(Instr, Recipe);
95389544
if (isa<VPWidenIntOrFpInductionRecipe>(Recipe) && isa<TruncInst>(Instr)) {

llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,10 @@ class VPRecipeBuilder {
122122
tryToOptimizeInductionTruncate(TruncInst *I, ArrayRef<VPValue *> Operands,
123123
VFRange &Range);
124124

125-
/// Handle non-loop phi nodes. Return a new VPBlendRecipe otherwise. Currently
125+
/// Handle non-loop phi nodes, returning a new VPBlendRecipe. Currently
126126
/// all such phi nodes are turned into a sequence of select instructions as
127127
/// the vectorizer currently performs full if-conversion.
128-
VPBlendRecipe *tryToBlend(PHINode *Phi, ArrayRef<VPValue *> Operands);
128+
VPBlendRecipe *tryToBlend(VPWidenPHIRecipe *PhiR);
129129

130130
/// Handle call instructions. If \p CI can be widened for \p Range.Start,
131131
/// return a new VPWidenCallRecipe or VPWidenIntrinsicRecipe. Range.End may be
@@ -179,11 +179,9 @@ class VPRecipeBuilder {
179179
/// that are valid so recipes can be formed later.
180180
void collectScaledReductions(VFRange &Range);
181181

182-
/// Create and return a widened recipe for \p I if one can be created within
182+
/// Create and return a widened recipe for \p R if one can be created within
183183
/// the given VF \p Range.
184-
VPRecipeBase *tryToCreateWidenRecipe(Instruction *Instr,
185-
ArrayRef<VPValue *> Operands,
186-
VFRange &Range);
184+
VPRecipeBase *tryToCreateWidenRecipe(VPSingleDefRecipe *R, VFRange &Range);
187185

188186
/// Create and return a partial reduction recipe for a reduction instruction
189187
/// along with binary operation and reduction phi operands.

0 commit comments

Comments
 (0)