@@ -274,32 +274,28 @@ void VPRecipeBase::moveBefore(VPBasicBlock &BB,
274274 insertBefore (BB, I);
275275}
276276
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-
290277InstructionCost 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 ())) {
302292 RecipeCost = 0 ;
293+ } else {
294+ RecipeCost = computeCost (VF, Ctx);
295+ if (UI && ForceTargetInstructionCost.getNumOccurrences () > 0 &&
296+ RecipeCost.isValid ())
297+ RecipeCost = InstructionCost (ForceTargetInstructionCost);
298+ }
303299
304300 LLVM_DEBUG ({
305301 dbgs () << " Cost of " << RecipeCost << " for VF " << VF << " : " ;
@@ -310,20 +306,18 @@ InstructionCost VPRecipeBase::cost(ElementCount VF, VPCostContext &Ctx) {
310306
311307InstructionCost VPRecipeBase::computeCost (ElementCount VF,
312308 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 ());
321315 if (UI && isa<VPReplicateRecipe>(this )) {
322316 // VPReplicateRecipe may be cloned as part of an existing VPlan-to-VPlan
323317 // transform, avoid computing their cost multiple times for now.
324318 Ctx.SkipCostComputation .insert (UI);
325319 }
326- return UI ? Ctx.getLegacyCost (UI, VF) : InstructionCost::getMax () ;
320+ return UI ? Ctx.getLegacyCost (UI, VF) : 0 ;
327321}
328322
329323FastMathFlags VPRecipeWithIRFlags::getFastMathFlags () const {
@@ -867,6 +861,11 @@ void VPIRInstruction::execute(VPTransformState &State) {
867861 State.Builder .SetInsertPoint (I.getParent (), std::next (I.getIterator ()));
868862}
869863
864+ InstructionCost VPIRInstruction::computeCost (ElementCount VF,
865+ VPCostContext &Ctx) const {
866+ return 0 ;
867+ }
868+
870869#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
871870void VPIRInstruction::print (raw_ostream &O, const Twine &Indent,
872871 VPSlotTracker &SlotTracker) const {
@@ -2159,6 +2158,11 @@ void VPBranchOnMaskRecipe::execute(VPTransformState &State) {
21592158 ReplaceInstWithInst (CurrentTerminator, CondBr);
21602159}
21612160
2161+ InstructionCost VPBranchOnMaskRecipe::computeCost (ElementCount VF,
2162+ VPCostContext &Ctx) const {
2163+ return 0 ;
2164+ }
2165+
21622166void VPPredInstPHIRecipe::execute (VPTransformState &State) {
21632167 assert (State.Lane && " Predicated instruction PHI works per instance." );
21642168 Instruction *ScalarPredInst =
@@ -2841,6 +2845,11 @@ void VPInterleaveRecipe::print(raw_ostream &O, const Twine &Indent,
28412845}
28422846#endif
28432847
2848+ InstructionCost VPInterleaveRecipe::computeCost (ElementCount VF,
2849+ VPCostContext &Ctx) const {
2850+ return Ctx.getLegacyCost (IG->getInsertPos (), VF);
2851+ }
2852+
28442853void VPCanonicalIVPHIRecipe::execute (VPTransformState &State) {
28452854 Value *Start = getStartValue ()->getLiveInIRValue ();
28462855 PHINode *Phi = PHINode::Create (Start->getType (), 2 , " index" );
0 commit comments