Skip to content

Commit ed220e1

Browse files
authored
[VPlan][NFC] Implement VPWidenMemoryRecipe::computeCost(). (#105614)
In this patch, we implement the `computeCost()` function in `VPWidenMemoryRecipe`.
1 parent b057e16 commit ed220e1

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2539,6 +2539,10 @@ class VPWidenMemoryRecipe : public VPRecipeBase {
25392539
llvm_unreachable("VPWidenMemoryRecipe should not be instantiated.");
25402540
}
25412541

2542+
/// Return the cost of this VPWidenMemoryRecipe.
2543+
InstructionCost computeCost(ElementCount VF,
2544+
VPCostContext &Ctx) const override;
2545+
25422546
Instruction &getIngredient() const { return Ingredient; }
25432547
};
25442548

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,12 @@ static Instruction *getInstructionForCost(const VPRecipeBase *R) {
272272
return dyn_cast_or_null<Instruction>(S->getUnderlyingValue());
273273
if (auto *IG = dyn_cast<VPInterleaveRecipe>(R))
274274
return IG->getInsertPos();
275+
// Currently the legacy cost model only calculates the instruction cost with
276+
// underlying instruction. Removing the WidenMem here will prevent
277+
// force-target-instruction-cost overwriting the cost of recipe with
278+
// underlying instruction which is inconsistent with the legacy model.
279+
// TODO: Remove WidenMem from this function when we don't need to compare to
280+
// the legacy model.
275281
if (auto *WidenMem = dyn_cast<VPWidenMemoryRecipe>(R))
276282
return &WidenMem->getIngredient();
277283
return nullptr;
@@ -2132,6 +2138,46 @@ void VPPredInstPHIRecipe::print(raw_ostream &O, const Twine &Indent,
21322138
}
21332139
#endif
21342140

2141+
InstructionCost VPWidenMemoryRecipe::computeCost(ElementCount VF,
2142+
VPCostContext &Ctx) const {
2143+
Type *Ty = ToVectorTy(getLoadStoreType(&Ingredient), VF);
2144+
const Align Alignment =
2145+
getLoadStoreAlignment(const_cast<Instruction *>(&Ingredient));
2146+
unsigned AS =
2147+
getLoadStoreAddressSpace(const_cast<Instruction *>(&Ingredient));
2148+
TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput;
2149+
2150+
if (!Consecutive) {
2151+
// TODO: Using the original IR may not be accurate.
2152+
// Currently, ARM will use the underlying IR to calculate gather/scatter
2153+
// instruction cost.
2154+
const Value *Ptr = getLoadStorePointerOperand(&Ingredient);
2155+
assert(!Reverse &&
2156+
"Inconsecutive memory access should not have the order.");
2157+
return Ctx.TTI.getAddressComputationCost(Ty) +
2158+
Ctx.TTI.getGatherScatterOpCost(Ingredient.getOpcode(), Ty, Ptr,
2159+
IsMasked, Alignment, CostKind,
2160+
&Ingredient);
2161+
}
2162+
2163+
InstructionCost Cost = 0;
2164+
if (IsMasked) {
2165+
Cost += Ctx.TTI.getMaskedMemoryOpCost(Ingredient.getOpcode(), Ty, Alignment,
2166+
AS, CostKind);
2167+
} else {
2168+
TTI::OperandValueInfo OpInfo =
2169+
Ctx.TTI.getOperandInfo(Ingredient.getOperand(0));
2170+
Cost += Ctx.TTI.getMemoryOpCost(Ingredient.getOpcode(), Ty, Alignment, AS,
2171+
CostKind, OpInfo, &Ingredient);
2172+
}
2173+
if (!Reverse)
2174+
return Cost;
2175+
2176+
return Cost += Ctx.TTI.getShuffleCost(TargetTransformInfo::SK_Reverse,
2177+
cast<VectorType>(Ty), std::nullopt,
2178+
CostKind, 0);
2179+
}
2180+
21352181
void VPWidenLoadRecipe::execute(VPTransformState &State) {
21362182
auto *LI = cast<LoadInst>(&Ingredient);
21372183

0 commit comments

Comments
 (0)