Skip to content

Commit b354f58

Browse files
committed
[VPlan] Add new VPPhi subclass for VPInstruction with PHI opcodes.
Similarly to VPInstructionWithType and VPIRPhi, add VPPhi as a subclass for VPInstruction. This allows implementing the VPPhiAccessors trait, making available helpers for generic printing of incoming values / blocks and accessors for incoming blocks and values. It will also allow properly verifying def-uses for values used by VPInstructions with PHI opcodes via llvm#124838.
1 parent fe56c8f commit b354f58

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ class VPBuilder {
253253
VPInstruction *createScalarPhi(ArrayRef<VPValue *> IncomingValues,
254254
DebugLoc DL, const Twine &Name = "") {
255255
return tryInsertInstruction(
256-
new VPInstruction(Instruction::PHI, IncomingValues, DL, Name));
256+
new VPPhi(Instruction::PHI, IncomingValues, DL, Name));
257257
}
258258

259259
/// Convert the input value \p Current to the corresponding value of an

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,28 @@ class VPPhiAccessors {
11431143
#endif
11441144
};
11451145

1146+
struct VPPhi : public VPInstruction, public VPPhiAccessors {
1147+
VPPhi(unsigned Opcode, ArrayRef<VPValue *> Operands, DebugLoc DL,
1148+
const Twine &Name = "")
1149+
: VPInstruction(Opcode, Operands, DL, Name) {}
1150+
1151+
static inline bool classof(const VPRecipeBase *U) {
1152+
auto *R = dyn_cast<VPInstruction>(U);
1153+
return R && R->getOpcode() == Instruction::PHI;
1154+
}
1155+
1156+
void execute(VPTransformState &State) override;
1157+
1158+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1159+
/// Print the recipe.
1160+
void print(raw_ostream &O, const Twine &Indent,
1161+
VPSlotTracker &SlotTracker) const override;
1162+
#endif
1163+
1164+
protected:
1165+
const VPRecipeBase *getAsRecipe() const override { return this; }
1166+
};
1167+
11461168
/// A recipe to wrap on original IR instruction not to be modified during
11471169
/// execution, except for PHIs. PHIs are modeled via the VPIRPhi subclass.
11481170
/// Expect PHIs, VPIRInstructions cannot have any operands.

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -492,16 +492,7 @@ Value *VPInstruction::generate(VPTransformState &State) {
492492
return Builder.CreateCmp(getPredicate(), A, B, Name);
493493
}
494494
case Instruction::PHI: {
495-
assert(getParent() ==
496-
getParent()->getPlan()->getVectorLoopRegion()->getEntry() &&
497-
"VPInstructions with PHI opcodes must be used for header phis only "
498-
"at the moment");
499-
BasicBlock *VectorPH =
500-
State.CFG.VPBB2IRBB.at(getParent()->getCFGPredecessor(0));
501-
Value *Start = State.get(getOperand(0), VPLane(0));
502-
PHINode *Phi = State.Builder.CreatePHI(Start->getType(), 2, Name);
503-
Phi->addIncoming(Start, VectorPH);
504-
return Phi;
495+
llvm_unreachable("should be handled by VPPhi::execute");
505496
}
506497
case Instruction::Select: {
507498
bool OnlyFirstLaneUsed = vputils::onlyFirstLaneUsed(this);
@@ -1131,6 +1122,30 @@ void VPInstructionWithType::print(raw_ostream &O, const Twine &Indent,
11311122
}
11321123
#endif
11331124

1125+
void VPPhi::execute(VPTransformState &State) {
1126+
State.setDebugLocFrom(getDebugLoc());
1127+
assert(getParent() ==
1128+
getParent()->getPlan()->getVectorLoopRegion()->getEntry() &&
1129+
"VPInstructions with PHI opcodes must be used for header phis only "
1130+
"at the moment");
1131+
BasicBlock *VectorPH = State.CFG.VPBB2IRBB.at(getIncomingBlock(0));
1132+
Value *Start = State.get(getIncomingValue(0), VPLane(0));
1133+
PHINode *Phi = State.Builder.CreatePHI(Start->getType(), 2, getName());
1134+
Phi->addIncoming(Start, VectorPH);
1135+
State.set(this, Phi, VPLane(0));
1136+
}
1137+
1138+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1139+
void VPPhi::print(raw_ostream &O, const Twine &Indent,
1140+
VPSlotTracker &SlotTracker) const {
1141+
O << Indent << "EMIT ";
1142+
printAsOperand(O, SlotTracker);
1143+
O << " = phi ";
1144+
1145+
printPhiOperands(O, SlotTracker);
1146+
}
1147+
#endif
1148+
11341149
VPIRInstruction *VPIRInstruction ::create(Instruction &I) {
11351150
if (auto *Phi = dyn_cast<PHINode>(&I))
11361151
return new VPIRPhi(*Phi);

0 commit comments

Comments
 (0)