Skip to content

Commit

Permalink
[SCEVExpander] Migrate costAndCollectOperands to use InstructionCost.
Browse files Browse the repository at this point in the history
This patch changes costAndCollectOperands to use InstructionCost for
accumulated cost values.

isHighCostExpansion will return true if the cost has exceeded the budget.

Reviewed By: CarolineConcatto, ctetreau

Differential Revision: https://reviews.llvm.org/D92238
  • Loading branch information
sdesmalen-arm committed Feb 16, 2021
1 parent 07cc771 commit 00fe10c
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 32 deletions.
21 changes: 12 additions & 9 deletions llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InstructionCost.h"

namespace llvm {
extern cl::opt<unsigned> SCEVCheapExpansionBudget;
Expand Down Expand Up @@ -237,15 +238,16 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
return true; // by always claiming to be high-cost.
SmallVector<SCEVOperand, 8> Worklist;
SmallPtrSet<const SCEV *, 8> Processed;
int BudgetRemaining = Budget * TargetTransformInfo::TCC_Basic;
InstructionCost Cost = 0;
unsigned ScaledBudget = Budget * TargetTransformInfo::TCC_Basic;
Worklist.emplace_back(-1, -1, Expr);
while (!Worklist.empty()) {
const SCEVOperand WorkItem = Worklist.pop_back_val();
if (isHighCostExpansionHelper(WorkItem, L, *At, BudgetRemaining,
*TTI, Processed, Worklist))
if (isHighCostExpansionHelper(WorkItem, L, *At, Cost, ScaledBudget, *TTI,
Processed, Worklist))
return true;
}
assert(BudgetRemaining >= 0 && "Should have returned from inner loop.");
assert(Cost <= ScaledBudget && "Should have returned from inner loop.");
return false;
}

Expand Down Expand Up @@ -399,11 +401,12 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
Value *expandCodeForImpl(const SCEV *SH, Type *Ty, Instruction *I, bool Root);

/// Recursive helper function for isHighCostExpansion.
bool isHighCostExpansionHelper(
const SCEVOperand &WorkItem, Loop *L, const Instruction &At,
int &BudgetRemaining, const TargetTransformInfo &TTI,
SmallPtrSetImpl<const SCEV *> &Processed,
SmallVectorImpl<SCEVOperand> &Worklist);
bool isHighCostExpansionHelper(const SCEVOperand &WorkItem, Loop *L,
const Instruction &At, InstructionCost &Cost,
unsigned Budget,
const TargetTransformInfo &TTI,
SmallPtrSetImpl<const SCEV *> &Processed,
SmallVectorImpl<SCEVOperand> &Worklist);

/// Insert the specified binary operator, doing a small amount of work to
/// avoid inserting an obviously redundant operation, and hoisting to an
Expand Down
44 changes: 21 additions & 23 deletions llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2179,13 +2179,13 @@ SCEVExpander::getRelatedExistingExpansion(const SCEV *S, const Instruction *At,
return None;
}

