-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[VPlan] Add VPPhiAccessors to provide interface for phi recipes (NFC) #129388
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 1 commit
b357af4
9113022
c61233f
a73a137
90b2d4d
f768b97
d6d6bb5
8dfd569
595b057
a2b4ebb
46780ab
54981bf
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 |
|---|---|---|
|
|
@@ -1085,6 +1085,62 @@ class VPIRInstruction : public VPRecipeBase { | |
| void extractLastLaneOfOperand(VPBuilder &Builder); | ||
| }; | ||
|
|
||
| /// Helper type to provide functions to access incoming values and blocks for | ||
| /// phi-like recipes. RecipeTy must be a sub-class of VPRecipeBase. | ||
| template <typename RecipeTy> class VPPhiAccessors { | ||
| /// Return a VPRecipeBase* to the current object. | ||
| const VPRecipeBase *getAsRecipe() const { | ||
| return static_cast<const RecipeTy *>(this); | ||
|
||
| } | ||
|
|
||
| public: | ||
| /// Returns the \p I th incoming VPValue. | ||
| VPValue *getIncomingValue(unsigned I) const { | ||
|
||
| return getAsRecipe()->getOperand(I); | ||
| } | ||
|
|
||
| /// Returns an interator range over the incoming values | ||
| VPUser::const_operand_range incoming_values() const { | ||
| return getAsRecipe()->operands(); | ||
| } | ||
|
|
||
| /// Returns the \p I th incoming block. | ||
|
||
| const VPBasicBlock *getIncomingBlock(unsigned Idx) const; | ||
|
Collaborator
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. Inline as well? Good to see its implementation next to that of getIncomingValue() and getNumIncoming().
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. It needs access to
Collaborator
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. Ok, probably better done separately, if at all. |
||
|
|
||
| using const_incoming_block_iterator = | ||
| mapped_iterator<detail::index_iterator, | ||
| std::function<const VPBasicBlock *(size_t)>>; | ||
| using const_incoming_blocks_range = | ||
| iterator_range<const_incoming_block_iterator>; | ||
|
|
||
| const_incoming_block_iterator incoming_block_begin() const { | ||
| return const_incoming_block_iterator( | ||
| detail::index_iterator(0), | ||
| [this](size_t Idx) { return getIncomingBlock(Idx); }); | ||
| } | ||
| const_incoming_block_iterator incoming_block_end() const { | ||
| return const_incoming_block_iterator( | ||
| detail::index_iterator(getAsRecipe()->getVPDefID() == | ||
|
||
| VPDef::VPWidenIntOrFpInductionSC | ||
| ? 2 | ||
| : getAsRecipe()->getNumOperands()), | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| [this](size_t Idx) { return getIncomingBlock(Idx); }); | ||
| } | ||
|
|
||
| /// Returns an iterator range over the incoming blocks. | ||
| const_incoming_blocks_range incoming_blocks() const { | ||
| return make_range(incoming_block_begin(), incoming_block_end()); | ||
| } | ||
|
|
||
| /// Returns an iterator range over pairs of incoming values and corrsponding | ||
lukel97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// incoming blocks. | ||
| detail::zippy<llvm::detail::zip_shortest, VPUser::const_operand_range, | ||
| const_incoming_blocks_range> | ||
| incoming_values_and_blocks() const { | ||
|
||
| return zip(incoming_values(), incoming_blocks()); | ||
| } | ||
| }; | ||
|
|
||
| /// VPWidenRecipe is a recipe for producing a widened instruction using the | ||
| /// opcode and operands of the recipe. This recipe covers most of the | ||
| /// traditional vectorization cases where each recipe transforms into a | ||
|
|
@@ -1944,7 +2000,8 @@ class VPScalarPHIRecipe : public VPHeaderPHIRecipe { | |
| /// recipe is placed in an entry block to a (non-replicate) region, it must have | ||
| /// exactly 2 incoming values, the first from the predecessor of the region and | ||
| /// the second from the exiting block of the region. | ||
| class VPWidenPHIRecipe : public VPSingleDefRecipe { | ||
| class VPWidenPHIRecipe : public VPSingleDefRecipe, | ||
| public VPPhiAccessors<VPWidenPHIRecipe> { | ||
| public: | ||
| /// Create a new VPWidenPHIRecipe for \p Phi with start value \p Start and | ||
| /// debug location \p DL. | ||
|
|
@@ -1970,12 +2027,6 @@ class VPWidenPHIRecipe : public VPSingleDefRecipe { | |
| void print(raw_ostream &O, const Twine &Indent, | ||
| VPSlotTracker &SlotTracker) const override; | ||
| #endif | ||
|
|
||
| /// Returns the \p I th incoming VPBasicBlock. | ||
| VPBasicBlock *getIncomingBlock(unsigned I); | ||
|
|
||
| /// Returns the \p I th incoming VPValue. | ||
| VPValue *getIncomingValue(unsigned I) { return getOperand(I); } | ||
| }; | ||
|
|
||
| /// A recipe for handling first-order recurrence phis. The start value is the | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1031,6 +1031,29 @@ void VPIRInstruction::print(raw_ostream &O, const Twine &Indent, | |
| } | ||
| #endif | ||
|
|
||
| static const VPBasicBlock *getIncomingBlockForRecipe(const VPRecipeBase *R, | ||
|
||
| unsigned I) { | ||
| const VPBasicBlock *Parent = R->getParent(); | ||
| const VPBlockBase *Pred = nullptr; | ||
| if (Parent->getNumPredecessors() > 0) { | ||
| Pred = Parent->getPredecessors()[I]; | ||
| } else { | ||
| auto *Region = Parent->getParent(); | ||
| assert(Region && !Region->isReplicator() && Region->getEntry() == Parent && | ||
| "must be in the entry block of a non-replicate region"); | ||
| assert( | ||
| I < 2 && | ||
| (R->getNumOperands() == 2 || isa<VPWidenIntOrFpInductionRecipe>(R)) && | ||
| "when placed in an entry block, only 2 incoming blocks are available"); | ||
|
|
||
| // I == 0 selects the predecessor of the region, I == 1 selects the region | ||
| // itself whose exiting block feeds the phi across the backedge. | ||
| Pred = I == 0 ? Region->getSinglePredecessor() : Region; | ||
| } | ||
|
|
||
| return Pred->getExitingBasicBlock(); | ||
| } | ||
|
|
||
| void VPWidenCallRecipe::execute(VPTransformState &State) { | ||
| assert(State.VF.isVector() && "not widening"); | ||
| State.setDebugLocFrom(getDebugLoc()); | ||
|
|
@@ -3580,25 +3603,10 @@ void VPReductionPHIRecipe::print(raw_ostream &O, const Twine &Indent, | |
| } | ||
| #endif | ||
|
|
||
| VPBasicBlock *VPWidenPHIRecipe::getIncomingBlock(unsigned I) { | ||
|
Collaborator
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. Better keep delegating the implementation of
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. This is now providing a specialized definition of |
||
| VPBasicBlock *Parent = getParent(); | ||
| VPBlockBase *Pred = nullptr; | ||
| if (Parent->getNumPredecessors() > 0) { | ||
| Pred = Parent->getPredecessors()[I]; | ||
| } else { | ||
| auto *Region = Parent->getParent(); | ||
| assert(Region && !Region->isReplicator() && Region->getEntry() == Parent && | ||
| "must be in the entry block of a non-replicate region"); | ||
| assert( | ||
| I < 2 && getNumOperands() == 2 && | ||
| "when placed in an entry block, only 2 incoming blocks are available"); | ||
|
|
||
| // I == 0 selects the predecessor of the region, I == 1 selects the region | ||
| // itself whose exiting block feeds the phi across the backedge. | ||
| Pred = I == 0 ? Region->getSinglePredecessor() : Region; | ||
| } | ||
|
|
||
| return Pred->getExitingBasicBlock(); | ||
| template <> | ||
| const VPBasicBlock * | ||
| VPPhiAccessors<VPWidenPHIRecipe>::getIncomingBlock(unsigned Idx) const { | ||
| return getIncomingBlockForRecipe(getAsRecipe(), Idx); | ||
| } | ||
|
|
||
| void VPWidenPHIRecipe::execute(VPTransformState &State) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Perhaps better to rename Inc to Idx? It sounds like a short form of increment or incoming.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a short form of incoming value, while Idx would refer to an Index?