[llvm] [LV] Mark functions in legacy cost model const (NFC) (PR #216282)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 02:49:55 PDT 2026
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/216282
>From 32b247239c1114fccd33aabbb54d51e6c8a228e1 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Fri, 14 Aug 2026 10:01:30 +0100
Subject: [PATCH 1/2] [LV] Mark functions in legacy cost model const (NFC)
To make clear that these functions do not set widening decisions or
mutate any other state in LoopVectorizationCostModel, mark them const.
We also remove the unnecessary getBFI function.
---
.../Transforms/Vectorize/LoopVectorize.cpp | 40 ++++++++-----------
1 file changed, 16 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 8ca56cb727423..d326decde60d4 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -1033,11 +1033,11 @@ class LoopVectorizationCostModel {
/// every iteration of the loop header.
inline uint64_t
getPredBlockCostDivisor(TargetTransformInfo::TargetCostKind CostKind,
- const BasicBlock *BB);
+ const BasicBlock *BB) const;
/// Returns true if an artificially high cost for emulated masked memrefs
/// should be used.
- bool useEmulatedMaskMemRefHack(Instruction *I, ElementCount VF);
+ bool useEmulatedMaskMemRefHack(Instruction *I, ElementCount VF) const;
/// Return the costs for our two available strategies for lowering a
/// div/rem operation which requires speculating at least one lane.
@@ -1334,13 +1334,14 @@ class LoopVectorizationCostModel {
InstructionCost getMemoryInstructionCost(Instruction *I, ElementCount VF);
/// The cost computation for scalarized memory instruction.
- InstructionCost getMemInstScalarizationCost(Instruction *I, ElementCount VF);
+ InstructionCost getMemInstScalarizationCost(Instruction *I,
+ ElementCount VF) const;
/// The cost computation for interleaving group of memory instructions.
- InstructionCost getInterleaveGroupCost(Instruction *I, ElementCount VF);
+ InstructionCost getInterleaveGroupCost(Instruction *I, ElementCount VF) const;
/// The cost computation for Gather/Scatter instruction.
- InstructionCost getGatherScatterCost(Instruction *I, ElementCount VF);
+ InstructionCost getGatherScatterCost(Instruction *I, ElementCount VF) const;
/// The cost computation for widening instruction \p I with consecutive
/// memory access.
@@ -1351,7 +1352,7 @@ class LoopVectorizationCostModel {
/// Load: scalar load + broadcast.
/// Store: scalar store + (loop invariant value stored? 0 : extract of last
/// element)
- InstructionCost getUniformMemOpCost(Instruction *I, ElementCount VF);
+ InstructionCost getUniformMemOpCost(Instruction *I, ElementCount VF) const;
/// Estimate the overhead of scalarizing an instruction. This is a
/// convenience wrapper for the type-based getScalarizationOverhead API.
@@ -1499,15 +1500,6 @@ class LoopVectorizationCostModel {
/// unless necessary, e.g. when the loop isn't legal to vectorize or when
/// there is no predication.
std::function<BlockFrequencyInfo &()> GetBFI;
- /// The BlockFrequencyInfo returned from GetBFI.
- BlockFrequencyInfo *BFI = nullptr;
- /// Returns the BlockFrequencyInfo for the function if cached, otherwise
- /// fetches it via GetBFI. Avoids an indirect call to the std::function.
- BlockFrequencyInfo &getBFI() {
- if (!BFI)
- BFI = &GetBFI();
- return *BFI;
- }
const Function *TheFunction;
@@ -2480,7 +2472,7 @@ bool LoopVectorizationCostModel::isPredicatedInst(Instruction *I) const {
}
uint64_t LoopVectorizationCostModel::getPredBlockCostDivisor(
- TargetTransformInfo::TargetCostKind CostKind, const BasicBlock *BB) {
+ TargetTransformInfo::TargetCostKind CostKind, const BasicBlock *BB) const {
if (CostKind == TTI::TCK_CodeSize)
return 1;
// If the block wasn't originally predicated then return early to avoid
@@ -2489,8 +2481,8 @@ uint64_t LoopVectorizationCostModel::getPredBlockCostDivisor(
return 1;
uint64_t HeaderFreq =
- getBFI().getBlockFreq(TheLoop->getHeader()).getFrequency();
- uint64_t BBFreq = getBFI().getBlockFreq(BB).getFrequency();
+ GetBFI().getBlockFreq(TheLoop->getHeader()).getFrequency();
+ uint64_t BBFreq = GetBFI().getBlockFreq(BB).getFrequency();
assert(HeaderFreq >= BBFreq &&
"Header has smaller block freq than dominated BB?");
return std::round((double)HeaderFreq / BBFreq);
@@ -3906,8 +3898,8 @@ LoopVectorizationPlanner::selectInterleaveCount(VPlan &Plan, ElementCount VF,
return 1;
}
-bool LoopVectorizationCostModel::useEmulatedMaskMemRefHack(Instruction *I,
- ElementCount VF) {
+bool LoopVectorizationCostModel::useEmulatedMaskMemRefHack(
+ Instruction *I, ElementCount VF) const {
// TODO: Cost model for emulated masked load/store is completely
// broken. This hack guides the cost model to use an artificially
// high enough value to practically disable vectorization with such
@@ -4143,7 +4135,7 @@ static const SCEV *getAddressAccessSCEV(
InstructionCost
LoopVectorizationCostModel::getMemInstScalarizationCost(Instruction *I,
- ElementCount VF) {
+ ElementCount VF) const {
assert(VF.isVector() &&
"Scalarization cost of instruction implies vectorization.");
if (VF.isScalable())
@@ -4233,7 +4225,7 @@ InstructionCost LoopVectorizationCostModel::getConsecutiveMemOpCost(
InstructionCost
LoopVectorizationCostModel::getUniformMemOpCost(Instruction *I,
- ElementCount VF) {
+ ElementCount VF) const {
assert(isUniformMemOp(*I, VF));
Type *ValTy = getLoadStoreType(I);
@@ -4268,7 +4260,7 @@ LoopVectorizationCostModel::getUniformMemOpCost(Instruction *I,
InstructionCost
LoopVectorizationCostModel::getGatherScatterCost(Instruction *I,
- ElementCount VF) {
+ ElementCount VF) const {
Type *ValTy = getLoadStoreType(I);
auto *VectorTy = cast<VectorType>(toVectorTy(ValTy, VF));
const Align Alignment = getLoadStoreAlignment(I);
@@ -4291,7 +4283,7 @@ LoopVectorizationCostModel::getGatherScatterCost(Instruction *I,
InstructionCost
LoopVectorizationCostModel::getInterleaveGroupCost(Instruction *I,
- ElementCount VF) {
+ ElementCount VF) const {
const auto *Group = getInterleavedAccessGroup(I);
assert(Group && "Fail to get an interleaved access group.");
>From 239b9245d7c9ea6fb0f15c352bc6846d64ba41af Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Thu, 27 Aug 2026 10:47:33 +0100
Subject: [PATCH 2/2] [LV] Restore getBFI (NFC)
---
.../Transforms/Vectorize/LoopVectorize.cpp | 22 +++++++++++++------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index d326decde60d4..a5dff6d0267b0 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -1033,7 +1033,7 @@ class LoopVectorizationCostModel {
/// every iteration of the loop header.
inline uint64_t
getPredBlockCostDivisor(TargetTransformInfo::TargetCostKind CostKind,
- const BasicBlock *BB) const;
+ const BasicBlock *BB);
/// Returns true if an artificially high cost for emulated masked memrefs
/// should be used.
@@ -1334,8 +1334,7 @@ class LoopVectorizationCostModel {
InstructionCost getMemoryInstructionCost(Instruction *I, ElementCount VF);
/// The cost computation for scalarized memory instruction.
- InstructionCost getMemInstScalarizationCost(Instruction *I,
- ElementCount VF) const;
+ InstructionCost getMemInstScalarizationCost(Instruction *I, ElementCount VF);
/// The cost computation for interleaving group of memory instructions.
InstructionCost getInterleaveGroupCost(Instruction *I, ElementCount VF) const;
@@ -1500,6 +1499,15 @@ class LoopVectorizationCostModel {
/// unless necessary, e.g. when the loop isn't legal to vectorize or when
/// there is no predication.
std::function<BlockFrequencyInfo &()> GetBFI;
+ /// The BlockFrequencyInfo returned from GetBFI.
+ BlockFrequencyInfo *BFI = nullptr;
+ /// Returns the BlockFrequencyInfo for the function if cached, otherwise
+ /// fetches it via GetBFI. Avoids an indirect call to the std::function.
+ BlockFrequencyInfo &getBFI() {
+ if (!BFI)
+ BFI = &GetBFI();
+ return *BFI;
+ }
const Function *TheFunction;
@@ -2472,7 +2480,7 @@ bool LoopVectorizationCostModel::isPredicatedInst(Instruction *I) const {
}
uint64_t LoopVectorizationCostModel::getPredBlockCostDivisor(
- TargetTransformInfo::TargetCostKind CostKind, const BasicBlock *BB) const {
+ TargetTransformInfo::TargetCostKind CostKind, const BasicBlock *BB) {
if (CostKind == TTI::TCK_CodeSize)
return 1;
// If the block wasn't originally predicated then return early to avoid
@@ -2481,8 +2489,8 @@ uint64_t LoopVectorizationCostModel::getPredBlockCostDivisor(
return 1;
uint64_t HeaderFreq =
- GetBFI().getBlockFreq(TheLoop->getHeader()).getFrequency();
- uint64_t BBFreq = GetBFI().getBlockFreq(BB).getFrequency();
+ getBFI().getBlockFreq(TheLoop->getHeader()).getFrequency();
+ uint64_t BBFreq = getBFI().getBlockFreq(BB).getFrequency();
assert(HeaderFreq >= BBFreq &&
"Header has smaller block freq than dominated BB?");
return std::round((double)HeaderFreq / BBFreq);
@@ -4135,7 +4143,7 @@ static const SCEV *getAddressAccessSCEV(
InstructionCost
LoopVectorizationCostModel::getMemInstScalarizationCost(Instruction *I,
- ElementCount VF) const {
+ ElementCount VF) {
assert(VF.isVector() &&
"Scalarization cost of instruction implies vectorization.");
if (VF.isScalable())
More information about the llvm-commits
mailing list