Skip to content

Commit d9474a8

Browse files
committed
Revert "[VPlan] Use BlockFrequencyInfo in getPredBlockCostDivisor (llvm#158690)"
This reverts commit e8219e5.
1 parent 817e57f commit d9474a8

File tree

11 files changed

+42
-463
lines changed

11 files changed

+42
-463
lines changed

llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ class LoopVectorizationLegality {
364364

365365
/// Return true if the block BB needs to be predicated in order for the loop
366366
/// to be vectorized.
367-
bool blockNeedsPredication(const BasicBlock *BB) const;
367+
bool blockNeedsPredication(BasicBlock *BB) const;
368368

369369
/// Check if this pointer is consecutive when vectorizing. This happens
370370
/// when the last index of the GEP is the induction variable, or that the

llvm/include/llvm/Transforms/Vectorize/LoopVectorize.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> {
145145
LoopInfo *LI;
146146
TargetTransformInfo *TTI;
147147
DominatorTree *DT;
148-
std::function<BlockFrequencyInfo &()> GetBFI;
148+
BlockFrequencyInfo *BFI;
149149
TargetLibraryInfo *TLI;
150150
DemandedBits *DB;
151151
AssumptionCache *AC;

llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,8 +1443,7 @@ bool LoopVectorizationLegality::isFixedOrderRecurrence(
14431443
return FixedOrderRecurrences.count(Phi);
14441444
}
14451445

1446-
bool LoopVectorizationLegality::blockNeedsPredication(
1447-
const BasicBlock *BB) const {
1446+
bool LoopVectorizationLegality::blockNeedsPredication(BasicBlock *BB) const {
14481447
// When vectorizing early exits, create predicates for the latch block only.
14491448
// The early exiting block must be a direct predecessor of the latch at the
14501449
// moment.

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 34 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@
146146
#include "llvm/Transforms/Vectorize/LoopVectorizationLegality.h"
147147
#include <algorithm>
148148
#include <cassert>
149-
#include <cmath>
150149
#include <cstdint>
151150
#include <functional>
152151
#include <iterator>
@@ -874,14 +873,12 @@ class LoopVectorizationCostModel {
874873
const TargetTransformInfo &TTI,
875874
const TargetLibraryInfo *TLI, DemandedBits *DB,
876875
AssumptionCache *AC,
877-
OptimizationRemarkEmitter *ORE,
878-
std::function<BlockFrequencyInfo &()> GetBFI,
879-
const Function *F, const LoopVectorizeHints *Hints,
876+
OptimizationRemarkEmitter *ORE, const Function *F,
877+
const LoopVectorizeHints *Hints,
880878
InterleavedAccessInfo &IAI, bool OptForSize)
881879
: ScalarEpilogueStatus(SEL), TheLoop(L), PSE(PSE), LI(LI), Legal(Legal),
882-
TTI(TTI), TLI(TLI), DB(DB), AC(AC), ORE(ORE), GetBFI(GetBFI),
883-
TheFunction(F), Hints(Hints), InterleaveInfo(IAI),
884-
OptForSize(OptForSize) {
880+
TTI(TTI), TLI(TLI), DB(DB), AC(AC), ORE(ORE), TheFunction(F),
881+
Hints(Hints), InterleaveInfo(IAI), OptForSize(OptForSize) {
885882
if (TTI.supportsScalableVectors() || ForceTargetSupportsScalableVectors)
886883
initializeVScaleForTuning();
887884
CostKind = F->hasMinSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput;
@@ -1222,7 +1219,7 @@ class LoopVectorizationCostModel {
12221219
/// for which our chosen predication strategy is scalarization (i.e. we
12231220
/// don't have an alternate strategy such as masking available).
12241221
/// \p VF is the vectorization factor that will be used to vectorize \p I.
1225-
bool isScalarWithPredication(Instruction *I, ElementCount VF);
1222+
bool isScalarWithPredication(Instruction *I, ElementCount VF) const;
12261223

12271224
/// Returns true if \p I is an instruction that needs to be predicated
12281225
/// at runtime. The result is independent of the predication mechanism.
@@ -1237,19 +1234,29 @@ class LoopVectorizationCostModel {
12371234
/// optimizing for code size it will just be 1 as code size costs don't depend
12381235
/// on execution probabilities.
12391236
///
1240-
/// Note that if a block wasn't originally predicated but was predicated due
1241-
/// to tail folding, the divisor will still be 1 because it will execute for
1242-
/// every iteration of the loop header.
1237+
/// TODO: We should use actual block probability here, if available.
1238+
/// Currently, we always assume predicated blocks have a 50% chance of
1239+
/// executing, apart from blocks that are only predicated due to tail folding.
12431240
inline unsigned
12441241
getPredBlockCostDivisor(TargetTransformInfo::TargetCostKind CostKind,
1245-
const BasicBlock *BB);
1242+
BasicBlock *BB) const {
1243+
// If a block wasn't originally predicated but was predicated due to
1244+
// e.g. tail folding, don't divide the cost. Tail folded loops may still be
1245+
// predicated in the final vector loop iteration, but for most loops that
1246+
// don't have low trip counts we can expect their probability to be close to
1247+
// zero.
1248+
if (!Legal->blockNeedsPredication(BB))
1249+
return 1;
1250+
return CostKind == TTI::TCK_CodeSize ? 1 : 2;
1251+
}
12461252

12471253
/// Return the costs for our two available strategies for lowering a
12481254
/// div/rem operation which requires speculating at least one lane.
12491255
/// First result is for scalarization (will be invalid for scalable
12501256
/// vectors); second is for the safe-divisor strategy.
12511257
std::pair<InstructionCost, InstructionCost>
1252-
getDivRemSpeculationCost(Instruction *I, ElementCount VF);
1258+
getDivRemSpeculationCost(Instruction *I,
1259+
ElementCount VF) const;
12531260

12541261
/// Returns true if \p I is a memory instruction with consecutive memory
12551262
/// access that can be widened.
@@ -1722,20 +1729,6 @@ class LoopVectorizationCostModel {
17221729
/// Interface to emit optimization remarks.
17231730
OptimizationRemarkEmitter *ORE;
17241731

1725-
/// A function to lazily fetch BlockFrequencyInfo. This avoids computing it
1726-
/// unless necessary, e.g. when the loop isn't legal to vectorize or when
1727-
/// there is no predication.
1728-
std::function<BlockFrequencyInfo &()> GetBFI;
1729-
/// The BlockFrequencyInfo returned from GetBFI.
1730-
BlockFrequencyInfo *BFI = nullptr;
1731-
/// Returns the BlockFrequencyInfo for the function if cached, otherwise
1732-
/// fetches it via GetBFI. Avoids an indirect call to the std::function.
1733-
BlockFrequencyInfo &getBFI() {
1734-
if (!BFI)
1735-
BFI = &GetBFI();
1736-
return *BFI;
1737-
}
1738-
17391732
const Function *TheFunction;
17401733

17411734
/// Loop Vectorize Hint.
@@ -2799,8 +2792,8 @@ void LoopVectorizationCostModel::collectLoopScalars(ElementCount VF) {
27992792
Scalars[VF].insert_range(Worklist);
28002793
}
28012794

2802-
bool LoopVectorizationCostModel::isScalarWithPredication(Instruction *I,
2803-
ElementCount VF) {
2795+
bool LoopVectorizationCostModel::isScalarWithPredication(
2796+
Instruction *I, ElementCount VF) const {
28042797
if (!isPredicatedInst(I))
28052798
return false;
28062799

@@ -2893,26 +2886,9 @@ bool LoopVectorizationCostModel::isPredicatedInst(Instruction *I) const {
28932886
}
28942887
}
28952888

2896-
unsigned LoopVectorizationCostModel::getPredBlockCostDivisor(
2897-
TargetTransformInfo::TargetCostKind CostKind, const BasicBlock *BB) {
2898-
if (CostKind == TTI::TCK_CodeSize)
2899-
return 1;
2900-
// If the block wasn't originally predicated then return early to avoid
2901-
// computing BlockFrequencyInfo unnecessarily.
2902-
if (!Legal->blockNeedsPredication(BB))
2903-
return 1;
2904-
2905-
uint64_t HeaderFreq =
2906-
getBFI().getBlockFreq(TheLoop->getHeader()).getFrequency();
2907-
uint64_t BBFreq = getBFI().getBlockFreq(BB).getFrequency();
2908-
assert(HeaderFreq >= BBFreq &&
2909-
"Header has smaller block freq than dominated BB?");
2910-
return std::round((double)HeaderFreq / BBFreq);
2911-
}
2912-
29132889
std::pair<InstructionCost, InstructionCost>
29142890
LoopVectorizationCostModel::getDivRemSpeculationCost(Instruction *I,
2915-
ElementCount VF) {
2891+
ElementCount VF) const {
29162892
assert(I->getOpcode() == Instruction::UDiv ||
29172893
I->getOpcode() == Instruction::SDiv ||
29182894
I->getOpcode() == Instruction::SRem ||
@@ -9206,9 +9182,8 @@ static bool processLoopInVPlanNativePath(
92069182
Loop *L, PredicatedScalarEvolution &PSE, LoopInfo *LI, DominatorTree *DT,
92079183
LoopVectorizationLegality *LVL, TargetTransformInfo *TTI,
92089184
TargetLibraryInfo *TLI, DemandedBits *DB, AssumptionCache *AC,
9209-
OptimizationRemarkEmitter *ORE,
9210-
std::function<BlockFrequencyInfo &()> GetBFI, bool OptForSize,
9211-
LoopVectorizeHints &Hints, LoopVectorizationRequirements &Requirements) {
9185+
OptimizationRemarkEmitter *ORE, bool OptForSize, LoopVectorizeHints &Hints,
9186+
LoopVectorizationRequirements &Requirements) {
92129187

92139188
if (isa<SCEVCouldNotCompute>(PSE.getBackedgeTakenCount())) {
92149189
LLVM_DEBUG(dbgs() << "LV: cannot compute the outer-loop trip count\n");
@@ -9221,8 +9196,8 @@ static bool processLoopInVPlanNativePath(
92219196
ScalarEpilogueLowering SEL =
92229197
getScalarEpilogueLowering(F, L, Hints, OptForSize, TTI, TLI, *LVL, &IAI);
92239198

9224-
LoopVectorizationCostModel CM(SEL, L, PSE, LI, LVL, *TTI, TLI, DB, AC, ORE,
9225-
GetBFI, F, &Hints, IAI, OptForSize);
9199+
LoopVectorizationCostModel CM(SEL, L, PSE, LI, LVL, *TTI, TLI, DB, AC, ORE, F,
9200+
&Hints, IAI, OptForSize);
92269201
// Use the planner for outer loop vectorization.
92279202
// TODO: CM is not used at this point inside the planner. Turn CM into an
92289203
// optional argument if we don't need it in the future.
@@ -9922,10 +9897,8 @@ bool LoopVectorizePass::processLoop(Loop *L) {
99229897

99239898
// Query this against the original loop and save it here because the profile
99249899
// of the original loop header may change as the transformation happens.
9925-
bool OptForSize = llvm::shouldOptimizeForSize(
9926-
L->getHeader(), PSI,
9927-
PSI && PSI->hasProfileSummary() ? &GetBFI() : nullptr,
9928-
PGSOQueryType::IRPass);
9900+
bool OptForSize = llvm::shouldOptimizeForSize(L->getHeader(), PSI, BFI,
9901+
PGSOQueryType::IRPass);
99299902

99309903
// Check if it is legal to vectorize the loop.
99319904
LoopVectorizationRequirements Requirements;
@@ -9959,8 +9932,7 @@ bool LoopVectorizePass::processLoop(Loop *L) {
99599932
// pipeline.
99609933
if (!L->isInnermost())
99619934
return processLoopInVPlanNativePath(L, PSE, LI, DT, &LVL, TTI, TLI, DB, AC,
9962-
ORE, GetBFI, OptForSize, Hints,
9963-
Requirements);
9935+
ORE, OptForSize, Hints, Requirements);
99649936

99659937
assert(L->isInnermost() && "Inner loop expected.");
99669938

@@ -10063,7 +10035,7 @@ bool LoopVectorizePass::processLoop(Loop *L) {
1006310035

1006410036
// Use the cost model.
1006510037
LoopVectorizationCostModel CM(SEL, L, PSE, LI, &LVL, *TTI, TLI, DB, AC, ORE,
10066-
GetBFI, F, &Hints, IAI, OptForSize);
10038+
F, &Hints, IAI, OptForSize);
1006710039
// Use the planner for vectorization.
1006810040
LoopVectorizationPlanner LVP(L, LI, DT, TLI, *TTI, &LVL, CM, IAI, PSE, Hints,
1006910041
ORE);
@@ -10381,9 +10353,9 @@ PreservedAnalyses LoopVectorizePass::run(Function &F,
1038110353

1038210354
auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
1038310355
PSI = MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
10384-
GetBFI = [&AM, &F]() -> BlockFrequencyInfo & {
10385-
return AM.getResult<BlockFrequencyAnalysis>(F);
10386-
};
10356+
BFI = nullptr;
10357+
if (PSI && PSI->hasProfileSummary())
10358+
BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
1038710359
LoopVectorizeResult Result = runImpl(F);
1038810360
if (!Result.MadeAnyChange)
1038910361
return PreservedAnalyses::all();

llvm/test/Transforms/LoopVectorize/AArch64/early_exit_costs.ll

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ define i64 @same_exit_block_pre_inc_use1_nosve() {
5757
; CHECK-NEXT: Cost of 48 for VF 16: EMIT vp<{{.*}}> = first-active-lane ir<%cmp3>
5858
; CHECK-NEXT: Cost of 0 for VF 16: EMIT vp<{{.*}}> = add
5959
; CHECK-NEXT: Cost of 0 for VF 16: vp<{{.*}}> = DERIVED-IV
60-
; CHECK: LV: Minimum required TC for runtime checks to be profitable:128
61-
; CHECK-NEXT: LV: Vectorization is not beneficial: expected trip count < minimum profitable VF (64 < 128)
60+
; CHECK: LV: Minimum required TC for runtime checks to be profitable:160
61+
; CHECK-NEXT: LV: Vectorization is not beneficial: expected trip count < minimum profitable VF (64 < 160)
6262
; CHECK-NEXT: LV: Too many memory checks needed.
6363
entry:
6464
%p1 = alloca [1024 x i8]
@@ -105,7 +105,7 @@ loop.header:
105105
%gep.src = getelementptr inbounds i64, ptr %src, i64 %iv
106106
%l = load i64, ptr %gep.src, align 1
107107
%t = trunc i64 %l to i1
108-
br i1 %t, label %exit.0, label %loop.latch, !prof !0
108+
br i1 %t, label %exit.0, label %loop.latch
109109

110110
loop.latch:
111111
%iv.next = add i64 %iv, 1
@@ -120,6 +120,4 @@ exit.1:
120120
ret i64 0
121121
}
122122

123-
!0 = !{!"branch_weights", i32 1, i32 1}
124-
125123
attributes #1 = { "target-features"="+sve" vscale_range(1,16) }

llvm/test/Transforms/LoopVectorize/AArch64/predicated-costs.ll

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -385,59 +385,6 @@ attributes #1 = { "target-cpu"="neoverse-v2" }
385385
!1 = !{!"llvm.loop.mustprogress"}
386386
!2 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
387387
!3 = !{!"llvm.loop.vectorize.enable", i1 true}
388-
389-
; BFI computes if is taken 20 times, and loop 32 times. Make sure we round the
390-
; divisor up to 2 so that we don't vectorize the loop unprofitably.
391-
define void @round_scalar_pred_divisor(ptr %dst, double %x) {
392-
; CHECK-LABEL: define void @round_scalar_pred_divisor(
393-
; CHECK-SAME: ptr [[DST:%.*]], double [[X:%.*]]) {
394-
; CHECK-NEXT: [[ENTRY:.*]]:
395-
; CHECK-NEXT: br label %[[LOOP:.*]]
396-
; CHECK: [[LOOP]]:
397-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ]
398-
; CHECK-NEXT: [[C:%.*]] = fcmp une double [[X]], 0.000000e+00
399-
; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[LATCH]]
400-
; CHECK: [[IF]]:
401-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[IV]] to i32
402-
; CHECK-NEXT: [[UITOFP:%.*]] = uitofp i32 [[TRUNC]] to double
403-
; CHECK-NEXT: [[SIN:%.*]] = tail call double @llvm.sin.f64(double [[UITOFP]])
404-
; CHECK-NEXT: [[FPTRUNC:%.*]] = fptrunc double [[SIN]] to float
405-
; CHECK-NEXT: br label %[[LATCH]]
406-
; CHECK: [[LATCH]]:
407-
; CHECK-NEXT: [[PHI:%.*]] = phi float [ [[FPTRUNC]], %[[IF]] ], [ 0.000000e+00, %[[LOOP]] ]
408-
; CHECK-NEXT: store float [[PHI]], ptr [[DST]], align 4
409-
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
410-
; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 1024
411-
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP]]
412-
; CHECK: [[EXIT]]:
413-
; CHECK-NEXT: ret void
414-
;
415-
entry:
416-
br label %loop
417-
418-
loop:
419-
%iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
420-
%c = fcmp une double %x, 0.0
421-
br i1 %c, label %if, label %latch
422-
423-
if:
424-
%trunc = trunc i64 %iv to i32
425-
%uitofp = uitofp i32 %trunc to double
426-
%sin = tail call double @llvm.sin(double %uitofp)
427-
%fptrunc = fptrunc double %sin to float
428-
br label %latch
429-
430-
latch:
431-
%phi = phi float [ %fptrunc, %if ], [ 0.0, %loop ]
432-
store float %phi, ptr %dst
433-
%iv.next = add i64 %iv, 1
434-
%ec = icmp eq i64 %iv, 1024
435-
br i1 %ec, label %exit, label %loop
436-
437-
exit:
438-
ret void
439-
}
440-
441388
;.
442389
; CHECK: [[META0]] = !{[[META1:![0-9]+]]}
443390
; CHECK: [[META1]] = distinct !{[[META1]], [[META2:![0-9]+]]}

llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ define i32 @diff_exit_block_needs_scev_check(i32 %end) {
386386
; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[END]] to i10
387387
; CHECK-NEXT: [[TMP1:%.*]] = zext i10 [[TMP0]] to i64
388388
; CHECK-NEXT: [[UMAX1:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP1]], i64 1)
389-
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[UMAX1]], 8
389+
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[UMAX1]], 12
390390
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
391391
; CHECK: vector.scevcheck:
392392
; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[END_CLAMPED]], i32 1)

0 commit comments

Comments
 (0)