template<typename T> static int costAndCollectOperands(
template<typename T> static InstructionCost costAndCollectOperands(
const SCEVOperand &WorkItem, const TargetTransformInfo &TTI,
TargetTransformInfo::TargetCostKind CostKind,
SmallVectorImpl<SCEVOperand> &Worklist) {

const T *S = cast<T>(WorkItem.S);
int Cost = 0;
InstructionCost Cost = 0;
// Object to help map SCEV operands to expanded IR instructions.
struct OperationIndices {
OperationIndices(unsigned Opc, size_t min, size_t max) :
Expand All @@ -2200,22 +2200,23 @@ template<typename T> static int costAndCollectOperands(
// we know what the generated user(s) will be.
SmallVector<OperationIndices, 2> Operations;

auto CastCost = [&](unsigned Opcode) {
auto CastCost = [&](unsigned Opcode) -> InstructionCost {
Operations.emplace_back(Opcode, 0, 0);
return TTI.getCastInstrCost(Opcode, S->getType(),
S->getOperand(0)->getType(),
TTI::CastContextHint::None, CostKind);
};

auto ArithCost = [&](unsigned Opcode, unsigned NumRequired,
unsigned MinIdx = 0, unsigned MaxIdx = 1) {
unsigned MinIdx = 0,
unsigned MaxIdx = 1) -> InstructionCost {
Operations.emplace_back(Opcode, MinIdx, MaxIdx);
return NumRequired *
TTI.getArithmeticInstrCost(Opcode, S->getType(), CostKind);
};

auto CmpSelCost = [&](unsigned Opcode, unsigned NumRequired,
unsigned MinIdx, unsigned MaxIdx) {
auto CmpSelCost = [&](unsigned Opcode, unsigned NumRequired, unsigned MinIdx,
unsigned MaxIdx) -> InstructionCost {
Operations.emplace_back(Opcode, MinIdx, MaxIdx);
Type *OpType = S->getOperand(0)->getType();
return NumRequired * TTI.getCmpSelInstrCost(
Expand Down Expand Up @@ -2286,10 +2287,11 @@ template<typename T> static int costAndCollectOperands(

// Much like with normal add expr, the polynominal will require
// one less addition than the number of it's terms.
int AddCost = ArithCost(Instruction::Add, NumTerms - 1,
/*MinIdx*/1, /*MaxIdx*/1);
InstructionCost AddCost = ArithCost(Instruction::Add, NumTerms - 1,
/*MinIdx*/ 1, /*MaxIdx*/ 1);
// Here, *each* one of those will require a multiplication.
int MulCost = ArithCost(Instruction::Mul, NumNonZeroDegreeNonOneTerms);
InstructionCost MulCost =
ArithCost(Instruction::Mul, NumNonZeroDegreeNonOneTerms);
Cost = AddCost + MulCost;

// What is the degree of this polynominal?
Expand Down Expand Up @@ -2320,10 +2322,10 @@ template<typename T> static int costAndCollectOperands(

bool SCEVExpander::isHighCostExpansionHelper(
const SCEVOperand &WorkItem, Loop *L, const Instruction &At,
int &BudgetRemaining, const TargetTransformInfo &TTI,
InstructionCost &Cost, unsigned Budget, const TargetTransformInfo &TTI,
SmallPtrSetImpl<const SCEV *> &Processed,
SmallVectorImpl<SCEVOperand> &Worklist) {
if (BudgetRemaining < 0)
if (Cost > Budget)
return true; // Already run out of budget, give up.

const SCEV *S = WorkItem.S;
Expand Down Expand Up @@ -2353,17 +2355,16 @@ bool SCEVExpander::isHighCostExpansionHelper(
return 0;
const APInt &Imm = cast<SCEVConstant>(S)->getAPInt();
Type *Ty = S->getType();
BudgetRemaining -= TTI.getIntImmCostInst(
Cost += TTI.getIntImmCostInst(
WorkItem.ParentOpcode, WorkItem.OperandIdx, Imm, Ty, CostKind);
return BudgetRemaining < 0;
return Cost > Budget;
}
case scTruncate:
case scPtrToInt:
case scZeroExtend:
case scSignExtend: {
int Cost =
Cost +=
costAndCollectOperands<SCEVCastExpr>(WorkItem, TTI, CostKind, Worklist);
BudgetRemaining -= Cost;
return false; // Will answer upon next entry into this function.
}
case scUDivExpr: {
Expand All @@ -2379,10 +2380,8 @@ bool SCEVExpander::isHighCostExpansionHelper(
SE.getAddExpr(S, SE.getConstant(S->getType(), 1)), &At, L))
return false; // Consider it to be free.

int Cost =
Cost +=
costAndCollectOperands<SCEVUDivExpr>(WorkItem, TTI, CostKind, Worklist);
// Need to count the cost of this UDiv.
BudgetRemaining -= Cost;
return false; // Will answer upon next entry into this function.
}
case scAddExpr:
Expand All @@ -2395,17 +2394,16 @@ bool SCEVExpander::isHighCostExpansionHelper(
"Nary expr should have more than 1 operand.");
// The simple nary expr will require one less op (or pair of ops)
// than the number of it's terms.
int Cost =
Cost +=
costAndCollectOperands<SCEVNAryExpr>(WorkItem, TTI, CostKind, Worklist);
BudgetRemaining -= Cost;
return BudgetRemaining < 0;
return Cost > Budget;
}
case scAddRecExpr: {
assert(cast<SCEVAddRecExpr>(S)->getNumOperands() >= 2 &&
"Polynomial should be at least linear");
BudgetRemaining -= costAndCollectOperands<SCEVAddRecExpr>(
Cost += costAndCollectOperands<SCEVAddRecExpr>(
WorkItem, TTI, CostKind, Worklist);
return BudgetRemaining < 0;
return Cost > Budget;
}
}
llvm_unreachable("Unknown SCEV kind!");
Expand Down

0 comments on commit 00fe10c

Please sign in to comment.