VPWidenIntOrFpInductionRecipe inherits from VPHeaderPHIRecipe since this recipe is phi like and only gets placed in vector header vp basic block.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Since VPWidenIntOrFpInductionRecipe exists is phi like and in the
header, but isnt a VPCSAHeaderPHIRecipe, I fix the verification check.
I think a isHeaderPhi function where recipes can report if they are
header phi like might be nice in the future.
@fhahn is there a reason why VPWidenIntOrFpInductionRecipe does not extend VPHeaderPHIRecipe? That might be a better solution than this one.
To respond to my own question:
I imagine VPWidenIntOrFpInductionRecipe does not extend VPHeaderPHIRecipe because if its changed to derive VPHeaderPHIRecipe, the PHI is the only one that can define this VPValue, even though there are two constructors which would like to set different underlying values for this VPValue:
- IV defines this VPValue
- Trunc defines this VPValue
An additional reason why it does not extend is:
> VPWidenIntOrFPInductionRecipe are not in the phi section of the header block for truncates of induction variables. Those recipes are moved to the phi section of the header block after applying SinkAfter, which relies on the original position of the trunc.
Therefore, I prefer the proposed solution.
Instead of using multiple isa checks in the same guard (and those same checks being duplicated across multiple ifs), move into utils method. Also move isPhi out of VPRecipeBase to reduce class bloat.
Thanks for the patch.
VPWidenIntOrFPInductionRecipe are not in the phi section of the header block for truncates of induction variables. Those recipes are moved to the phi section of the header block after applying SinkAfter, which relies on the original position of the trunc.
I am not sure if this is still true, we should move them to the header at construction time. If so, It would be better to VPWidenIntOrFpInductionRecipe inherit from VPHeaderPHIRecipe, unless that causes any other issues. They have the same base classes, so that should be fine.
I just saw that D142589 landed which removes the fact that VPWidenIntOrFpInductionRecipe are not in the header block for truncates of induction variables. So I think you are right that this is no longer a concern.
However, it is still the case the VPHeaderPHIRecipe only accepts PHINodes as its underlying value, but VPWidenIntOrFpInductionRecipe uses either PHINode or TruncInst as an underlying value. I see two approaches forward:
- Modify VPHeaderPHIRecipe to accept any Instruction as its underlying value.
- Only use PHINode as underlying value for VPWidenIntOrFpInductionRecipe.
I prefer option 1, as the only real change required is for the underlying instruction of a VPHeaderPHIRecipe to change from PHINode -> Instruction. Option 2 is more involved since we're currently creating two VPWidenIntOrFpInductionRecipe (one for the phi and one for the trunc), but we would need to only create one (since one recipe per underlying IR is permitted) and update the single recipe with the trunc information when we process the trunc as well as replace uses of the trunc with this recipe.
But I think also boils down to what does it mean to be a "phi-like" recipe. Does it mean that the input IR is phi like? Does it mean that the output IR is phi like? Do both need to be phi like? I think if we are okay with it meaning the output IR is phi like, then option 1 is acceptable. If we are okay with this definition of phi-like, then we are able to have phi-like VPInstructions (which do not have any input IR) in the future.
I have updated this patch with approach 1.
Thanks for the update! For the phi-like terminology, what matter is whether the recipe merges incoming values from different blocks.
After changing VPWidenIntOrFpInductionRecipe, are the other changes still needed?
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
10470 ↗ | (On Diff #499266) | that should not be needed I think, cast asserts that the argument isa VPHeaderPHIRecipe. |
llvm/lib/Transforms/Vectorize/VPlan.h | ||
---|---|---|
1186 | Could you make sure that the code movement preserves the original code? I didn't check all lines, but it looks like the original code had a newline before here. |
After changing VPWidenIntOrFpInductionRecipe, are the other changes still needed?
I think this change reduces class bloat (since not all recipes are phi like, header phi like, or generate backedge). It also makes it so we only use RecipeTy in classof and uses isa to determine whether something isPhi.
I have some changes I plan to upstream in the near future that I think will give these util functions an even stronger justification for existing. If you don't think that the justifications i give are strong enough now, I am happy to remove them from this patch and include them in the future patch I mentioned.
Usually we try to keep unrelated changes as separate patches, if possible. It seems like fixing the inheritance can be done on its own and the isPhi changes can be done & discussed separately from that issue.
This change makes a lot of sense, except for getBackedgeValue() - see comment.
llvm/lib/Transforms/Vectorize/VPlan.h | ||
---|---|---|
1219–1220 | Now that VPWidenIntOrFpInductionRecipe inherits from VPHeaderPHIRecipe, it also inherits getBackedgeValue(), which should return a VPValue defined by some recipe - getBackedgeRecipe() - inside the loop. The default returns getOperand(1). However, VPWidenIntOrFpInductionRecipe has no such VPValue nor recipe to return because it takes care of generating the corresponding IR code only during execution. Better override getBackedgeValue() and getBackedgeRecipe(), asserting they are unreachable/never called? | |
1224–1229 | nit: these should now be one liners. |
llvm/lib/Transforms/Vectorize/VPlan.h | ||
---|---|---|
1219–1220 | I'm happy to add the overridden methods with unreachables in them for now. However, I think in the future it would be nice if a recipe extends another recipe, all operands of the base recipe must exist and be at the same index in the parent recipe. If not all derived versions of HeaderPHIRecipes have backedge values and recipes, then it should not belong in the base class. |
llvm/lib/Transforms/Vectorize/VPlan.h | ||
---|---|---|
1219–1220 | Agreed. This calls for a refactoring of VPWidenIntOrFpInductionRecipe, which will hopefully simplify its execute() to avoid inserting IR code in multiple points. Also calls for checking other derivatives of HeaderPHIRecipe, including VPWidenPointerInductionRecipe. Worth leaving behind a TODO to clean-up them unreachables? |
Could you make sure that the code movement preserves the original code? I didn't check all lines, but it looks like the original code had a newline before here.