34 #define CM_NAME "cost-model"
35 #define DEBUG_TYPE CM_NAME
39 cl::desc(
"Recognize reduction patterns."));
71 static const char cm_name[] =
"Cost Model Analysis";
76 return new CostModelAnalysis();
80 CostModelAnalysis::getAnalysisUsage(
AnalysisUsage &AU)
const {
85 CostModelAnalysis::runOnFunction(
Function &
F) {
87 auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>();
88 TTI = TTIWP ? &TTIWP->getTTI(F) :
nullptr;
94 for (
unsigned i = 0, MaskSize = Mask.
size();
i < MaskSize; ++
i)
95 if (Mask[
i] >= 0 && Mask[
i] != (
int)(MaskSize - 1 -
i))
103 for (
unsigned i = 0, NumVecElts = Mask.
size();
i < NumVecElts; ++
i) {
105 if ((
unsigned)Mask[
i] >= NumVecElts)
111 return !(Vec0 && Vec1);
115 for (
unsigned i = 0;
i < Mask.
size(); ++
i)
122 bool isAlternate =
true;
123 unsigned MaskSize = Mask.
size();
126 for (
unsigned i = 0;
i < MaskSize && isAlternate; ++
i) {
129 isAlternate = Mask[
i] == (int)((
i & 1) ? MaskSize +
i :
i);
137 for (
unsigned i = 0;
i < MaskSize && isAlternate; ++
i) {
140 isAlternate = Mask[
i] == (int)((
i & 1) ?
i : MaskSize +
i);
151 if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) {
160 if (Splat && (isa<Argument>(Splat) || isa<GlobalValue>(Splat)))
170 if (!SI && Level == 0 && IsLeft)
179 for (
unsigned i = 0, e = (1 << Level), val = !IsLeft;
i != e; ++
i, val += 2)
183 return Mask == ActualMask;
187 unsigned Level,
unsigned NumLevels) {
194 if (BinOp ==
nullptr)
211 if (!Level && !RS && !LS)
217 Value *NextLevelOp =
nullptr;
218 if (NextLevelOpR && NextLevelOpL) {
220 if (NextLevelOpL != NextLevelOpR)
223 NextLevelOp = NextLevelOpL;
224 }
else if (Level == 0 && (NextLevelOpR || NextLevelOpL)) {
231 if (NextLevelOpL && NextLevelOpL != R)
233 else if (NextLevelOpR && NextLevelOpR != L)
236 NextLevelOp = NextLevelOpL ? R :
L;
243 if (Level + 1 != NumLevels) {
244 if (!(NextLevelBinOp = dyn_cast<BinaryOperator>(NextLevelOp)))
246 else if (NextLevelBinOp->
getOpcode() != Opcode)
260 if (++Level == NumLevels)
268 unsigned &Opcode,
Type *&Ty) {
316 static std::pair<Value *, ShuffleVectorInst *>
323 if ((S = dyn_cast<ShuffleVectorInst>(L)))
324 return std::make_pair(R, S);
327 return std::make_pair(L, S);
331 unsigned &Opcode,
Type *&Ty) {
346 unsigned RdxOpcode = RdxStart->
getOpcode();
364 unsigned MaskStart = 1;
365 Value *RdxOp = RdxStart;
367 unsigned NumVecElemsRemain = NumVecElems;
368 while (NumVecElemsRemain - 1) {
371 if (!(BinOp = dyn_cast<BinaryOperator>(RdxOp)))
381 if (Shuffle ==
nullptr)
387 for (
unsigned j = 0; j != MaskStart; ++j)
388 ShuffleMask[j] = MaskStart + j;
390 std::fill(&ShuffleMask[MaskStart], ShuffleMask.
end(), -1);
393 if (ShuffleMask != Mask)
397 NumVecElemsRemain /= 2;
406 unsigned CostModelAnalysis::getInstructionCost(
const Instruction *
I)
const {
411 case Instruction::GetElementPtr:
412 return TTI->getUserCost(I);
415 case Instruction::PHI:
416 case Instruction::Br: {
417 return TTI->getCFInstrCost(I->
getOpcode());
420 case Instruction::FAdd:
421 case Instruction::Sub:
422 case Instruction::FSub:
423 case Instruction::Mul:
424 case Instruction::FMul:
425 case Instruction::UDiv:
426 case Instruction::SDiv:
427 case Instruction::FDiv:
428 case Instruction::URem:
429 case Instruction::SRem:
430 case Instruction::FRem:
431 case Instruction::Shl:
432 case Instruction::LShr:
433 case Instruction::AShr:
452 case Instruction::ICmp:
453 case Instruction::FCmp: {
455 return TTI->getCmpSelInstrCost(I->
getOpcode(), ValTy);
460 return TTI->getMemoryOpCost(I->
getOpcode(), ValTy,
470 case Instruction::ZExt:
471 case Instruction::SExt:
472 case Instruction::FPToUI:
473 case Instruction::FPToSI:
474 case Instruction::FPExt:
475 case Instruction::PtrToInt:
476 case Instruction::IntToPtr:
477 case Instruction::SIToFP:
478 case Instruction::UIToFP:
479 case Instruction::Trunc:
480 case Instruction::FPTrunc:
481 case Instruction::BitCast:
482 case Instruction::AddrSpaceCast: {
486 case Instruction::ExtractElement: {
495 unsigned ReduxOpCode;
499 return TTI->getReductionCost(ReduxOpCode, ReduxType,
false);
501 return TTI->getReductionCost(ReduxOpCode, ReduxType,
true);
503 return TTI->getVectorInstrCost(I->
getOpcode(),
506 case Instruction::InsertElement: {
512 return TTI->getVectorInstrCost(I->
getOpcode(),
515 case Instruction::ShuffleVector: {
521 if (NumVecElems == Mask.
size()) {
527 VecTypOp0, 0,
nullptr);
531 VecTypOp0, 0,
nullptr);
535 VecTypOp0, 0,
nullptr);
538 VecTypOp0, 0,
nullptr);
546 for (
unsigned J = 0, JE = II->getNumArgOperands(); J != JE; ++J)
550 if (
auto *FPMO = dyn_cast<FPMathOperator>(II))
551 FMF = FPMO->getFastMathFlags();
553 return TTI->getIntrinsicInstrCost(II->getIntrinsicID(), II->getType(),
569 unsigned Cost = getInstructionCost(&Inst);
570 if (Cost != (
unsigned)-1)
571 OS <<
"Cost Model: Found an estimated cost of " << Cost;
573 OS <<
"Cost Model: Unknown cost";
575 OS <<
" for instruction: " << Inst <<
"\n";
Value * getValueOperand()
void push_back(const T &Elt)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A Module instance is used to store all the information related to an LLVM module. ...
void initializeCostModelAnalysisPass(PassRegistry &)
const Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
This instruction constructs a fixed permutation of two input vectors.
An instruction for reading from memory.
static TargetTransformInfo::OperandValueKind getOperandInfo(Value *V)
static const char cm_name[]
This class represents the LLVM 'select' instruction.
static bool matchPairwiseReduction(const ExtractElementInst *ReduxRoot, unsigned &Opcode, Type *&Ty)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
VectorType * getType() const
Overload to return most specific vector type.
static bool isZeroEltBroadcastVectorMask(ArrayRef< int > Mask)
Function Alias Analysis false
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
An instruction for storing to memory.
size_t size() const
size - Get the array size.
initializer< Ty > init(const Ty &Val)
This instruction inserts a single (scalar) element into a VectorType value.
unsigned getAlignment() const
Return the alignment of the access that is being performed.
constexpr bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
static bool isReverseVectorMask(ArrayRef< int > Mask)
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
bool isVectorTy() const
True if this is an instance of VectorType.
const Value * getCondition() const
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
APInt Xor(const APInt &LHS, const APInt &RHS)
Bitwise XOR function for APInt.
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
static cl::opt< bool > EnableReduxCost("costmodel-reduxcost", cl::init(false), cl::Hidden, cl::desc("Recognize reduction patterns."))
BinaryOps getOpcode() const
static std::pair< Value *, ShuffleVectorInst * > getShuffleAndOtherOprd(BinaryOperator *B)
This is the shared class of boolean and integer constants.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
static bool isSingleSourceVectorMask(ArrayRef< int > Mask)
static bool matchPairwiseReductionAtLevel(const BinaryOperator *BinOp, unsigned Level, unsigned NumLevels)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
unsigned Log2_32(uint32_t Value)
Log2_32 - This function returns the floor log base 2 of the specified value, -1 if the value is zero...
static bool isAlternateVectorMask(ArrayRef< int > Mask)
void setPreservesAll()
Set by analyses that do not transform their input at all.
unsigned getVectorNumElements() const
APInt And(const APInt &LHS, const APInt &RHS)
Bitwise AND function for APInt.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
unsigned getAlignment() const
Return the alignment of the access that is being performed.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
iterator_range< value_op_iterator > operand_values()
static bool matchPairwiseShuffleMask(ShuffleVectorInst *SI, bool IsLeft, unsigned Level)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
VectorType * getType() const
Overload to return most specific vector type.
FunctionPass * createCostModelAnalysisPass()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
This class implements an extremely fast bulk output stream that can only output to a stream...
static bool matchVectorSplittingReduction(const ExtractElementInst *ReduxRoot, unsigned &Opcode, Type *&Ty)
Convenience struct for specifying and reasoning about fast-math flags.
static void getShuffleMask(Constant *Mask, SmallVectorImpl< int > &Result)
Convert the input shuffle mask operand to a vector of integers.
A wrapper class for inspecting calls to intrinsic functions.