@@ -473,7 +473,7 @@ class VPBlockBase {
473
473
// / that are actually instantiated. Values of this enumeration are kept in the
474
474
// / SubclassID field of the VPBlockBase objects. They are used for concrete
475
475
// / type identification.
476
- using VPBlockTy = enum { VPBasicBlockSC, VPRegionBlockSC };
476
+ using VPBlockTy = enum { VPRegionBlockSC, VPBasicBlockSC, VPIRBasicBlockSC };
477
477
478
478
using VPBlocksTy = SmallVectorImpl<VPBlockBase *>;
479
479
@@ -2833,10 +2833,13 @@ class VPBasicBlock : public VPBlockBase {
2833
2833
public:
2834
2834
using RecipeListTy = iplist<VPRecipeBase>;
2835
2835
2836
- private :
2836
+ protected :
2837
2837
// / The VPRecipes held in the order of output instructions to generate.
2838
2838
RecipeListTy Recipes;
2839
2839
2840
+ VPBasicBlock (const unsigned char BlockSC, const Twine &Name = " " )
2841
+ : VPBlockBase(BlockSC, Name.str()) {}
2842
+
2840
2843
public:
2841
2844
VPBasicBlock (const Twine &Name = " " , VPRecipeBase *Recipe = nullptr )
2842
2845
: VPBlockBase(VPBasicBlockSC, Name.str()) {
@@ -2885,7 +2888,8 @@ class VPBasicBlock : public VPBlockBase {
2885
2888
2886
2889
// / Method to support type inquiry through isa, cast, and dyn_cast.
2887
2890
static inline bool classof (const VPBlockBase *V) {
2888
- return V->getVPBlockID () == VPBlockBase::VPBasicBlockSC;
2891
+ return V->getVPBlockID () == VPBlockBase::VPBasicBlockSC ||
2892
+ V->getVPBlockID () == VPBlockBase::VPIRBasicBlockSC;
2889
2893
}
2890
2894
2891
2895
void insert (VPRecipeBase *Recipe, iterator InsertPt) {
@@ -2948,12 +2952,48 @@ class VPBasicBlock : public VPBlockBase {
2948
2952
return NewBlock;
2949
2953
}
2950
2954
2955
+ protected:
2956
+ // / Execute the recipes in the IR basic block \p BB.
2957
+ void executeRecipes (VPTransformState *State, BasicBlock *BB);
2958
+
2951
2959
private:
2952
2960
// / Create an IR BasicBlock to hold the output instructions generated by this
2953
2961
// / VPBasicBlock, and return it. Update the CFGState accordingly.
2954
2962
BasicBlock *createEmptyBasicBlock (VPTransformState::CFGState &CFG);
2955
2963
};
2956
2964
2965
+ // / A special type of VPBasicBlock that wraps an existing IR basic block.
2966
+ // / Recipes of the block get added before the first non-phi instruction in the
2967
+ // / wrapped block.
2968
+ // / Note: At the moment, VPIRBasicBlock can only be used to wrap VPlan's
2969
+ // / preheader block.
2970
+ class VPIRBasicBlock : public VPBasicBlock {
2971
+ BasicBlock *IRBB;
2972
+
2973
+ public:
2974
+ VPIRBasicBlock (BasicBlock *IRBB)
2975
+ : VPBasicBlock(VPIRBasicBlockSC, " ph" ), IRBB(IRBB) {}
2976
+
2977
+ ~VPIRBasicBlock () override {}
2978
+
2979
+ static inline bool classof (const VPBlockBase *V) {
2980
+ return V->getVPBlockID () == VPBlockBase::VPIRBasicBlockSC;
2981
+ }
2982
+
2983
+ // / The method which generates the output IR instructions that correspond to
2984
+ // / this VPBasicBlock, thereby "executing" the VPlan.
2985
+ void execute (VPTransformState *State) override ;
2986
+
2987
+ VPIRBasicBlock *clone () override {
2988
+ auto *NewBlock = new VPIRBasicBlock (IRBB);
2989
+ for (VPRecipeBase &R : Recipes)
2990
+ NewBlock->appendRecipe (R.clone ());
2991
+ return NewBlock;
2992
+ }
2993
+
2994
+ BasicBlock *getIRBasicBlock () const { return IRBB; }
2995
+ };
2996
+
2957
2997
// / VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks
2958
2998
// / which form a Single-Entry-Single-Exiting subgraph of the output IR CFG.
2959
2999
// / A VPRegionBlock may indicate that its contents are to be replicated several
@@ -3142,12 +3182,12 @@ class VPlan {
3142
3182
~VPlan ();
3143
3183
3144
3184
// / Create initial VPlan skeleton, having an "entry" VPBasicBlock (wrapping
3145
- // / original scalar pre-header) which contains SCEV expansions that need to
3146
- // / happen before the CFG is modified; a VPBasicBlock for the vector
3185
+ // / original scalar pre-header \p PH ) which contains SCEV expansions that need
3186
+ // / to happen before the CFG is modified; a VPBasicBlock for the vector
3147
3187
// / pre-header, followed by a region for the vector loop, followed by the
3148
3188
// / middle VPBasicBlock.
3149
3189
static VPlanPtr createInitialVPlan (const SCEV *TripCount,
3150
- ScalarEvolution &PSE);
3190
+ ScalarEvolution &PSE, BasicBlock *PH );
3151
3191
3152
3192
// / Prepare the plan for execution, setting up the required live-in values.
3153
3193
void prepareToExecute (Value *TripCount, Value *VectorTripCount,
0 commit comments