forked from OSchip/llvm-project
[NFC][SCEV] Piping to pass new SCEVCheapExpansionBudget option into SCEVExpander::isHighCostExpansionHelper()
Summary: In future patches`SCEVExpander::isHighCostExpansionHelper()` will respect the budget allocated by performing TTI cost modelling. This is a fully NFC patch to make things reviewable. Reviewers: reames, mkazantsev, wmi, sanjoy Reviewed By: mkazantsev Subscribers: hiraditya, zzheng, javed.absar, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D73705
This commit is contained in:
parent
0789f28048
commit
b99c91a087
|
@ -19,11 +19,13 @@
|
||||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||||
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
|
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
|
||||||
#include "llvm/Analysis/TargetFolder.h"
|
#include "llvm/Analysis/TargetFolder.h"
|
||||||
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||||
#include "llvm/IR/IRBuilder.h"
|
#include "llvm/IR/IRBuilder.h"
|
||||||
#include "llvm/IR/ValueHandle.h"
|
#include "llvm/IR/ValueHandle.h"
|
||||||
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class TargetTransformInfo;
|
extern cl::opt<unsigned> SCEVCheapExpansionBudget;
|
||||||
|
|
||||||
/// Return true if the given expression is safe to expand in the sense that
|
/// Return true if the given expression is safe to expand in the sense that
|
||||||
/// all materialized values are safe to speculate anywhere their operands are
|
/// all materialized values are safe to speculate anywhere their operands are
|
||||||
|
@ -177,11 +179,13 @@ namespace llvm {
|
||||||
/// At is an optional parameter which specifies point in code where user is
|
/// At is an optional parameter which specifies point in code where user is
|
||||||
/// going to expand this expression. Sometimes this knowledge can lead to a
|
/// going to expand this expression. Sometimes this knowledge can lead to a
|
||||||
/// more accurate cost estimation.
|
/// more accurate cost estimation.
|
||||||
bool isHighCostExpansion(const SCEV *Expr, Loop *L,
|
bool isHighCostExpansion(const SCEV *Expr, Loop *L, unsigned Budget,
|
||||||
const TargetTransformInfo *TTI,
|
const TargetTransformInfo *TTI,
|
||||||
const Instruction *At = nullptr) {
|
const Instruction *At = nullptr) {
|
||||||
SmallPtrSet<const SCEV *, 8> Processed;
|
SmallPtrSet<const SCEV *, 8> Processed;
|
||||||
return isHighCostExpansionHelper(Expr, L, At, TTI, Processed);
|
int BudgetRemaining = Budget * TargetTransformInfo::TCC_Basic;
|
||||||
|
return isHighCostExpansionHelper(Expr, L, At, BudgetRemaining, TTI,
|
||||||
|
Processed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This method returns the canonical induction variable of the specified
|
/// This method returns the canonical induction variable of the specified
|
||||||
|
@ -324,7 +328,7 @@ namespace llvm {
|
||||||
|
|
||||||
/// Recursive helper function for isHighCostExpansion.
|
/// Recursive helper function for isHighCostExpansion.
|
||||||
bool isHighCostExpansionHelper(const SCEV *S, Loop *L,
|
bool isHighCostExpansionHelper(const SCEV *S, Loop *L,
|
||||||
const Instruction *At,
|
const Instruction *At, int &BudgetRemaining,
|
||||||
const TargetTransformInfo *TTI,
|
const TargetTransformInfo *TTI,
|
||||||
SmallPtrSetImpl<const SCEV *> &Processed);
|
SmallPtrSetImpl<const SCEV *> &Processed);
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,17 @@
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/IR/PatternMatch.h"
|
#include "llvm/IR/PatternMatch.h"
|
||||||
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
cl::opt<unsigned> llvm::SCEVCheapExpansionBudget(
|
||||||
|
"scev-cheap-expansion-budget", cl::Hidden, cl::init(4),
|
||||||
|
cl::desc("When performing SCEV expansion only if it is cheap to do, this "
|
||||||
|
"controls the budget that is considered cheap (default = 4)"));
|
||||||
|
|
||||||
using namespace PatternMatch;
|
using namespace PatternMatch;
|
||||||
|
|
||||||
/// ReuseOrCreateCast - Arrange for there to be a cast of V to Ty at IP,
|
/// ReuseOrCreateCast - Arrange for there to be a cast of V to Ty at IP,
|
||||||
|
@ -2129,7 +2136,7 @@ SCEVExpander::getRelatedExistingExpansion(const SCEV *S, const Instruction *At,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SCEVExpander::isHighCostExpansionHelper(
|
bool SCEVExpander::isHighCostExpansionHelper(
|
||||||
const SCEV *S, Loop *L, const Instruction *At,
|
const SCEV *S, Loop *L, const Instruction *At, int &BudgetRemaining,
|
||||||
const TargetTransformInfo *TTI, SmallPtrSetImpl<const SCEV *> &Processed) {
|
const TargetTransformInfo *TTI, SmallPtrSetImpl<const SCEV *> &Processed) {
|
||||||
// If we can find an existing value for this scev available at the point "At"
|
// If we can find an existing value for this scev available at the point "At"
|
||||||
// then consider the expression cheap.
|
// then consider the expression cheap.
|
||||||
|
@ -2143,13 +2150,13 @@ bool SCEVExpander::isHighCostExpansionHelper(
|
||||||
return false;
|
return false;
|
||||||
case scTruncate:
|
case scTruncate:
|
||||||
return isHighCostExpansionHelper(cast<SCEVTruncateExpr>(S)->getOperand(), L,
|
return isHighCostExpansionHelper(cast<SCEVTruncateExpr>(S)->getOperand(), L,
|
||||||
At, TTI, Processed);
|
At, BudgetRemaining, TTI, Processed);
|
||||||
case scZeroExtend:
|
case scZeroExtend:
|
||||||
return isHighCostExpansionHelper(cast<SCEVZeroExtendExpr>(S)->getOperand(),
|
return isHighCostExpansionHelper(cast<SCEVZeroExtendExpr>(S)->getOperand(),
|
||||||
L, At, TTI, Processed);
|
L, At, BudgetRemaining, TTI, Processed);
|
||||||
case scSignExtend:
|
case scSignExtend:
|
||||||
return isHighCostExpansionHelper(cast<SCEVSignExtendExpr>(S)->getOperand(),
|
return isHighCostExpansionHelper(cast<SCEVSignExtendExpr>(S)->getOperand(),
|
||||||
L, At, TTI, Processed);
|
L, At, BudgetRemaining, TTI, Processed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Processed.insert(S).second)
|
if (!Processed.insert(S).second)
|
||||||
|
@ -2162,8 +2169,8 @@ bool SCEVExpander::isHighCostExpansionHelper(
|
||||||
// lowered into a right shift.
|
// lowered into a right shift.
|
||||||
if (auto *SC = dyn_cast<SCEVConstant>(UDivExpr->getRHS()))
|
if (auto *SC = dyn_cast<SCEVConstant>(UDivExpr->getRHS()))
|
||||||
if (SC->getAPInt().isPowerOf2()) {
|
if (SC->getAPInt().isPowerOf2()) {
|
||||||
if (isHighCostExpansionHelper(UDivExpr->getLHS(), L, At, TTI,
|
if (isHighCostExpansionHelper(UDivExpr->getLHS(), L, At,
|
||||||
Processed))
|
BudgetRemaining, TTI, Processed))
|
||||||
return true;
|
return true;
|
||||||
const DataLayout &DL =
|
const DataLayout &DL =
|
||||||
L->getHeader()->getParent()->getParent()->getDataLayout();
|
L->getHeader()->getParent()->getParent()->getDataLayout();
|
||||||
|
@ -2200,7 +2207,7 @@ bool SCEVExpander::isHighCostExpansionHelper(
|
||||||
// they are not too expensive rematerialize.
|
// they are not too expensive rematerialize.
|
||||||
if (const SCEVNAryExpr *NAry = dyn_cast<SCEVNAryExpr>(S)) {
|
if (const SCEVNAryExpr *NAry = dyn_cast<SCEVNAryExpr>(S)) {
|
||||||
for (auto *Op : NAry->operands())
|
for (auto *Op : NAry->operands())
|
||||||
if (isHighCostExpansionHelper(Op, L, At, TTI, Processed))
|
if (isHighCostExpansionHelper(Op, L, At, BudgetRemaining, TTI, Processed))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2759,7 +2759,8 @@ bool IndVarSimplify::run(Loop *L) {
|
||||||
|
|
||||||
// Avoid high cost expansions. Note: This heuristic is questionable in
|
// Avoid high cost expansions. Note: This heuristic is questionable in
|
||||||
// that our definition of "high cost" is not exactly principled.
|
// that our definition of "high cost" is not exactly principled.
|
||||||
if (Rewriter.isHighCostExpansion(ExitCount, L, TTI))
|
if (Rewriter.isHighCostExpansion(ExitCount, L, SCEVCheapExpansionBudget,
|
||||||
|
TTI))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check preconditions for proper SCEVExpander operation. SCEV does not
|
// Check preconditions for proper SCEVExpander operation. SCEV does not
|
||||||
|
|
|
@ -635,7 +635,8 @@ bool llvm::UnrollRuntimeLoopRemainder(
|
||||||
const DataLayout &DL = Header->getModule()->getDataLayout();
|
const DataLayout &DL = Header->getModule()->getDataLayout();
|
||||||
SCEVExpander Expander(*SE, DL, "loop-unroll");
|
SCEVExpander Expander(*SE, DL, "loop-unroll");
|
||||||
if (!AllowExpensiveTripCount &&
|
if (!AllowExpensiveTripCount &&
|
||||||
Expander.isHighCostExpansion(TripCountSC, L, TTI, PreHeaderBR)) {
|
Expander.isHighCostExpansion(TripCountSC, L, SCEVCheapExpansionBudget,
|
||||||
|
TTI, PreHeaderBR)) {
|
||||||
LLVM_DEBUG(dbgs() << "High cost for expanding trip count scev!\n");
|
LLVM_DEBUG(dbgs() << "High cost for expanding trip count scev!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1361,7 +1361,8 @@ int llvm::rewriteLoopExitValues(Loop *L, LoopInfo *LI, TargetLibraryInfo *TLI,
|
||||||
hasHardUserWithinLoop(L, Inst))
|
hasHardUserWithinLoop(L, Inst))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool HighCost = Rewriter.isHighCostExpansion(ExitValue, L, TTI, Inst);
|
bool HighCost = Rewriter.isHighCostExpansion(
|
||||||
|
ExitValue, L, SCEVCheapExpansionBudget, TTI, Inst);
|
||||||
Value *ExitVal = Rewriter.expandCodeFor(ExitValue, PN->getType(), Inst);
|
Value *ExitVal = Rewriter.expandCodeFor(ExitValue, PN->getType(), Inst);
|
||||||
|
|
||||||
LLVM_DEBUG(dbgs() << "rewriteLoopExitValues: AfterLoopVal = "
|
LLVM_DEBUG(dbgs() << "rewriteLoopExitValues: AfterLoopVal = "
|
||||||
|
|
|
@ -669,7 +669,7 @@ bool SimplifyIndvar::replaceIVUserWithLoopInvariant(Instruction *I) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Do not generate something ridiculous even if S is loop invariant.
|
// Do not generate something ridiculous even if S is loop invariant.
|
||||||
if (Rewriter.isHighCostExpansion(S, L, TTI, I))
|
if (Rewriter.isHighCostExpansion(S, L, SCEVCheapExpansionBudget, TTI, I))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto *IP = GetLoopInvariantInsertPosition(L, I);
|
auto *IP = GetLoopInvariantInsertPosition(L, I);
|
||||||
|
|
Loading…
Reference in New Issue