[LoopVectorize][NFC] Add optional Name parameter to VPInstruction

This patch is a simple piece of refactoring that now permits users
to create VPInstructions and specify the name of the value being
generated. This is useful for creating more readable/meaningful
names in IR.

Differential Revision: https://reviews.llvm.org/D128982
This commit is contained in:
David Sherwood 2022-07-01 10:19:45 +01:00
parent 79942d32a6
commit 02d6950d84
4 changed files with 41 additions and 30 deletions

View File

@ -45,8 +45,9 @@ class VPBuilder {
VPBasicBlock::iterator InsertPt = VPBasicBlock::iterator(); VPBasicBlock::iterator InsertPt = VPBasicBlock::iterator();
VPInstruction *createInstruction(unsigned Opcode, VPInstruction *createInstruction(unsigned Opcode,
ArrayRef<VPValue *> Operands, DebugLoc DL) { ArrayRef<VPValue *> Operands, DebugLoc DL,
VPInstruction *Instr = new VPInstruction(Opcode, Operands, DL); const Twine &Name = "") {
VPInstruction *Instr = new VPInstruction(Opcode, Operands, DL, Name);
if (BB) if (BB)
BB->insert(Instr, InsertPt); BB->insert(Instr, InsertPt);
return Instr; return Instr;
@ -54,8 +55,8 @@ class VPBuilder {
VPInstruction *createInstruction(unsigned Opcode, VPInstruction *createInstruction(unsigned Opcode,
std::initializer_list<VPValue *> Operands, std::initializer_list<VPValue *> Operands,
DebugLoc DL) { DebugLoc DL, const Twine &Name = "") {
return createInstruction(Opcode, ArrayRef<VPValue *>(Operands), DL); return createInstruction(Opcode, ArrayRef<VPValue *>(Operands), DL, Name);
} }
public: public:
@ -123,34 +124,37 @@ public:
/// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as
/// its underlying Instruction. /// its underlying Instruction.
VPValue *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands, VPValue *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands,
Instruction *Inst = nullptr) { Instruction *Inst = nullptr, const Twine &Name = "") {
DebugLoc DL; DebugLoc DL;
if (Inst) if (Inst)
DL = Inst->getDebugLoc(); DL = Inst->getDebugLoc();
VPInstruction *NewVPInst = createInstruction(Opcode, Operands, DL); VPInstruction *NewVPInst = createInstruction(Opcode, Operands, DL, Name);
NewVPInst->setUnderlyingValue(Inst); NewVPInst->setUnderlyingValue(Inst);
return NewVPInst; return NewVPInst;
} }
VPValue *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands, VPValue *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands,
DebugLoc DL) { DebugLoc DL, const Twine &Name = "") {
return createInstruction(Opcode, Operands, DL); return createInstruction(Opcode, Operands, DL, Name);
} }
VPValue *createNot(VPValue *Operand, DebugLoc DL) { VPValue *createNot(VPValue *Operand, DebugLoc DL, const Twine &Name = "") {
return createInstruction(VPInstruction::Not, {Operand}, DL); return createInstruction(VPInstruction::Not, {Operand}, DL, Name);
} }
VPValue *createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL) { VPValue *createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL,
return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}, DL); const Twine &Name = "") {
return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}, DL, Name);
} }
VPValue *createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL) { VPValue *createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL,
return createInstruction(Instruction::BinaryOps::Or, {LHS, RHS}, DL); const Twine &Name = "") {
return createInstruction(Instruction::BinaryOps::Or, {LHS, RHS}, DL, Name);
} }
VPValue *createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, VPValue *createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal,
DebugLoc DL) { DebugLoc DL, const Twine &Name = "") {
return createNaryOp(Instruction::Select, {Cond, TrueVal, FalseVal}, DL); return createNaryOp(Instruction::Select, {Cond, TrueVal, FalseVal}, DL,
Name);
} }
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//

View File

