-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[VPlan] Expand VPWidenPointerInductionRecipe into separate recipes #148274
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 4 commits
8dec7cf
61e4aec
ecb3fa5
3b38332
0315ec1
3adca50
628c26b
50454c5
5bf2d79
42586b7
e1ca024
4a25f75
03369e2
1c9e58a
73973fe
564ede8
a8a84f1
3b1f709
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 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -475,6 +475,7 @@ unsigned VPInstruction::getNumOperandsForOpcode(unsigned Opcode) { | |||||||||
| case VPInstruction::FirstOrderRecurrenceSplice: | ||||||||||
| case VPInstruction::LogicalAnd: | ||||||||||
| case VPInstruction::PtrAdd: | ||||||||||
| case VPInstruction::WidePtrAdd: | ||||||||||
| case VPInstruction::WideIVStep: | ||||||||||
| return 2; | ||||||||||
| case Instruction::Select: | ||||||||||
|
|
@@ -513,6 +514,7 @@ bool VPInstruction::canGenerateScalarForFirstLane() const { | |||||||||
| case VPInstruction::CalculateTripCountMinusVF: | ||||||||||
| case VPInstruction::CanonicalIVIncrementForPart: | ||||||||||
| case VPInstruction::PtrAdd: | ||||||||||
| case VPInstruction::WidePtrAdd: | ||||||||||
| case VPInstruction::ExplicitVectorLength: | ||||||||||
| case VPInstruction::AnyOf: | ||||||||||
| return true; | ||||||||||
|
|
@@ -854,6 +856,11 @@ Value *VPInstruction::generate(VPTransformState &State) { | |||||||||
| Value *Addend = State.get(getOperand(1), VPLane(0)); | ||||||||||
| return Builder.CreatePtrAdd(Ptr, Addend, Name, getGEPNoWrapFlags()); | ||||||||||
| } | ||||||||||
| case VPInstruction::WidePtrAdd: { | ||||||||||
| Value *Ptr = State.get(getOperand(0), true); | ||||||||||
| Value *Addend = State.get(getOperand(1), vputils::onlyFirstLaneUsed(this)); | ||||||||||
|
||||||||||
| return Builder.CreatePtrAdd(Ptr, Addend, Name, getGEPNoWrapFlags()); | ||||||||||
| } | ||||||||||
| case VPInstruction::AnyOf: { | ||||||||||
| Value *Res = State.get(getOperand(0)); | ||||||||||
| for (VPValue *Op : drop_begin(operands())) | ||||||||||
|
|
@@ -1045,6 +1052,7 @@ bool VPInstruction::opcodeMayReadOrWriteFromMemory() const { | |||||||||
| case VPInstruction::LogicalAnd: | ||||||||||
| case VPInstruction::Not: | ||||||||||
| case VPInstruction::PtrAdd: | ||||||||||
| case VPInstruction::WidePtrAdd: | ||||||||||
| case VPInstruction::WideIVStep: | ||||||||||
|
||||||||||
| case VPInstruction::WidePtrAdd: | |
| case VPInstruction::WideIVStep: | |
| case VPInstruction::WideIVStep: | |
| case VPInstruction::WidePtrAdd: |
lex order (even though its not consistent throughout)
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -973,6 +973,7 @@ static Value *tryToFoldLiveIns(const VPRecipeBase &R, unsigned Opcode, | |
| RFlags.getGEPNoWrapFlags()); | ||
| } | ||
| case VPInstruction::PtrAdd: | ||
| case VPInstruction::WidePtrAdd: | ||
| return Folder.FoldGEP(IntegerType::getInt8Ty(TypeInfo.getContext()), Ops[0], | ||
| Ops[1], | ||
| cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags()); | ||
|
|
@@ -2675,6 +2676,106 @@ expandVPWidenIntOrFpInduction(VPWidenIntOrFpInductionRecipe *WidenIVR, | |
| WidenIVR->replaceAllUsesWith(WidePHI); | ||
| } | ||
|
|
||
| /// Expand a VPWidenPointerInductionRecipe into executable recipes, for the | ||
| /// initial value, phi and backedge value. In the following example: | ||
| /// | ||
| /// <x1> vector loop: { | ||
| /// vector.body: | ||
| /// EMIT ir<%ptr.iv> = WIDEN-POINTER-INDUCTION %start, %step, %vf | ||
| /// ... | ||
| /// EMIT branch-on-count ... | ||
| /// } | ||
| /// | ||
| /// WIDEN-POINTER-INDUCTION will get expanded to: | ||
| /// | ||
| /// <x1> vector loop: { | ||
| /// vector.body: | ||
| /// EMIT-SCALAR %pointer.phi = phi %start, %ptr.ind | ||
| /// EMIT %mul = mul %stepvector, %step | ||
| /// EMIT %vector.gep = ptradd %pointer.phi, %add | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// ... | ||
| /// EMIT %ptr.ind = ptradd %pointer.phi, %vf | ||
| /// EMIT branch-on-count ... | ||
| /// } | ||
| static void expandVPWidenPointerInduction(VPWidenPointerInductionRecipe *R, | ||
| VPTypeAnalysis &TypeInfo) { | ||
| VPlan *Plan = R->getParent()->getPlan(); | ||
|
|
||
| assert(R->getInductionDescriptor().getKind() == | ||
| InductionDescriptor::IK_PtrInduction && | ||
| "Not a pointer induction according to InductionDescriptor!"); | ||
| assert(TypeInfo.inferScalarType(R)->isPointerTy() && "Unexpected type."); | ||
| assert(!R->onlyScalarsGenerated(Plan->hasScalableVF()) && | ||
| "Recipe should have been replaced"); | ||
|
|
||
| unsigned CurrentPart = 0; | ||
| if (R->getNumOperands() > 3) | ||
| CurrentPart = | ||
| cast<ConstantInt>(R->getOperand(4)->getLiveInIRValue())->getZExtValue(); | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| VPBuilder Builder(R); | ||
| DebugLoc DL = R->getDebugLoc(); | ||
|
|
||
| // Build a pointer phi | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| VPPhi *Phi; | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (CurrentPart == 0) { | ||
| Phi = Builder.createScalarPhi({R->getStartValue()}, R->getDebugLoc(), | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| "pointer.phi"); | ||
| } else { | ||
| // The recipe has been unrolled. In that case, fetch the single pointer phi | ||
| // shared among all unrolled parts of the recipe. | ||
| auto *PtrAdd = cast<VPInstruction>(R->getOperand(3)); | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Phi = cast<VPPhi>(PtrAdd->getOperand(0)->getDefiningRecipe()); | ||
| } | ||
|
|
||
| Builder.setInsertPoint(R->getParent(), R->getParent()->getFirstNonPhi()); | ||
|
|
||
| // A pointer induction, performed by using a gep | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Type *PhiType = TypeInfo.inferScalarType(R->getStepValue()); | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| VPValue *RuntimeVF = Builder.createScalarZExtOrTrunc( | ||
| &Plan->getVF(), PhiType, TypeInfo.inferScalarType(&Plan->getVF()), DL); | ||
| if (CurrentPart == 0) { | ||
| // The recipe represents the first part of the pointer induction. Create the | ||
| // GEP to increment the phi across all unrolled parts. | ||
| VPValue *NumUnrolledElems = Builder.createScalarZExtOrTrunc( | ||
| R->getOperand(2), PhiType, TypeInfo.inferScalarType(R->getOperand(2)), | ||
| DL); | ||
| VPValue *Offset = Builder.createNaryOp( | ||
| Instruction::Mul, {R->getStepValue(), NumUnrolledElems}); | ||
|
|
||
| VPBuilder::InsertPointGuard Guard(Builder); | ||
| VPBasicBlock *ExitingBB = | ||
| Plan->getVectorLoopRegion()->getExitingBasicBlock(); | ||
| Builder.setInsertPoint(ExitingBB, | ||
| ExitingBB->getTerminator()->getIterator()); | ||
|
|
||
| VPValue *InductionGEP = Builder.createPtrAdd(Phi, Offset, DL, "ptr.ind"); | ||
| Phi->addOperand(InductionGEP); | ||
| } | ||
|
|
||
| VPValue *CurrentPartV = | ||
| Plan->getOrAddLiveIn(ConstantInt::get(PhiType, CurrentPart)); | ||
|
|
||
| // Create actual address geps that use the pointer phi as base and a | ||
| // vectorized version of the step value (<step*0, ..., step*N>) as offset. | ||
| VPValue *StartOffsetScalar = | ||
| Builder.createNaryOp(Instruction::Mul, {RuntimeVF, CurrentPartV}); | ||
| VPValue *StartOffset = | ||
| Builder.createNaryOp(VPInstruction::Broadcast, StartOffsetScalar); | ||
|
||
| // Create a vector of consecutive numbers from zero to VF. | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| StartOffset = Builder.createNaryOp( | ||
| Instruction::Add, | ||
| {StartOffset, | ||
| Builder.createNaryOp(VPInstruction::StepVector, {}, PhiType)}); | ||
|
||
|
|
||
| VPValue *PtrAdd = Builder.createWidePtrAdd( | ||
| Phi, | ||
| Builder.createNaryOp(Instruction::Mul, {StartOffset, R->getStepValue()}), | ||
| DL, "vector.gep"); | ||
|
|
||
| R->replaceAllUsesWith(PtrAdd); | ||
| } | ||
|
|
||
| void VPlanTransforms::dissolveLoopRegions(VPlan &Plan) { | ||
| // Replace loop regions with explicity CFG. | ||
| SmallVector<VPRegionBlock *> LoopRegions; | ||
|
|
@@ -2711,6 +2812,12 @@ void VPlanTransforms::convertToConcreteRecipes(VPlan &Plan, | |
| continue; | ||
| } | ||
|
|
||
| if (auto *WidenIVR = dyn_cast<VPWidenPointerInductionRecipe>(&R)) { | ||
| expandVPWidenPointerInduction(WidenIVR, TypeInfo); | ||
| ToRemove.push_back(WidenIVR); | ||
| continue; | ||
| } | ||
|
|
||
| if (auto *Expr = dyn_cast<VPExpressionRecipe>(&R)) { | ||
| Expr->decompose(); | ||
| ToRemove.push_back(Expr); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.