@@ -274,32 +274,28 @@ void VPRecipeBase::moveBefore(VPBasicBlock &BB,
274
274
insertBefore (BB, I);
275
275
}
276
276
277
- // / Return the underlying instruction to be used for computing \p R's cost via
278
- // / the legacy cost model. Return nullptr if there's no suitable instruction or
279
- // / computeCost is already implemented for the recipe and there is no need for
280
- // / the underlying instruction, i.e. it does not need to be skipped for cost
281
- // / computations.
282
- static Instruction *getInstructionForCost (const VPRecipeBase *R) {
283
- if (auto *S = dyn_cast<VPSingleDefRecipe>(R))
284
- return dyn_cast_or_null<Instruction>(S->getUnderlyingValue ());
285
- if (auto *IG = dyn_cast<VPInterleaveRecipe>(R))
286
- return IG->getInsertPos ();
287
- return nullptr ;
288
- }
289
-
290
277
InstructionCost VPRecipeBase::cost (ElementCount VF, VPCostContext &Ctx) {
291
- auto *UI = getInstructionForCost (this );
292
- if (UI && Ctx.skipCostComputation (UI, VF.isVector ()))
293
- return 0 ;
294
-
295
- InstructionCost RecipeCost = computeCost (VF, Ctx);
296
- if (ForceTargetInstructionCost.getNumOccurrences () > 0 &&
297
- (RecipeCost.isValid () && RecipeCost != InstructionCost::getMax ()))
298
- RecipeCost = InstructionCost (ForceTargetInstructionCost);
299
- // Max cost is used as a sentinel value to detect recipes without underlying
300
- // instructions for which no forced target instruction cost should be applied.
301
- else if (RecipeCost == InstructionCost::getMax ())
278
+ // Get the underlying instruction for the recipe, if there is one. Is is used
279
+ // to
280
+ // * decide if cost computation should be skipped for this recipe
281
+ // * apply forced target instr
282
+ Instruction *UI = nullptr ;
283
+ if (auto *S = dyn_cast<VPSingleDefRecipe>(this ))
284
+ UI = dyn_cast_or_null<Instruction>(S->getUnderlyingValue ());
285
+ else if (auto *IG = dyn_cast<VPInterleaveRecipe>(this ))
286
+ UI = IG->getInsertPos ();
287
+ else if (auto *WidenMem = dyn_cast<VPWidenMemoryRecipe>(this ))
288
+ UI = &WidenMem->getIngredient ();
289
+
290
+ InstructionCost RecipeCost;
291
+ if (UI && Ctx.skipCostComputation (UI, VF.isVector ())) {
302
292
RecipeCost = 0 ;
293
+ } else {
294
+ RecipeCost = computeCost (VF, Ctx);
295
+ if (UI && ForceTargetInstructionCost.getNumOccurrences () > 0 &&
296
+ RecipeCost.isValid ())
297
+ RecipeCost = InstructionCost (ForceTargetInstructionCost);
298
+ }
303
299
304
300
LLVM_DEBUG ({
305
301
dbgs () << " Cost of " << RecipeCost << " for VF " << VF << " : " ;
@@ -310,20 +306,18 @@ InstructionCost VPRecipeBase::cost(ElementCount VF, VPCostContext &Ctx) {
310
306
311
307
InstructionCost VPRecipeBase::computeCost (ElementCount VF,
312
308
VPCostContext &Ctx) const {
313
- // Compute the cost for the recipe falling back to the legacy cost model using
314
- // the underlying instruction. If there is no underlying instruction or the
315
- // cost is computed by the recipe's computeCost, returns
316
- // InstructionCost::getMax. It is used as a sentinel value to detect recipes
317
- // without underlying instructions for which no forced target instruction cost
318
- // should be applied.
319
-
320
- Instruction *UI = getInstructionForCost (this );
309
+ llvm_unreachable (" subclasses should implement computeCost" );
310
+ }
311
+
312
+ InstructionCost VPSingleDefRecipe::computeCost (ElementCount VF,
313
+ VPCostContext &Ctx) const {
314
+ Instruction *UI = dyn_cast_or_null<Instruction>(getUnderlyingValue ());
321
315
if (UI && isa<VPReplicateRecipe>(this )) {
322
316
// VPReplicateRecipe may be cloned as part of an existing VPlan-to-VPlan
323
317
// transform, avoid computing their cost multiple times for now.
324
318
Ctx.SkipCostComputation .insert (UI);
325
319
}
326
- return UI ? Ctx.getLegacyCost (UI, VF) : InstructionCost::getMax () ;
320
+ return UI ? Ctx.getLegacyCost (UI, VF) : 0 ;
327
321
}
328
322
329
323
FastMathFlags VPRecipeWithIRFlags::getFastMathFlags () const {
@@ -867,6 +861,11 @@ void VPIRInstruction::execute(VPTransformState &State) {
867
861
State.Builder .SetInsertPoint (I.getParent (), std::next (I.getIterator ()));
868
862
}
869
863
864
+ InstructionCost VPIRInstruction::computeCost (ElementCount VF,
865
+ VPCostContext &Ctx) const {
866
+ return 0 ;
867
+ }
868
+
870
869
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
871
870
void VPIRInstruction::print (raw_ostream &O, const Twine &Indent,
872
871
VPSlotTracker &SlotTracker) const {
@@ -2159,6 +2158,11 @@ void VPBranchOnMaskRecipe::execute(VPTransformState &State) {
2159
2158
ReplaceInstWithInst (CurrentTerminator, CondBr);
2160
2159
}
2161
2160
2161
+ InstructionCost VPBranchOnMaskRecipe::computeCost (ElementCount VF,
2162
+ VPCostContext &Ctx) const {
2163
+ return 0 ;
2164
+ }
2165
+
2162
2166
void VPPredInstPHIRecipe::execute (VPTransformState &State) {
2163
2167
assert (State.Lane && " Predicated instruction PHI works per instance." );
2164
2168
Instruction *ScalarPredInst =
@@ -2841,6 +2845,11 @@ void VPInterleaveRecipe::print(raw_ostream &O, const Twine &Indent,
2841
2845
}
2842
2846
#endif
2843
2847
2848
+ InstructionCost VPInterleaveRecipe::computeCost (ElementCount VF,
2849
+ VPCostContext &Ctx) const {
2850
+ return Ctx.getLegacyCost (IG->getInsertPos (), VF);
2851
+ }
2852
+
2844
2853
void VPCanonicalIVPHIRecipe::execute (VPTransformState &State) {
2845
2854
Value *Start = getStartValue ()->getLiveInIRValue ();
2846
2855
PHINode *Phi = PHINode::Create (Start->getType (), 2 , " index" );
0 commit comments