-
Notifications
You must be signed in to change notification settings - Fork 12k
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
[VPlan] Add VPIRBasicBlock, use to model pre-preheader. #93398
Changes from all commits
35c5111
6f5a775
a7714cb
f469a3a
38c2da3
73729d4
872f0b5
92e31f8
c69dde0
bd83113
5374577
b4381ff
6285815
9ef075a
1134c38
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 |
---|---|---|
|
@@ -473,7 +473,7 @@ class VPBlockBase { | |
/// that are actually instantiated. Values of this enumeration are kept in the | ||
/// SubclassID field of the VPBlockBase objects. They are used for concrete | ||
/// type identification. | ||
using VPBlockTy = enum { VPBasicBlockSC, VPRegionBlockSC }; | ||
using VPBlockTy = enum { VPRegionBlockSC, VPBasicBlockSC, VPIRBasicBlockSC }; | ||
|
||
using VPBlocksTy = SmallVectorImpl<VPBlockBase *>; | ||
|
||
|
@@ -2833,10 +2833,13 @@ class VPBasicBlock : public VPBlockBase { | |
public: | ||
using RecipeListTy = iplist<VPRecipeBase>; | ||
|
||
private: | ||
protected: | ||
/// The VPRecipes held in the order of output instructions to generate. | ||
RecipeListTy Recipes; | ||
|
||
VPBasicBlock(const unsigned char BlockSC, const Twine &Name = "") | ||
: VPBlockBase(BlockSC, Name.str()) {} | ||
|
||
public: | ||
VPBasicBlock(const Twine &Name = "", VPRecipeBase *Recipe = nullptr) | ||
: VPBlockBase(VPBasicBlockSC, Name.str()) { | ||
|
@@ -2885,7 +2888,8 @@ class VPBasicBlock : public VPBlockBase { | |
|
||
/// Method to support type inquiry through isa, cast, and dyn_cast. | ||
static inline bool classof(const VPBlockBase *V) { | ||
return V->getVPBlockID() == VPBlockBase::VPBasicBlockSC; | ||
return V->getVPBlockID() == VPBlockBase::VPBasicBlockSC || | ||
V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC; | ||
} | ||
|
||
void insert(VPRecipeBase *Recipe, iterator InsertPt) { | ||
|
@@ -2948,12 +2952,48 @@ class VPBasicBlock : public VPBlockBase { | |
return NewBlock; | ||
} | ||
|
||
protected: | ||
/// Execute the recipes in the IR basic block \p BB. | ||
void executeRecipes(VPTransformState *State, BasicBlock *BB); | ||
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. Documentation missing. 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. Added, thanks! |
||
|
||
private: | ||
/// Create an IR BasicBlock to hold the output instructions generated by this | ||
/// VPBasicBlock, and return it. Update the CFGState accordingly. | ||
BasicBlock *createEmptyBasicBlock(VPTransformState::CFGState &CFG); | ||
}; | ||
|
||
/// A special type of VPBasicBlock that wraps an existing IR basic block. | ||
/// Recipes of the block get added before the first non-phi instruction in the | ||
/// wrapped block. | ||
/// Note: At the moment, VPIRBasicBlock can only be used to wrap VPlan's | ||
/// preheader block. | ||
class VPIRBasicBlock : public VPBasicBlock { | ||
BasicBlock *IRBB; | ||
|
||
public: | ||
VPIRBasicBlock(BasicBlock *IRBB) | ||
: VPBasicBlock(VPIRBasicBlockSC, "ph"), IRBB(IRBB) {} | ||
|
||
~VPIRBasicBlock() override {} | ||
|
||
static inline bool classof(const VPBlockBase *V) { | ||
return V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC; | ||
} | ||
|
||
/// The method which generates the output IR instructions that correspond to | ||
/// this VPBasicBlock, thereby "executing" the VPlan. | ||
void execute(VPTransformState *State) override; | ||
|
||
VPIRBasicBlock *clone() override { | ||
auto *NewBlock = new VPIRBasicBlock(IRBB); | ||
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 cloning produces multiple VPBB's holding the same IRBB, all destined to inject instructions into it following its last phi. Can we verify that the order in which these VPBB's will execute corresponds to related dependences - if any, perhaps by asserting that in any given VPlan all VPIRBasicBlocks hold distinct IRBB's? And/or document this concern. 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 updated the verifier to check that IR blocks aren't wrapped by multiple wrapper blocks per VPlan. 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 updated the verifier to check that IR blocks aren't wrapped by multiple wrapper blocks per VPlan. |
||
for (VPRecipeBase &R : Recipes) | ||
NewBlock->appendRecipe(R.clone()); | ||
return NewBlock; | ||
} | ||
|
||
BasicBlock *getIRBasicBlock() const { return IRBB; } | ||
}; | ||
|
||
/// VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks | ||
/// which form a Single-Entry-Single-Exiting subgraph of the output IR CFG. | ||
/// A VPRegionBlock may indicate that its contents are to be replicated several | ||
|
@@ -3142,12 +3182,12 @@ class VPlan { | |
~VPlan(); | ||
|
||
/// Create initial VPlan skeleton, having an "entry" VPBasicBlock (wrapping | ||
/// original scalar pre-header) which contains SCEV expansions that need to | ||
/// happen before the CFG is modified; a VPBasicBlock for the vector | ||
/// original scalar pre-header \p PH) which contains SCEV expansions that need | ||
/// to happen before the CFG is modified; a VPBasicBlock for the vector | ||
/// pre-header, followed by a region for the vector loop, followed by the | ||
/// middle VPBasicBlock. | ||
static VPlanPtr createInitialVPlan(const SCEV *TripCount, | ||
ScalarEvolution &PSE); | ||
ScalarEvolution &PSE, BasicBlock *PH); | ||
|
||
/// Prepare the plan for execution, setting up the required live-in values. | ||
void prepareToExecute(Value *TripCount, Value *VectorTripCount, | ||
|
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.
Yeah, Recipes can be made protected, now that a subclass may want to access them.
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.
Done, thanks