@@ -280,33 +280,28 @@ void VPRecipeBase::moveBefore(VPBasicBlock &BB,
280
280
insertBefore (BB, I);
281
281
}
282
282
283
- // / Return the underlying instruction to be used for computing \p R's cost via
284
- // / the legacy cost model. Return nullptr if there's no suitable instruction.
285
- static Instruction *getInstructionForCost (const VPRecipeBase *R) {
286
- if (auto *S = dyn_cast<VPSingleDefRecipe>(R))
287
- return dyn_cast_or_null<Instruction>(S->getUnderlyingValue ());
288
- if (auto *IG = dyn_cast<VPInterleaveRecipe>(R))
289
- return IG->getInsertPos ();
290
- // Currently the legacy cost model only calculates the instruction cost with
291
- // underlying instruction. Removing the WidenMem here will prevent
292
- // force-target-instruction-cost overwriting the cost of recipe with
293
- // underlying instruction which is inconsistent with the legacy model.
294
- // TODO: Remove WidenMem from this function when we don't need to compare to
295
- // the legacy model.
296
- if (auto *WidenMem = dyn_cast<VPWidenMemoryRecipe>(R))
297
- return &WidenMem->getIngredient ();
298
- return nullptr ;
299
- }
300
-
301
283
InstructionCost VPRecipeBase::cost (ElementCount VF, VPCostContext &Ctx) {
302
- auto *UI = getInstructionForCost (this );
303
- if (UI && Ctx.skipCostComputation (UI, VF.isVector ()))
304
- return 0 ;
305
-
306
- InstructionCost RecipeCost = computeCost (VF, Ctx);
307
- if (UI && ForceTargetInstructionCost.getNumOccurrences () > 0 &&
308
- RecipeCost.isValid ())
309
- RecipeCost = InstructionCost (ForceTargetInstructionCost);
284
+ // Get the underlying instruction for the recipe, if there is one. It is used
285
+ // to
286
+ // * decide if cost computation should be skipped for this recipe,
287
+ // * apply forced target instruction cost.
288
+ Instruction *UI = nullptr ;
289
+ if (auto *S = dyn_cast<VPSingleDefRecipe>(this ))
290
+ UI = dyn_cast_or_null<Instruction>(S->getUnderlyingValue ());
291
+ else if (auto *IG = dyn_cast<VPInterleaveRecipe>(this ))
292
+ UI = IG->getInsertPos ();
293
+ else if (auto *WidenMem = dyn_cast<VPWidenMemoryRecipe>(this ))
294
+ UI = &WidenMem->getIngredient ();
295
+
296
+ InstructionCost RecipeCost;
297
+ if (UI && Ctx.skipCostComputation (UI, VF.isVector ())) {
298
+ RecipeCost = 0 ;
299
+ } else {
300
+ RecipeCost = computeCost (VF, Ctx);
301
+ if (UI && ForceTargetInstructionCost.getNumOccurrences () > 0 &&
302
+ RecipeCost.isValid ())
303
+ RecipeCost = InstructionCost (ForceTargetInstructionCost);
304
+ }
310
305
311
306
LLVM_DEBUG ({
312
307
dbgs () << " Cost of " << RecipeCost << " for VF " << VF << " : " ;
@@ -317,11 +312,14 @@ InstructionCost VPRecipeBase::cost(ElementCount VF, VPCostContext &Ctx) {
317
312
318
313
InstructionCost VPRecipeBase::computeCost (ElementCount VF,
319
314
VPCostContext &Ctx) const {
320
- // Compute the cost for the recipe falling back to the legacy cost model using
321
- // the underlying instruction. If there is no underlying instruction, returns
322
- // 0.
323
- Instruction *UI = getInstructionForCost (this );
324
- if (UI && isa<VPReplicateRecipe>(this )) {
315
+ llvm_unreachable (" subclasses should implement computeCost" );
316
+ }
317
+
318
+ InstructionCost VPSingleDefRecipe::computeCost (ElementCount VF,
319
+ VPCostContext &Ctx) const {
320
+ Instruction *UI = dyn_cast_or_null<Instruction>(getUnderlyingValue ());
321
+ if (isa<VPReplicateRecipe>(this )) {
322
+ assert (UI && " VPReplicateRecipe must have an underlying instruction" );
325
323
// VPReplicateRecipe may be cloned as part of an existing VPlan-to-VPlan
326
324
// transform, avoid computing their cost multiple times for now.
327
325
Ctx.SkipCostComputation .insert (UI);
@@ -870,6 +868,13 @@ void VPIRInstruction::execute(VPTransformState &State) {
870
868
State.Builder .SetInsertPoint (I.getParent (), std::next (I.getIterator ()));
871
869
}
872
870
871
+ InstructionCost VPIRInstruction::computeCost (ElementCount VF,
872
+ VPCostContext &Ctx) const {
873
+ // The recipe wraps an existing IR instruction on the border of VPlan's scope,
874
+ // hence it does not contribute to the cost-modeling for the VPlan.
875
+ return 0 ;
876
+ }
877
+
873
878
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
874
879
void VPIRInstruction::print (raw_ostream &O, const Twine &Indent,
875
880
VPSlotTracker &SlotTracker) const {
@@ -2210,6 +2215,14 @@ void VPBranchOnMaskRecipe::execute(VPTransformState &State) {
2210
2215
ReplaceInstWithInst (CurrentTerminator, CondBr);
2211
2216
}
2212
2217
2218
+ InstructionCost VPBranchOnMaskRecipe::computeCost (ElementCount VF,
2219
+ VPCostContext &Ctx) const {
2220
+ // The legacy cost model doesn't assign costs to branches for individual
2221
+ // replicate regions. Match the current behavior in the VPlan cost model for
2222
+ // now.
2223
+ return 0 ;
2224
+ }
2225
+
2213
2226
void VPPredInstPHIRecipe::execute (VPTransformState &State) {
2214
2227
assert (State.Lane && " Predicated instruction PHI works per instance." );
2215
2228
Instruction *ScalarPredInst =
@@ -2892,6 +2905,11 @@ void VPInterleaveRecipe::print(raw_ostream &O, const Twine &Indent,
2892
2905
}
2893
2906
#endif
2894
2907
2908
+ InstructionCost VPInterleaveRecipe::computeCost (ElementCount VF,
2909
+ VPCostContext &Ctx) const {
2910
+ return Ctx.getLegacyCost (IG->getInsertPos (), VF);
2911
+ }
2912
+
2895
2913
void VPCanonicalIVPHIRecipe::execute (VPTransformState &State) {
2896
2914
Value *Start = getStartValue ()->getLiveInIRValue ();
2897
2915
PHINode *Phi = PHINode::Create (Start->getType (), 2 , " index" );
0 commit comments