@ -8031,7 +8031,8 @@ VPValue *VPRecipeBuilder::createBlockInMask(BasicBlock *BB, VPlanPtr &Plan) {
Builder.setInsertPoint(HeaderVPBB, NewInsertionPoint); Builder.setInsertPoint(HeaderVPBB, NewInsertionPoint);
if (CM.TTI.emitGetActiveLaneMask()) { if (CM.TTI.emitGetActiveLaneMask()) {
VPValue *TC = Plan->getOrCreateTripCount(); VPValue *TC = Plan->getOrCreateTripCount();
BlockMask = Builder.createNaryOp(VPInstruction::ActiveLaneMask, {IV, TC}); BlockMask = Builder.createNaryOp(VPInstruction::ActiveLaneMask, {IV, TC},
nullptr, "active.lane.mask");
} else { } else {
VPValue *BTC = Plan->getOrCreateBackedgeTakenCount(); VPValue *BTC = Plan->getOrCreateBackedgeTakenCount();
BlockMask = Builder.createNaryOp(VPInstruction::ICmpULE, {IV, BTC}); BlockMask = Builder.createNaryOp(VPInstruction::ICmpULE, {IV, BTC});
@ -8588,7 +8589,7 @@ static void addCanonicalIVRecipes(VPlan &Plan, Type *IdxTy, DebugLoc DL,
auto *CanonicalIVIncrement = auto *CanonicalIVIncrement =
new VPInstruction(HasNUW ? VPInstruction::CanonicalIVIncrementNUW new VPInstruction(HasNUW ? VPInstruction::CanonicalIVIncrementNUW
: VPInstruction::CanonicalIVIncrement, : VPInstruction::CanonicalIVIncrement,
{CanonicalIVPHI}, DL); {CanonicalIVPHI}, DL, "index.next");
CanonicalIVPHI->addOperand(CanonicalIVIncrement); CanonicalIVPHI->addOperand(CanonicalIVIncrement);
VPBasicBlock *EB = TopRegion->getExitingBasicBlock(); VPBasicBlock *EB = TopRegion->getExitingBasicBlock();

View File

@ -794,6 +794,9 @@ private:
FastMathFlags FMF; FastMathFlags FMF;
DebugLoc DL; DebugLoc DL;
/// An optional name that can be used for the generated IR instruction.
const std::string Name;
/// Utility method serving execute(): generates a single instance of the /// Utility method serving execute(): generates a single instance of the
/// modeled instruction. /// modeled instruction.
void generateInstruction(VPTransformState &State, unsigned Part); void generateInstruction(VPTransformState &State, unsigned Part);
@ -802,14 +805,15 @@ protected:
void setUnderlyingInstr(Instruction *I) { setUnderlyingValue(I); } void setUnderlyingInstr(Instruction *I) { setUnderlyingValue(I); }
public: public:
VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands, DebugLoc DL) VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands, DebugLoc DL,
const Twine &Name = "")
: VPRecipeBase(VPRecipeBase::VPInstructionSC, Operands), : VPRecipeBase(VPRecipeBase::VPInstructionSC, Operands),
VPValue(VPValue::VPVInstructionSC, nullptr, this), Opcode(Opcode), VPValue(VPValue::VPVInstructionSC, nullptr, this), Opcode(Opcode),
DL(DL) {} DL(DL), Name(Name.str()) {}
VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands, VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands,
DebugLoc DL = {}) DebugLoc DL = {}, const Twine &Name = "")
: VPInstruction(Opcode, ArrayRef<VPValue *>(Operands), DL) {} : VPInstruction(Opcode, ArrayRef<VPValue *>(Operands), DL, Name) {}
/// Method to support type inquiry through isa, cast, and dyn_cast. /// Method to support type inquiry through isa, cast, and dyn_cast.
static inline bool classof(const VPValue *V) { static inline bool classof(const VPValue *V) {
@ -818,7 +822,7 @@ public:
VPInstruction *clone() const { VPInstruction *clone() const {
SmallVector<VPValue *, 2> Operands(operands()); SmallVector<VPValue *, 2> Operands(operands());
return new VPInstruction(Opcode, Operands, DL); return new VPInstruction(Opcode, Operands, DL, Name);
} }
/// Method to support type inquiry through isa, cast, and dyn_cast. /// Method to support type inquiry through isa, cast, and dyn_cast.

View File

@ -189,7 +189,8 @@ void VPInstruction::generateInstruction(VPTransformState &State,
if (Instruction::isBinaryOp(getOpcode())) { if (Instruction::isBinaryOp(getOpcode())) {
Value *A = State.get(getOperand(0), Part); Value *A = State.get(getOperand(0), Part);
Value *B = State.get(getOperand(1), Part); Value *B = State.get(getOperand(1), Part);
Value *V = Builder.CreateBinOp((Instruction::BinaryOps)getOpcode(), A, B); Value *V =
Builder.CreateBinOp((Instruction::BinaryOps)getOpcode(), A, B, Name);
State.set(this, V, Part); State.set(this, V, Part);
return; return;
} }
@ -197,14 +198,14 @@ void VPInstruction::generateInstruction(VPTransformState &State,
switch (getOpcode()) { switch (getOpcode()) {
case VPInstruction::Not: { case VPInstruction::Not: {
Value *A = State.get(getOperand(0), Part); Value *A = State.get(getOperand(0), Part);
Value *V = Builder.CreateNot(A); Value *V = Builder.CreateNot(A, Name);
State.set(this, V, Part); State.set(this, V, Part);
break; break;
} }
case VPInstruction::ICmpULE: { case VPInstruction::ICmpULE: {
Value *IV = State.get(getOperand(0), Part); Value *IV = State.get(getOperand(0), Part);
Value *TC = State.get(getOperand(1), Part); Value *TC = State.get(getOperand(1), Part);
Value *V = Builder.CreateICmpULE(IV, TC); Value *V = Builder.CreateICmpULE(IV, TC, Name);
State.set(this, V, Part); State.set(this, V, Part);
break; break;
} }
@ -212,7 +213,7 @@ void VPInstruction::generateInstruction(VPTransformState &State,
Value *Cond = State.get(getOperand(0), Part); Value *Cond = State.get(getOperand(0), Part);
Value *Op1 = State.get(getOperand(1), Part); Value *Op1 = State.get(getOperand(1), Part);
Value *Op2 = State.get(getOperand(2), Part); Value *Op2 = State.get(getOperand(2), Part);
Value *V = Builder.CreateSelect(Cond, Op1, Op2); Value *V = Builder.CreateSelect(Cond, Op1, Op2, Name);
State.set(this, V, Part); State.set(this, V, Part);
break; break;
} }
@ -226,7 +227,7 @@ void VPInstruction::generateInstruction(VPTransformState &State,
auto *PredTy = VectorType::get(Int1Ty, State.VF); auto *PredTy = VectorType::get(Int1Ty, State.VF);
Instruction *Call = Builder.CreateIntrinsic( Instruction *Call = Builder.CreateIntrinsic(
Intrinsic::get_active_lane_mask, {PredTy, ScalarTC->getType()}, Intrinsic::get_active_lane_mask, {PredTy, ScalarTC->getType()},
{VIVElem0, ScalarTC}, nullptr, "active.lane.mask"); {VIVElem0, ScalarTC}, nullptr, Name);
State.set(this, Call, Part); State.set(this, Call, Part);
break; break;
} }
@ -250,7 +251,8 @@ void VPInstruction::generateInstruction(VPTransformState &State,
State.set(this, PartMinus1, Part); State.set(this, PartMinus1, Part);
} else { } else {
Value *V2 = State.get(getOperand(1), Part); Value *V2 = State.get(getOperand(1), Part);
State.set(this, Builder.CreateVectorSplice(PartMinus1, V2, -1), Part); State.set(this, Builder.CreateVectorSplice(PartMinus1, V2, -1, Name),
Part);
} }
break; break;
} }
@ -264,7 +266,7 @@ void VPInstruction::generateInstruction(VPTransformState &State,
// elements) times the unroll factor (num of SIMD instructions). // elements) times the unroll factor (num of SIMD instructions).
Value *Step = Value *Step =
createStepForVF(Builder, Phi->getType(), State.VF, State.UF); createStepForVF(Builder, Phi->getType(), State.VF, State.UF);
Next = Builder.CreateAdd(Phi, Step, "index.next", IsNUW, false); Next = Builder.CreateAdd(Phi, Step, Name, IsNUW, false);
} else { } else {
Next = State.get(this, 0); Next = State.get(this, 0);
} }