Skip to content

Commit 27a62ec

Browse files
authored
[LSR] Split the -lsr-term-fold transformation into it's own pass (#104234)
This transformation doesn't actually use any of the internal state of LSR and recomputes all information from SCEV. Splitting it out makes it easier to test. Note that long term I would like to write a version of this transform which *is* integrated with LSR's solver, but if that happens, we'll just delete the extra pass. Integration wise, I switched from using TTI to using a pass configuration variable. This seems slightly more idiomatic, and means we don't run the extra logic on any target other than RISCV.
1 parent 69115cc commit 27a62ec

25 files changed

+438
-291
lines changed

llvm/include/llvm/Analysis/TargetTransformInfo.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -739,11 +739,6 @@ class TargetTransformInfo {
739739
/// cost should return false, otherwise return true.
740740
bool isNumRegsMajorCostOfLSR() const;
741741

742-
/// Return true if LSR should attempts to replace a use of an otherwise dead
743-
/// primary IV in the latch condition with another IV available in the loop.
744-
/// When successful, makes the primary IV dead.
745-
bool shouldFoldTerminatingConditionAfterLSR() const;
746-
747742
/// Return true if LSR should drop a found solution if it's calculated to be
748743
/// less profitable than the baseline.
749744
bool shouldDropLSRSolutionIfLessProfitable() const;
@@ -1888,7 +1883,6 @@ class TargetTransformInfo::Concept {
18881883
virtual bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
18891884
const TargetTransformInfo::LSRCost &C2) = 0;
18901885
virtual bool isNumRegsMajorCostOfLSR() = 0;
1891-
virtual bool shouldFoldTerminatingConditionAfterLSR() const = 0;
18921886
virtual bool shouldDropLSRSolutionIfLessProfitable() const = 0;
18931887
virtual bool isProfitableLSRChainElement(Instruction *I) = 0;
18941888
virtual bool canMacroFuseCmp() = 0;
@@ -2367,9 +2361,6 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
23672361
bool isNumRegsMajorCostOfLSR() override {
23682362
return Impl.isNumRegsMajorCostOfLSR();
23692363
}
2370-
bool shouldFoldTerminatingConditionAfterLSR() const override {
2371-
return Impl.shouldFoldTerminatingConditionAfterLSR();
2372-
}
23732364
bool shouldDropLSRSolutionIfLessProfitable() const override {
23742365
return Impl.shouldDropLSRSolutionIfLessProfitable();
23752366
}

llvm/include/llvm/Analysis/TargetTransformInfoImpl.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,6 @@ class TargetTransformInfoImplBase {
244244

245245
bool isNumRegsMajorCostOfLSR() const { return true; }
246246

247-
bool shouldFoldTerminatingConditionAfterLSR() const { return false; }
248-
249247
bool shouldDropLSRSolutionIfLessProfitable() const { return false; }
250248

251249
bool isProfitableLSRChainElement(Instruction *I) const { return false; }

llvm/include/llvm/CodeGen/BasicTTIImpl.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -394,11 +394,6 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
394394
return TargetTransformInfoImplBase::isNumRegsMajorCostOfLSR();
395395
}
396396

397-
bool shouldFoldTerminatingConditionAfterLSR() const {
398-
return TargetTransformInfoImplBase::
399-
shouldFoldTerminatingConditionAfterLSR();
400-
}
401-
402397
bool shouldDropLSRSolutionIfLessProfitable() const {
403398
return TargetTransformInfoImplBase::shouldDropLSRSolutionIfLessProfitable();
404399
}

llvm/include/llvm/CodeGen/TargetPassConfig.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ class TargetPassConfig : public ImmutablePass {
140140
/// callers.
141141
bool RequireCodeGenSCCOrder = false;
142142

143+
/// Enable LoopTermFold immediately after LSR
144+
bool EnableLoopTermFold = false;
145+
143146
/// Add the actual instruction selection passes. This does not include
144147
/// preparation passes on IR.
145148
bool addCoreISelPasses();

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ void initializeLoopInfoWrapperPassPass(PassRegistry &);
169169
void initializeLoopPassPass(PassRegistry &);
170170
void initializeLoopSimplifyPass(PassRegistry &);
171171
void initializeLoopStrengthReducePass(PassRegistry &);
172+
void initializeLoopTermFoldPass(PassRegistry &);
172173
void initializeLoopUnrollPass(PassRegistry &);
173174
void initializeLowerAtomicLegacyPassPass(PassRegistry &);
174175
void initializeLowerConstantIntrinsicsPass(PassRegistry &);

llvm/include/llvm/LinkAllPasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ struct ForcePassLinking {
9090
(void)llvm::createLoopExtractorPass();
9191
(void)llvm::createLoopSimplifyPass();
9292
(void)llvm::createLoopStrengthReducePass();
93+
(void)llvm::createLoopTermFoldPass();
9394
(void)llvm::createLoopUnrollPass();
9495
(void)llvm::createLowerGlobalDtorsLegacyPass();
9596
(void)llvm::createLowerInvokePass();

llvm/include/llvm/Passes/MachinePassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ FUNCTION_PASS("win-eh-prepare", WinEHPreparePass())
7979
#define LOOP_PASS(NAME, CREATE_PASS)
8080
#endif
8181
LOOP_PASS("loop-reduce", LoopStrengthReducePass())
82+
LOOP_PASS("loop-term-fold", LoopTermFoldPass())
8283
#undef LOOP_PASS
8384

8485
#ifndef MACHINE_MODULE_PASS

llvm/include/llvm/Transforms/Scalar.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ Pass *createLICMPass();
5151
//
5252
Pass *createLoopStrengthReducePass();
5353

54+
//===----------------------------------------------------------------------===//
55+
//
56+
// LoopTermFold - This pass attempts to eliminate the last use of an IV in
57+
// a loop terminator instruction by rewriting it in terms of another IV.
58+
// Expected to be run immediately after LSR.
59+
//
60+
Pass *createLoopTermFoldPass();
61+
5462
//===----------------------------------------------------------------------===//
5563
//
5664
// LoopUnroll - This pass is a simple loop unrolling pass.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===- LoopTermFold.h - Loop Term Fold Pass ---------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
#ifndef LLVM_TRANSFORMS_SCALAR_LOOPTERMFOLD_H
12+
#define LLVM_TRANSFORMS_SCALAR_LOOPTERMFOLD_H
13+
14+
#include "llvm/Analysis/LoopAnalysisManager.h"
15+
#include "llvm/IR/PassManager.h"
16+
17+
namespace llvm {
18+
19+
class Loop;
20+
class LPMUpdater;
21+
22+
class LoopTermFoldPass : public PassInfoMixin<LoopTermFoldPass> {
23+
public:
24+
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
25+
LoopStandardAnalysisResults &AR, LPMUpdater &U);
26+
};
27+
28+
} // end namespace llvm
29+
30+
#endif // LLVM_TRANSFORMS_SCALAR_LOOPTERMFOLD_H

llvm/lib/Analysis/TargetTransformInfo.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -427,10 +427,6 @@ bool TargetTransformInfo::isNumRegsMajorCostOfLSR() const {
427427
return TTIImpl->isNumRegsMajorCostOfLSR();
428428
}
429429

430-
bool TargetTransformInfo::shouldFoldTerminatingConditionAfterLSR() const {
431-
return TTIImpl->shouldFoldTerminatingConditionAfterLSR();
432-
}
433-
434430
bool TargetTransformInfo::shouldDropLSRSolutionIfLessProfitable() const {
435431
return TTIImpl->shouldDropLSRSolutionIfLessProfitable();
436432
}

llvm/lib/CodeGen/TargetPassConfig.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,8 @@ void TargetPassConfig::addIRPasses() {
828828
if (!DisableLSR) {
829829
addPass(createCanonicalizeFreezeInLoopsPass());
830830
addPass(createLoopStrengthReducePass());
831+
if (EnableLoopTermFold)
832+
addPass(createLoopTermFoldPass());
831833
if (PrintLSR)
832834
addPass(createPrintFunctionPass(dbgs(),
833835
"\n\n*** Code after LSR ***\n"));

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@
249249
#include "llvm/Transforms/Scalar/LoopSimplifyCFG.h"
250250
#include "llvm/Transforms/Scalar/LoopSink.h"
251251
#include "llvm/Transforms/Scalar/LoopStrengthReduce.h"
252+
#include "llvm/Transforms/Scalar/LoopTermFold.h"
252253
#include "llvm/Transforms/Scalar/LoopUnrollAndJamPass.h"
253254
#include "llvm/Transforms/Scalar/LoopUnrollPass.h"
254255
#include "llvm/Transforms/Scalar/LoopVersioningLICM.h"

llvm/lib/Passes/PassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@ LOOP_PASS("loop-idiom-vectorize", LoopIdiomVectorizePass())
646646
LOOP_PASS("loop-instsimplify", LoopInstSimplifyPass())
647647
LOOP_PASS("loop-predication", LoopPredicationPass())
648648
LOOP_PASS("loop-reduce", LoopStrengthReducePass())
649+
LOOP_PASS("loop-term-fold", LoopTermFoldPass())
649650
LOOP_PASS("loop-simplifycfg", LoopSimplifyCFGPass())
650651
LOOP_PASS("loop-unroll-full", LoopFullUnrollPass())
651652
LOOP_PASS("loop-versioning-licm", LoopVersioningLICMPass())

llvm/lib/Target/RISCV/RISCVTargetMachine.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ class RISCVPassConfig : public TargetPassConfig {
336336
if (TM.getOptLevel() != CodeGenOptLevel::None)
337337
substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
338338
setEnableSinkAndFold(EnableSinkFold);
339+
EnableLoopTermFold = true;
339340
}
340341

341342
RISCVTargetMachine &getRISCVTargetMachine() const {

llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,9 +394,6 @@ class RISCVTTIImpl : public BasicTTIImplBase<RISCVTTIImpl> {
394394
bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
395395
const TargetTransformInfo::LSRCost &C2);
396396

397-
bool shouldFoldTerminatingConditionAfterLSR() const {
398-
return true;
399-
}
400397
bool
401398
shouldConsiderAddressTypePromotion(const Instruction &I,
402399
bool &AllowPromotionWithoutCommonHeader);

llvm/lib/Transforms/Scalar/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ add_llvm_component_library(LLVMScalarOpts
4444
LoopRotation.cpp
4545
LoopSimplifyCFG.cpp
4646
LoopStrengthReduce.cpp
47+
LoopTermFold.cpp
4748
LoopUnrollPass.cpp
4849
LoopUnrollAndJamPass.cpp
4950
LoopVersioningLICM.cpp

0 commit comments

Comments
 (0)