diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h index cefce93f9e25c..f55f21c94a85a 100644 --- a/llvm/include/llvm/Analysis/TargetTransformInfo.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h @@ -740,6 +740,10 @@ class TargetTransformInfo { /// When successful, makes the primary IV dead. bool shouldFoldTerminatingConditionAfterLSR() const; + /// Return true if LSR should drop a found solution if it's calculated to be + /// less profitable than the baseline. + bool shouldDropLSRSolutionIfLessProfitable() const; + /// \returns true if LSR should not optimize a chain that includes \p I. bool isProfitableLSRChainElement(Instruction *I) const; @@ -1864,6 +1868,7 @@ class TargetTransformInfo::Concept { const TargetTransformInfo::LSRCost &C2) = 0; virtual bool isNumRegsMajorCostOfLSR() = 0; virtual bool shouldFoldTerminatingConditionAfterLSR() const = 0; + virtual bool shouldDropLSRSolutionIfLessProfitable() const = 0; virtual bool isProfitableLSRChainElement(Instruction *I) = 0; virtual bool canMacroFuseCmp() = 0; virtual bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE, @@ -2337,6 +2342,9 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept { bool shouldFoldTerminatingConditionAfterLSR() const override { return Impl.shouldFoldTerminatingConditionAfterLSR(); } + bool shouldDropLSRSolutionIfLessProfitable() const override { + return Impl.shouldDropLSRSolutionIfLessProfitable(); + } bool isProfitableLSRChainElement(Instruction *I) override { return Impl.isProfitableLSRChainElement(I); } diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h index 9a57331d281db..7828bdc1f1f43 100644 --- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -241,6 +241,8 @@ class TargetTransformInfoImplBase { bool shouldFoldTerminatingConditionAfterLSR() const { return false; } + bool shouldDropLSRSolutionIfLessProfitable() const { return false; } + bool isProfitableLSRChainElement(Instruction *I) const { return false; } bool canMacroFuseCmp() const { return false; } diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h index 2091432d4fe27..ef4e0fd29768f 100644 --- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -399,6 +399,10 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase { shouldFoldTerminatingConditionAfterLSR(); } + bool shouldDropLSRSolutionIfLessProfitable() const { + return TargetTransformInfoImplBase::shouldDropLSRSolutionIfLessProfitable(); + } + bool isProfitableLSRChainElement(Instruction *I) { return TargetTransformInfoImplBase::isProfitableLSRChainElement(I); } diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp index 82b6d7e7c4833..7e721cbc87f3f 100644 --- a/llvm/lib/Analysis/TargetTransformInfo.cpp +++ b/llvm/lib/Analysis/TargetTransformInfo.cpp @@ -427,6 +427,10 @@ bool TargetTransformInfo::shouldFoldTerminatingConditionAfterLSR() const { return TTIImpl->shouldFoldTerminatingConditionAfterLSR(); } +bool TargetTransformInfo::shouldDropLSRSolutionIfLessProfitable() const { + return TTIImpl->shouldDropLSRSolutionIfLessProfitable(); +} + bool TargetTransformInfo::isProfitableLSRChainElement(Instruction *I) const { return TTIImpl->isProfitableLSRChainElement(I); } diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 35a17d6060c94..73ed611e8de8c 100644 --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -193,8 +193,8 @@ static cl::opt AllowTerminatingConditionFoldingAfterLSR( "lsr-term-fold", cl::Hidden, cl::desc("Attempt to replace primary IV with other IV.")); -static cl::opt AllowDropSolutionIfLessProfitable( - "lsr-drop-solution", cl::Hidden, cl::init(false), +static cl::opt AllowDropSolutionIfLessProfitable( + "lsr-drop-solution", cl::Hidden, cl::desc("Attempt to drop solution if it is less profitable")); STATISTIC(NumTermFold, @@ -5250,8 +5250,20 @@ void LSRInstance::Solve(SmallVectorImpl &Solution) const { assert(Solution.size() == Uses.size() && "Malformed solution!"); + const bool EnableDropUnprofitableSolution = [&] { + switch (AllowDropSolutionIfLessProfitable) { + case cl::BOU_TRUE: + return true; + case cl::BOU_FALSE: + return false; + case cl::BOU_UNSET: + return TTI.shouldDropLSRSolutionIfLessProfitable(); + } + llvm_unreachable("Unhandled cl::boolOrDefault enum"); + }(); + if (BaselineCost.isLess(SolutionCost)) { - if (!AllowDropSolutionIfLessProfitable) + if (!EnableDropUnprofitableSolution) LLVM_DEBUG( dbgs() << "Baseline is more profitable than chosen solution, " "add option 'lsr-drop-solution' to drop LSR solution.\n");