@@ -280,33 +280,28 @@ void VPRecipeBase::moveBefore(VPBasicBlock &BB,
280280 insertBefore (BB, I);
281281}
282282
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-
301283InstructionCost 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+ }
310305
311306 LLVM_DEBUG ({
312307 dbgs () << " Cost of " << RecipeCost << " for VF " << VF << " : " ;
@@ -317,11 +312,14 @@ InstructionCost VPRecipeBase::cost(ElementCount VF, VPCostContext &Ctx) {
317312
318313InstructionCost VPRecipeBase::computeCost (ElementCount VF,
319314 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" );
325323 // VPReplicateRecipe may be cloned as part of an existing VPlan-to-VPlan
326324 // transform, avoid computing their cost multiple times for now.
327325 Ctx.SkipCostComputation .insert (UI);
@@ -870,6 +868,13 @@ void VPIRInstruction::execute(VPTransformState &State) {
870868 State.Builder .SetInsertPoint (I.getParent (), std::next (I.getIterator ()));
871869}
872870
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+
873878#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
874879void VPIRInstruction::print (raw_ostream &O, const Twine &Indent,
875880 VPSlotTracker &SlotTracker) const {
@@ -2210,6 +2215,14 @@ void VPBranchOnMaskRecipe::execute(VPTransformState &State) {
22102215 ReplaceInstWithInst (CurrentTerminator, CondBr);
22112216}
22122217
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+
22132226void VPPredInstPHIRecipe::execute (VPTransformState &State) {
22142227 assert (State.Lane && " Predicated instruction PHI works per instance." );
22152228 Instruction *ScalarPredInst =
@@ -2892,6 +2905,11 @@ void VPInterleaveRecipe::print(raw_ostream &O, const Twine &Indent,
28922905}
28932906#endif
28942907
2908+ InstructionCost VPInterleaveRecipe::computeCost (ElementCount VF,
2909+ VPCostContext &Ctx) const {
2910+ return Ctx.getLegacyCost (IG->getInsertPos (), VF);
2911+ }
2912+
28952913void VPCanonicalIVPHIRecipe::execute (VPTransformState &State) {
28962914 Value *Start = getStartValue ()->getLiveInIRValue ();
28972915 PHINode *Phi = PHINode::Create (Start->getType (), 2 , " index" );
0 commit comments