-
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 2 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 |
|---|---|---|
|
|
@@ -898,6 +898,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 with a step of 1. | ||
| StepVector, | ||
|
|
||
| }; | ||
|
|
||
|
|
@@ -1063,6 +1065,9 @@ class VPInstructionWithType : public VPInstruction { | |
| : VPInstruction(Opcode, Operands, FMFs, DL, Name), ResultTy(ResultTy) {} | ||
|
|
||
| static inline bool classof(const VPRecipeBase *R) { | ||
| if (isa<VPInstruction>(R) && | ||
| cast<VPInstruction>(R)->getOpcode() == VPInstruction::StepVector) | ||
| return true; | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // VPInstructionWithType are VPInstructions with specific opcodes requiring | ||
| // type information. | ||
| if (R->isScalarCast()) | ||
|
|
@@ -1836,6 +1841,7 @@ class VPWidenIntOrFpInductionRecipe : public VPWidenInductionRecipe { | |
| Step, IndDesc, DL), | ||
| Trunc(nullptr) { | ||
| addOperand(VF); | ||
| addOperand(VF); // Dummy StepVector replaced in convertToConcreteRecipes | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, | ||
|
|
@@ -1845,6 +1851,7 @@ class VPWidenIntOrFpInductionRecipe : public VPWidenInductionRecipe { | |
| Step, IndDesc, DL), | ||
| Trunc(Trunc) { | ||
| addOperand(VF); | ||
| addOperand(VF); // Dummy StepVector replaced in convertToConcreteRecipes | ||
| SmallVector<std::pair<unsigned, MDNode *>> Metadata; | ||
| (void)Metadata; | ||
| if (Trunc) | ||
|
|
@@ -1875,10 +1882,14 @@ 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) { setOperand(3, V); } | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| VPValue *getSplatVFValue() { | ||
| // If the recipe has been unrolled (4 operands), return the VPValue for the | ||
| // If the recipe has been unrolled, return the VPValue for the | ||
| // induction increment. | ||
| return getNumOperands() == 5 ? getOperand(3) : nullptr; | ||
| return isUnrolled() ? getOperand(getNumOperands() - 2) : nullptr; | ||
lukel97 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| /// Returns the first defined value as TruncInst, if it is one or nullptr | ||
|
|
@@ -1900,8 +1911,11 @@ class VPWidenIntOrFpInductionRecipe : public VPWidenInductionRecipe { | |
| /// the last unrolled part, if it exists. Returns itself if unrolling did not | ||
| /// take place. | ||
| VPValue *getLastUnrolledPartOperand() { | ||
| return getNumOperands() == 5 ? getOperand(4) : this; | ||
| return isUnrolled() ? getOperand(getNumOperands() - 1) : this; | ||
| } | ||
|
|
||
| private: | ||
| bool isUnrolled() const { return getNumOperands() == 6; } | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| class VPWidenPointerInductionRecipe : public VPWidenInductionRecipe, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -930,6 +930,7 @@ bool VPInstruction::opcodeMayReadOrWriteFromMemory() const { | |
| case VPInstruction::Not: | ||
| case VPInstruction::PtrAdd: | ||
| case VPInstruction::WideIVStep: | ||
| case VPInstruction::StepVector: | ||
| return false; | ||
| default: | ||
| return true; | ||
|
|
@@ -1078,8 +1079,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: { | ||
|
|
@@ -1089,6 +1088,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"); | ||
| } | ||
|
|
@@ -1106,6 +1111,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()) << " "; | ||
|
|
@@ -1875,7 +1883,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"); | ||
|
|
@@ -1891,15 +1900,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"); | ||
|
|
@@ -1965,8 +1965,11 @@ 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); | ||
| 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.