Skip to content

Commit 10bd4cd

Browse files
authored
[VPlan] Remove ResumePhi opcode, use regular PHI instead (NFC). (#140405)
Use regular VPPhi instead of a separate opcode for resume phis. This removes an unneeded specialized opcode and unifies the code (verification, printing, updating when CFG is changed). Depends on #140132. PR: #140405
1 parent 67ff713 commit 10bd4cd

File tree

7 files changed

+51
-66
lines changed

7 files changed

+51
-66
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2379,11 +2379,9 @@ void InnerLoopVectorizer::introduceCheckBlockInVPlan(BasicBlock *CheckIRBB) {
23792379
PreVectorPH->swapSuccessors();
23802380

23812381
// We just connected a new block to the scalar preheader. Update all
2382-
// ResumePhis by adding an incoming value for it, replicating the last value.
2383-
for (VPRecipeBase &R : *cast<VPBasicBlock>(ScalarPH)) {
2384-
auto *ResumePhi = dyn_cast<VPInstruction>(&R);
2385-
if (!ResumePhi || ResumePhi->getOpcode() != VPInstruction::ResumePhi)
2386-
continue;
2382+
// VPPhis by adding an incoming value for it, replicating the last value.
2383+
for (VPRecipeBase &R : cast<VPBasicBlock>(ScalarPH)->phis()) {
2384+
auto *ResumePhi = cast<VPPhi>(&R);
23872385
ResumePhi->addOperand(
23882386
ResumePhi->getOperand(ResumePhi->getNumOperands() - 1));
23892387
}
@@ -2533,7 +2531,8 @@ BasicBlock *InnerLoopVectorizer::emitMemRuntimeChecks(BasicBlock *Bypass) {
25332531
static void replaceVPBBWithIRVPBB(VPBasicBlock *VPBB, BasicBlock *IRBB) {
25342532
VPIRBasicBlock *IRVPBB = VPBB->getPlan()->createVPIRBasicBlock(IRBB);
25352533
for (auto &R : make_early_inc_range(*VPBB)) {
2536-
assert(!R.isPhi() && "Tried to move phi recipe to end of block");
2534+
assert((IRVPBB->empty() || IRVPBB->back().isPhi() || !R.isPhi()) &&
2535+
"Tried to move phi recipe after a non-phi recipe");
25372536
R.moveBefore(*IRVPBB, IRVPBB->end());
25382537
}
25392538

@@ -7535,14 +7534,10 @@ static void fixReductionScalarResumeWhenVectorizingEpilog(
75357534
// created a bc.merge.rdx Phi after the main vector body. Ensure that we carry
75367535
// over the incoming values correctly.
75377536
using namespace VPlanPatternMatch;
7538-
auto IsResumePhi = [](VPUser *U) {
7539-
auto *VPI = dyn_cast<VPInstruction>(U);
7540-
return VPI && VPI->getOpcode() == VPInstruction::ResumePhi;
7541-
};
7542-
assert(count_if(EpiRedResult->users(), IsResumePhi) == 1 &&
7537+
assert(count_if(EpiRedResult->users(), IsaPred<VPPhi>) == 1 &&
75437538
"ResumePhi must have a single user");
75447539
auto *EpiResumePhiVPI =
7545-
cast<VPInstruction>(*find_if(EpiRedResult->users(), IsResumePhi));
7540+
cast<VPInstruction>(*find_if(EpiRedResult->users(), IsaPred<VPPhi>));
75467541
auto *EpiResumePhi = cast<PHINode>(State.get(EpiResumePhiVPI, true));
75477542
EpiResumePhi->setIncomingValueForBlock(
75487543
BypassBlock, MainResumePhi->getIncomingValueForBlock(BypassBlock));
@@ -8723,9 +8718,8 @@ static VPInstruction *addResumePhiRecipeForInduction(
87238718
WideIV->getDebugLoc());
87248719
}
87258720

8726-
auto *ResumePhiRecipe =
8727-
ScalarPHBuilder.createNaryOp(VPInstruction::ResumePhi, {EndValue, Start},
8728-
WideIV->getDebugLoc(), "bc.resume.val");
8721+
auto *ResumePhiRecipe = ScalarPHBuilder.createScalarPhi(
8722+
{EndValue, Start}, WideIV->getDebugLoc(), "bc.resume.val");
87298723
return ResumePhiRecipe;
87308724
}
87318725

@@ -8754,8 +8748,7 @@ static void addScalarResumePhis(VPRecipeBuilder &Builder, VPlan &Plan,
87548748
if (VPInstruction *ResumePhi = addResumePhiRecipeForInduction(
87558749
WideIVR, VectorPHBuilder, ScalarPHBuilder, TypeInfo,
87568750
&Plan.getVectorTripCount())) {
8757-
assert(ResumePhi->getOpcode() == VPInstruction::ResumePhi &&
8758-
"Expected a ResumePhi");
8751+
assert(isa<VPPhi>(ResumePhi) && "Expected a phi");
87598752
IVEndValues[WideIVR] = ResumePhi->getOperand(0);
87608753
ScalarPhiIRI->addOperand(ResumePhi);
87618754
continue;
@@ -8780,8 +8773,7 @@ static void addScalarResumePhis(VPRecipeBuilder &Builder, VPlan &Plan,
87808773
VPInstruction::ExtractLastElement, {ResumeFromVectorLoop}, {},
87818774
"vector.recur.extract");
87828775
StringRef Name = IsFOR ? "scalar.recur.init" : "bc.merge.rdx";
8783-
auto *ResumePhiR = ScalarPHBuilder.createNaryOp(
8784-
VPInstruction::ResumePhi,
8776+
auto *ResumePhiR = ScalarPHBuilder.createScalarPhi(
87858777
{ResumeFromVectorLoop, VectorPhiR->getStartValue()}, {}, Name);
87868778
ScalarPhiIRI->addOperand(ResumePhiR);
87878779
}
@@ -9961,9 +9953,7 @@ static void preparePlanForMainVectorLoop(VPlan &MainPlan, VPlan &EpiPlan) {
99619953
VPI->setOperand(1, Freeze);
99629954
if (UpdateResumePhis)
99639955
OrigStart->replaceUsesWithIf(Freeze, [Freeze](VPUser &U, unsigned) {
9964-
return Freeze != &U && isa<VPInstruction>(&U) &&
9965-
cast<VPInstruction>(&U)->getOpcode() ==
9966-
VPInstruction::ResumePhi;
9956+
return Freeze != &U && isa<VPPhi>(&U);
99679957
});
99689958
}
99699959
};
@@ -9976,13 +9966,12 @@ static void preparePlanForMainVectorLoop(VPlan &MainPlan, VPlan &EpiPlan) {
99769966
// scalar (which will become vector) epilogue loop we are done. Otherwise
99779967
// create it below.
99789968
if (any_of(*MainScalarPH, [VectorTC](VPRecipeBase &R) {
9979-
return match(&R, m_VPInstruction<VPInstruction::ResumePhi>(
9980-
m_Specific(VectorTC), m_SpecificInt(0)));
9969+
return match(&R, m_VPInstruction<Instruction::PHI>(m_Specific(VectorTC),
9970+
m_SpecificInt(0)));
99819971
}))
99829972
return;
99839973
VPBuilder ScalarPHBuilder(MainScalarPH, MainScalarPH->begin());
9984-
ScalarPHBuilder.createNaryOp(
9985-
VPInstruction::ResumePhi,
9974+
ScalarPHBuilder.createScalarPhi(
99869975
{VectorTC, MainPlan.getCanonicalIV()->getStartValue()}, {},
99879976
"vec.epilog.resume.val");
99889977
}

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -887,11 +887,6 @@ class VPInstruction : public VPRecipeWithIRFlags,
887887
SLPStore,
888888
ActiveLaneMask,
889889
ExplicitVectorLength,
890-
/// Creates a scalar phi in a leaf VPBB with a single predecessor in VPlan.
891-
/// The first operand is the incoming value from the predecessor in VPlan,
892-
/// the second operand is the incoming value for all other predecessors
893-
/// (which are currently not modeled in VPlan).
894-
ResumePhi,
895890
CalculateTripCountMinusVF,
896891
// Increment the canonical IV separately for each unrolled part.
897892
CanonicalIVIncrementForPart,
@@ -1137,11 +1132,15 @@ struct VPPhi : public VPInstruction, public VPPhiAccessors {
11371132
VPPhi(ArrayRef<VPValue *> Operands, DebugLoc DL, const Twine &Name = "")
11381133
: VPInstruction(Instruction::PHI, Operands, DL, Name) {}
11391134

1140-
static inline bool classof(const VPRecipeBase *U) {
1135+
static inline bool classof(const VPUser *U) {
11411136
auto *R = dyn_cast<VPInstruction>(U);
11421137
return R && R->getOpcode() == Instruction::PHI;
11431138
}
11441139

1140+
VPPhi *clone() override {
1141+
return new VPPhi(operands(), getDebugLoc(), getName());
1142+
}
1143+
11451144
void execute(VPTransformState &State) override;
11461145

11471146
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPInstruction *R) {
101101
return inferScalarType(R->getOperand(0));
102102
case VPInstruction::FirstOrderRecurrenceSplice:
103103
case VPInstruction::Not:
104-
case VPInstruction::ResumePhi:
105104
case VPInstruction::CalculateTripCountMinusVF:
106105
case VPInstruction::CanonicalIVIncrementForPart:
107106
case VPInstruction::AnyOf:

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -733,17 +733,6 @@ Value *VPInstruction::generate(VPTransformState &State) {
733733
Value *Addend = State.get(getOperand(1), VPLane(0));
734734
return Builder.CreatePtrAdd(Ptr, Addend, Name, getGEPNoWrapFlags());
735735
}
736-
case VPInstruction::ResumePhi: {
737-
auto *NewPhi =
738-
Builder.CreatePHI(State.TypeAnalysis.inferScalarType(this), 2, Name);
739-
for (const auto &[IncVPV, PredVPBB] :
740-
zip(operands(), getParent()->getPredecessors())) {
741-
Value *IncV = State.get(IncVPV, /* IsScalar */ true);
742-
BasicBlock *PredBB = State.CFG.VPBB2IRBB.at(cast<VPBasicBlock>(PredVPBB));
743-
NewPhi->addIncoming(IncV, PredBB);
744-
}
745-
return NewPhi;
746-
}
747736
case VPInstruction::AnyOf: {
748737
Value *A = State.get(getOperand(0));
749738
return Builder.CreateOrReduce(A);
@@ -847,8 +836,7 @@ bool VPInstruction::isVectorToScalar() const {
847836
}
848837

849838
bool VPInstruction::isSingleScalar() const {
850-
return getOpcode() == VPInstruction::ResumePhi ||
851-
getOpcode() == Instruction::PHI;
839+
return getOpcode() == Instruction::PHI;
852840
}
853841

854842
void VPInstruction::execute(VPTransformState &State) {
@@ -934,7 +922,6 @@ bool VPInstruction::onlyFirstLaneUsed(const VPValue *Op) const {
934922
case VPInstruction::CanonicalIVIncrementForPart:
935923
case VPInstruction::BranchOnCount:
936924
case VPInstruction::BranchOnCond:
937-
case VPInstruction::ResumePhi:
938925
return true;
939926
case VPInstruction::PtrAdd:
940927
return Op == getOperand(0) || vputils::onlyFirstLaneUsed(this);
@@ -991,9 +978,6 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
991978
case VPInstruction::ActiveLaneMask:
992979
O << "active lane mask";
993980
break;
994-
case VPInstruction::ResumePhi:
995-
O << "resume-phi";
996-
break;
997981
case VPInstruction::ExplicitVectorLength:
998982
O << "EXPLICIT-VECTOR-LENGTH";
999983
break;
@@ -1101,21 +1085,36 @@ void VPInstructionWithType::print(raw_ostream &O, const Twine &Indent,
11011085

11021086
void VPPhi::execute(VPTransformState &State) {
11031087
State.setDebugLocFrom(getDebugLoc());
1104-
BasicBlock *VectorPH = State.CFG.VPBB2IRBB.at(getIncomingBlock(0));
1105-
Value *Start = State.get(getIncomingValue(0), VPLane(0));
1106-
PHINode *Phi = State.Builder.CreatePHI(Start->getType(), 2, getName());
1107-
Phi->addIncoming(Start, VectorPH);
1108-
State.set(this, Phi, VPLane(0));
1088+
PHINode *NewPhi = State.Builder.CreatePHI(
1089+
State.TypeAnalysis.inferScalarType(this), 2, getName());
1090+
unsigned NumIncoming = getNumIncoming();
1091+
if (getParent() != getParent()->getPlan()->getScalarPreheader()) {
1092+
// TODO: Fixup all incoming values of header phis once recipes defining them
1093+
// are introduced.
1094+
NumIncoming = 1;
1095+
}
1096+
for (unsigned Idx = 0; Idx != NumIncoming; ++Idx) {
1097+
Value *IncV = State.get(getIncomingValue(Idx), VPLane(0));
1098+
BasicBlock *PredBB = State.CFG.VPBB2IRBB.at(getIncomingBlock(Idx));
1099+
NewPhi->addIncoming(IncV, PredBB);
1100+
}
1101+
State.set(this, NewPhi, VPLane(0));
11091102
}
11101103

11111104
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
11121105
void VPPhi::print(raw_ostream &O, const Twine &Indent,
11131106
VPSlotTracker &SlotTracker) const {
11141107
O << Indent << "EMIT" << (isSingleScalar() ? "-SCALAR" : "") << " ";
11151108
printAsOperand(O, SlotTracker);
1116-
O << " = phi ";
1117-
1118-
printPhiOperands(O, SlotTracker);
1109+
const VPBasicBlock *Parent = getParent();
1110+
if (Parent == Parent->getPlan()->getScalarPreheader()) {
1111+
// TODO: Use regular printing for resume-phis as well
1112+
O << " = resume-phi ";
1113+
printOperands(O, SlotTracker);
1114+
} else {
1115+
O << " = phi ";
1116+
printPhiOperands(O, SlotTracker);
1117+
}
11191118
}
11201119
#endif
11211120

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,8 +1864,8 @@ static void removeBranchOnCondTrue(VPlan &Plan) {
18641864
!isa<PHINode>(cast<VPIRInstruction>(&R)->getInstruction())) &&
18651865
!isa<VPHeaderPHIRecipe>(&R) &&
18661866
"Cannot update VPIRInstructions wrapping phis or header phis yet");
1867-
auto *VPI = dyn_cast<VPInstruction>(&R);
1868-
if (!VPI || VPI->getOpcode() != VPInstruction::ResumePhi)
1867+
auto *VPI = dyn_cast<VPPhi>(&R);
1868+
if (!VPI)
18691869
break;
18701870
VPBuilder B(VPI);
18711871
SmallVector<VPValue *> NewOperands;
@@ -1875,9 +1875,8 @@ static void removeBranchOnCondTrue(VPlan &Plan) {
18751875
continue;
18761876
NewOperands.push_back(Op);
18771877
}
1878-
VPI->replaceAllUsesWith(B.createNaryOp(VPInstruction::ResumePhi,
1879-
NewOperands, VPI->getDebugLoc(),
1880-
VPI->getName()));
1878+
VPI->replaceAllUsesWith(
1879+
B.createScalarPhi(NewOperands, VPI->getDebugLoc(), VPI->getName()));
18811880
VPI->eraseFromParent();
18821881
}
18831882
// Disconnect blocks and remove the terminator. RemovedSucc will be deleted

llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,7 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
243243
continue;
244244
}
245245
// TODO: Also verify VPPredInstPHIRecipe.
246-
if (isa<VPPredInstPHIRecipe>(UI) ||
247-
(isa<VPInstruction>(UI) && (cast<VPInstruction>(UI)->getOpcode() ==
248-
VPInstruction::ResumePhi)))
246+
if (isa<VPPredInstPHIRecipe>(UI))
249247
continue;
250248

251249
// If the user is in the same block, check it comes after R in the

llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ TEST_F(VPVerifierTest, VPPhiIncomingValueDoesntDominateIncomingBlock) {
151151
VPBasicBlock *VPBB1 = Plan.getEntry();
152152
VPBasicBlock *VPBB2 = Plan.createVPBasicBlock("");
153153
VPBasicBlock *VPBB3 = Plan.createVPBasicBlock("");
154+
VPBasicBlock *VPBB4 = Plan.createVPBasicBlock("");
154155

155156
VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero});
156157
VPPhi *Phi = new VPPhi({DefI}, {});
@@ -162,6 +163,7 @@ TEST_F(VPVerifierTest, VPPhiIncomingValueDoesntDominateIncomingBlock) {
162163
VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB3, VPBB3, "R1");
163164
VPBlockUtils::connectBlocks(VPBB1, VPBB2);
164165
VPBlockUtils::connectBlocks(VPBB2, R1);
166+
VPBlockUtils::connectBlocks(VPBB4, Plan.getScalarHeader());
165167
#if GTEST_HAS_STREAM_REDIRECTION
166168
::testing::internal::CaptureStderr();
167169
#endif

0 commit comments

Comments
 (0)