-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[VPlan] Add VPInstruction::StepVector and use it in VPWidenIntOrFpInductionRecipe #129508
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
68bbf28
5d307e4
83fafe3
2b7ee27
e73e994
c7d9d75
6759922
9937480
6626037
e994900
c2d8fb8
8201fa2
f813502
912883b
4158c96
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -911,6 +911,8 @@ class VPInstruction : public VPRecipeWithIRFlags, | |
| /// Scale the first operand (vector step) by the second operand | ||
| /// (scalar-step). Casts both operands to the result type if needed. | ||
| WideIVStep, | ||
| // Creates a step vector starting from 0 to VF with a step of 1. | ||
| StepVector, | ||
|
|
||
| }; | ||
|
|
||
|
|
@@ -1081,7 +1083,15 @@ class VPInstructionWithType : public VPInstruction { | |
| if (R->isScalarCast()) | ||
| return true; | ||
| auto *VPI = dyn_cast<VPInstruction>(R); | ||
| return VPI && VPI->getOpcode() == VPInstruction::WideIVStep; | ||
| if (!VPI) | ||
| return false; | ||
| switch (VPI->getOpcode()) { | ||
| case VPInstruction::WideIVStep: | ||
| case VPInstruction::StepVector: | ||
| return true; | ||
| default: | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| static inline bool classof(const VPUser *R) { | ||
|
|
@@ -1861,25 +1871,34 @@ class VPWidenIntOrFpInductionRecipe : public VPWidenInductionRecipe { | |
| TruncInst *Trunc; | ||
|
|
||
| // If this recipe is unrolled it will have 2 additional operands. | ||
| bool isUnrolled() const { return getNumOperands() == 5; } | ||
| bool isUnrolled() const { return getNumOperands() == 6; } | ||
|
|
||
| public: | ||
| VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, | ||
| VPValue *VF, const InductionDescriptor &IndDesc, | ||
| DebugLoc DL) | ||
| VPValue *VF, VPValue *StepVector, | ||
|
||
| const InductionDescriptor &IndDesc, DebugLoc DL) | ||
| : VPWidenInductionRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start, | ||
| Step, IndDesc, DL), | ||
| Trunc(nullptr) { | ||
| addOperand(VF); | ||
| // Temporarily use Poison for step-vector, which will only be introduced | ||
| // when needed, when preparing to execute. | ||
| assert(isa<PoisonValue>(StepVector->getLiveInIRValue())); | ||
| addOperand(StepVector); | ||
| } | ||
|
|
||
| VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, | ||
| VPValue *VF, const InductionDescriptor &IndDesc, | ||
| VPValue *VF, VPValue *StepVector, | ||
| const InductionDescriptor &IndDesc, | ||
| TruncInst *Trunc, DebugLoc DL) | ||
| : VPWidenInductionRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start, | ||
| Step, IndDesc, DL), | ||
| Trunc(Trunc) { | ||
| addOperand(VF); | ||
| // Temporarily use Poison for step-vector, which will only be introduced | ||
| // when needed, when preparing to execute. | ||
| assert(isa<PoisonValue>(StepVector->getLiveInIRValue())); | ||
| addOperand(StepVector); | ||
| SmallVector<std::pair<unsigned, MDNode *>> Metadata; | ||
| (void)Metadata; | ||
| if (Trunc) | ||
|
|
@@ -1892,7 +1911,7 @@ class VPWidenIntOrFpInductionRecipe : public VPWidenInductionRecipe { | |
| VPWidenIntOrFpInductionRecipe *clone() override { | ||
| return new VPWidenIntOrFpInductionRecipe( | ||
| getPHINode(), getStartValue(), getStepValue(), getVFValue(), | ||
| getInductionDescriptor(), Trunc, getDebugLoc()); | ||
| getStepVector(), getInductionDescriptor(), Trunc, getDebugLoc()); | ||
| } | ||
|
|
||
| VP_CLASSOF_IMPL(VPDef::VPWidenIntOrFpInductionSC) | ||
|
|
@@ -1910,6 +1929,15 @@ class VPWidenIntOrFpInductionRecipe : public VPWidenInductionRecipe { | |
| VPValue *getVFValue() { return getOperand(2); } | ||
| const VPValue *getVFValue() const { return getOperand(2); } | ||
|
|
||
| VPValue *getStepVector() { return getOperand(3); } | ||
|
||
| const VPValue *getStepVector() const { return getOperand(3); } | ||
|
||
| void setStepVector(VPValue *V) { | ||
| assert(isa<PoisonValue>(getOperand(3)->getLiveInIRValue()) && | ||
| cast<VPInstructionWithType>(V->getDefiningRecipe())->getOpcode() == | ||
| VPInstruction::StepVector); | ||
| setOperand(3, V); | ||
| } | ||
|
|
||
| VPValue *getSplatVFValue() { | ||
| // If the recipe has been unrolled return the VPValue for the induction | ||
| // increment. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -932,6 +932,7 @@ bool VPInstruction::opcodeMayReadOrWriteFromMemory() const { | |
| case VPInstruction::Not: | ||
| case VPInstruction::PtrAdd: | ||
| case VPInstruction::WideIVStep: | ||
| case VPInstruction::StepVector: | ||
| return false; | ||
| default: | ||
| return true; | ||
|
|
@@ -1083,8 +1084,6 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent, | |
|
|
||
| void VPInstructionWithType::execute(VPTransformState &State) { | ||
| State.setDebugLocFrom(getDebugLoc()); | ||
| assert(vputils::onlyFirstLaneUsed(this) && | ||
| "Codegen only implemented for first lane."); | ||
| switch (getOpcode()) { | ||
| case Instruction::ZExt: | ||
| case Instruction::Trunc: { | ||
|
|
@@ -1094,6 +1093,12 @@ void VPInstructionWithType::execute(VPTransformState &State) { | |
| State.set(this, Cast, VPLane(0)); | ||
| break; | ||
| } | ||
| case VPInstruction::StepVector: { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to add this to VPInstruction::computeCost?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's currently costed as zero for now since we don't want to change the overall cost of VPWidenIntOrFpInductionRecipe. Once we expand VPWidenIntOrFpInductionRecipe in #118638 I think it should be safe to add a cost to it then? Since the expansion will happen just before execution, after any costing. |
||
| Value *StepVector = | ||
| State.Builder.CreateStepVector(VectorType::get(ResultTy, State.VF)); | ||
| State.set(this, StepVector); | ||
| break; | ||
| } | ||
| default: | ||
| llvm_unreachable("opcode not implemented yet"); | ||
| } | ||
|
|
@@ -1111,6 +1116,9 @@ void VPInstructionWithType::print(raw_ostream &O, const Twine &Indent, | |
| O << "wide-iv-step "; | ||
| printOperands(O, SlotTracker); | ||
| break; | ||
| case VPInstruction::StepVector: | ||
| O << "step-vector " << *ResultTy; | ||
| break; | ||
| default: | ||
| assert(Instruction::isCast(getOpcode()) && "unhandled opcode"); | ||
| O << Instruction::getOpcodeName(getOpcode()) << " "; | ||
|
|
@@ -1886,7 +1894,8 @@ InstructionCost VPHeaderPHIRecipe::computeCost(ElementCount VF, | |
| /// (0 * Step, 1 * Step, 2 * Step, ...) | ||
| /// to each vector element of Val. | ||
| /// \p Opcode is relevant for FP induction variable. | ||
| static Value *getStepVector(Value *Val, Value *Step, | ||
| /// \p InitVec is an integer step vector from 0 with a step of 1. | ||
| static Value *getStepVector(Value *Val, Value *Step, Value *InitVec, | ||
| Instruction::BinaryOps BinOp, ElementCount VF, | ||
| IRBuilderBase &Builder) { | ||
| assert(VF.isVector() && "only vector VFs are supported"); | ||
|
|
@@ -1902,15 +1911,6 @@ static Value *getStepVector(Value *Val, Value *Step, | |
|
|
||
| SmallVector<Constant *, 8> Indices; | ||
|
|
||
| // Create a vector of consecutive numbers from zero to VF. | ||
| VectorType *InitVecValVTy = ValVTy; | ||
| if (STy->isFloatingPointTy()) { | ||
| Type *InitVecValSTy = | ||
| IntegerType::get(STy->getContext(), STy->getScalarSizeInBits()); | ||
| InitVecValVTy = VectorType::get(InitVecValSTy, VLen); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps we should assert that
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They might not always have the same type as step might be a float or an integer, whereas InitVec is always an integer. Hopefully the calls to |
||
| } | ||
| Value *InitVec = Builder.CreateStepVector(InitVecValVTy); | ||
|
|
||
| if (STy->isIntegerTy()) { | ||
| Step = Builder.CreateVectorSplat(VLen, Step); | ||
| assert(Step->getType() == Val->getType() && "Invalid step vec"); | ||
|
|
@@ -1976,8 +1976,12 @@ void VPWidenIntOrFpInductionRecipe::execute(VPTransformState &State) { | |
| } | ||
|
|
||
| Value *SplatStart = Builder.CreateVectorSplat(State.VF, Start); | ||
| Value *SteppedStart = getStepVector(SplatStart, Step, ID.getInductionOpcode(), | ||
| State.VF, State.Builder); | ||
| assert(cast<VPInstruction>(getStepVector())->getOpcode() == | ||
|
||
| VPInstruction::StepVector && | ||
| "step vector operand must be a VPInstruction::StepVector"); | ||
| Value *SteppedStart = | ||
| ::getStepVector(SplatStart, Step, State.get(getStepVector()), | ||
| ID.getInductionOpcode(), State.VF, State.Builder); | ||
|
|
||
| // We create vector phi nodes for both integer and floating-point induction | ||
| // variables. Here, we determine the kind of arithmetic we will perform. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.