@@ -68,10 +68,15 @@ class VPRecipeBuilder {
68
68
69
69
VPBuilder &Builder;
70
70
71
- // / The mask of each VPBB, generated earlier and used for predicating recipes
72
- // / in VPBB.
73
- // / TODO: remove by applying predication when generating the masks.
74
- DenseMap<VPBasicBlock *, VPValue *> &BlockMaskCache;
71
+ // / When we if-convert we need to create edge masks. We have to cache values
72
+ // / so that we don't end up with exponential recursion/IR. Note that
73
+ // / if-conversion currently takes place during VPlan-construction, so these
74
+ // / caches are only used at that stage.
75
+ using EdgeMaskCacheTy =
76
+ DenseMap<std::pair<BasicBlock *, BasicBlock *>, VPValue *>;
77
+ using BlockMaskCacheTy = DenseMap<BasicBlock *, VPValue *>;
78
+ EdgeMaskCacheTy EdgeMaskCache;
79
+ BlockMaskCacheTy BlockMaskCache;
75
80
76
81
// VPlan construction support: Hold a mapping from ingredients to
77
82
// their recipe.
@@ -85,6 +90,10 @@ class VPRecipeBuilder {
85
90
// / A mapping of partial reduction exit instructions to their scaling factor.
86
91
DenseMap<const Instruction *, unsigned > ScaledReductionMap;
87
92
93
+ // / A mapping from VP blocks to IR blocks, used temporarily while migrating
94
+ // / away from IR references.
95
+ const DenseMap<const VPBlockBase *, BasicBlock *> &VPB2IRBB;
96
+
88
97
// / Loop versioning instance for getting noalias metadata guaranteed by
89
98
// / runtime checks.
90
99
LoopVersioning *LVer;
@@ -113,6 +122,11 @@ class VPRecipeBuilder {
113
122
tryToOptimizeInductionTruncate (TruncInst *I, ArrayRef<VPValue *> Operands,
114
123
VFRange &Range);
115
124
125
+ // / Handle non-loop phi nodes, returning a new VPBlendRecipe. Currently
126
+ // / all such phi nodes are turned into a sequence of select instructions as
127
+ // / the vectorizer currently performs full if-conversion.
128
+ VPBlendRecipe *tryToBlend (VPWidenPHIRecipe *PhiR);
129
+
116
130
// / Handle call instructions. If \p CI can be widened for \p Range.Start,
117
131
// / return a new VPWidenCallRecipe or VPWidenIntrinsicRecipe. Range.End may be
118
132
// / decreased to ensure same decision from \p Range.Start to \p Range.End.
@@ -150,11 +164,10 @@ class VPRecipeBuilder {
150
164
LoopVectorizationLegality *Legal,
151
165
LoopVectorizationCostModel &CM,
152
166
PredicatedScalarEvolution &PSE, VPBuilder &Builder,
153
- DenseMap<VPBasicBlock *, VPValue *> &BlockMaskCache ,
167
+ const DenseMap<const VPBlockBase *, BasicBlock *> &VPB2IRBB ,
154
168
LoopVersioning *LVer)
155
169
: Plan(Plan), OrigLoop(OrigLoop), TLI(TLI), TTI(TTI), Legal(Legal),
156
- CM (CM), PSE(PSE), Builder(Builder), BlockMaskCache(BlockMaskCache),
157
- LVer(LVer) {}
170
+ CM (CM), PSE(PSE), Builder(Builder), VPB2IRBB(VPB2IRBB), LVer(LVer) {}
158
171
159
172
std::optional<unsigned > getScalingForReduction (const Instruction *ExitInst) {
160
173
auto It = ScaledReductionMap.find (ExitInst);
@@ -183,11 +196,38 @@ class VPRecipeBuilder {
183
196
Ingredient2Recipe[I] = R;
184
197
}
185
198
186
- // / Returns the *entry* mask for block \p VPBB or null if the mask is
187
- // / all-true.
188
- VPValue *getBlockInMask (VPBasicBlock *VPBB) const {
189
- return BlockMaskCache.lookup (VPBB);
199
+ // / Create the mask for the vector loop header block.
200
+ void createHeaderMask ();
201
+
202
+ // / A helper function that computes the predicate of the block BB, assuming
203
+ // / that the header block of the loop is set to True or the loop mask when
204
+ // / tail folding.
205
+ void createBlockInMask (const VPBasicBlock *VPBB) {
206
+ return createBlockInMask (VPB2IRBB.lookup (VPBB));
190
207
}
208
+ void createBlockInMask (BasicBlock *BB);
209
+
210
+ // / Returns the *entry* mask for the block \p VPBB.
211
+ VPValue *getBlockInMask (const VPBasicBlock *VPBB) const {
212
+ return getBlockInMask (VPB2IRBB.lookup (VPBB));
213
+ }
214
+
215
+ // / Returns the *entry* mask for the block \p BB.
216
+ VPValue *getBlockInMask (BasicBlock *BB) const ;
217
+
218
+ // / Create an edge mask for every destination of cases and/or default.
219
+ void createSwitchEdgeMasks (SwitchInst *SI);
220
+
221
+ // / A helper function that computes the predicate of the edge between SRC
222
+ // / and DST.
223
+ VPValue *createEdgeMask (BasicBlock *Src, BasicBlock *Dst);
224
+
225
+ // / A helper that returns the previously computed predicate of the edge
226
+ // / between SRC and DST.
227
+ VPValue *getEdgeMask (const VPBasicBlock *Src, const VPBasicBlock *Dst) const {
228
+ return getEdgeMask (VPB2IRBB.lookup (Src), VPB2IRBB.lookup (Dst));
229
+ }
230
+ VPValue *getEdgeMask (BasicBlock *Src, BasicBlock *Dst) const ;
191
231
192
232
// / Return the recipe created for given ingredient.
193
233
VPRecipeBase *getRecipe (Instruction *I) {
@@ -212,15 +252,6 @@ class VPRecipeBuilder {
212
252
}
213
253
return Plan.getOrAddLiveIn (V);
214
254
}
215
-
216
- void updateBlockMaskCache (DenseMap<VPValue *, VPValue *> &Old2New) {
217
- for (auto &[_, V] : BlockMaskCache) {
218
- if (auto *New = Old2New.lookup (V)) {
219
- V->replaceAllUsesWith (New);
220
- V = New;
221
- }
222
- }
223
- }
224
255
};
225
256
} // end namespace llvm
226
257
0 commit comments