17#include "llvm/IR/IntrinsicsWebAssembly.h"
23#define DEBUG_TYPE "wasmtti"
35 bool Vector = (ClassID == 1);
37 Result = std::max(Result, 16u);
63 Opcode, Ty,
CostKind, Op1Info, Op2Info);
67 case Instruction::LShr:
68 case Instruction::AShr:
69 case Instruction::Shl:
88 int ISD = TLI->InstructionOpcodeToISD(Opcode);
89 auto SrcTy = TLI->getValueType(
DL, Src);
90 auto DstTy = TLI->getValueType(
DL, Dst);
92 if (!SrcTy.isSimple() || !DstTy.isSimple()) {
96 if (!ST->hasSIMD128()) {
100 auto DstVT = DstTy.getSimpleVT();
101 auto SrcVT = SrcTy.getSimpleVT();
103 if (
I &&
I->hasOneUser()) {
105 int UserISD = TLI->InstructionOpcodeToISD(SingleUser->getOpcode());
111 if ((SrcVT == MVT::v8i8 && DstVT == MVT::v8i16) ||
112 (SrcVT == MVT::v4i16 && DstVT == MVT::v4i32) ||
113 (SrcVT == MVT::v2i32 && DstVT == MVT::v2i64)) {
118 if ((SrcVT == MVT::v4i8 && DstVT == MVT::v4i32) ||
119 (SrcVT == MVT::v2i16 && DstVT == MVT::v2i64)) {
203 if (
const auto *Entry =
215 Options.AllowOverlappingLoads =
true;
217 if (ST->hasSIMD128())
218 Options.LoadSizes.push_back(16);
220 Options.LoadSizes.append({8, 4, 2, 1});
221 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
236 EVT VT = TLI->getValueType(
DL, Ty,
true);
238 if (VT == MVT::Other)
243 if (!LT.first.isValid())
246 int ISD = TLI->InstructionOpcodeToISD(Opcode);
280 bool UseMaskForCond,
bool UseMaskForGaps)
const {
281 assert(Factor >= 2 &&
"Invalid interleave factor");
288 if (UseMaskForCond || UseMaskForGaps)
291 UseMaskForCond, UseMaskForGaps);
295 unsigned MinElts = VecTy->getElementCount().getKnownMinValue();
297 if (MinElts < 2 || MinElts % Factor != 0)
300 unsigned ElSize =
DL.getTypeSizeInBits(VecTy->getElementType());
302 if (ElSize != 8 && ElSize != 16 && ElSize != 32 && ElSize != 64)
307 VecTy->getElementCount().divideCoefficientBy(Factor));
311 unsigned VecSize =
DL.getTypeSizeInBits(SubVecTy);
313 unsigned NumAccesses =
314 std::max<unsigned>(1, (MinElts * ElSize +
MaxVecSize - 1) / VecSize);
350 EVT ETy = TLI->getValueType(
DL, SubVecTy);
351 if (
const auto *Entry =
353 return Entry->Cost + (NumAccesses * MemCost);
358 UseMaskForCond, UseMaskForGaps);
365 Opcode, Val,
CostKind, Index, Op0, Op1);
375 unsigned Opcode,
Type *InputTypeA,
Type *InputTypeB,
Type *AccumType,
380 if (!VF.
isFixed() || !ST->hasSIMD128())
386 if (Opcode != Instruction::Add)
391 if (AccumEVT != MVT::i32)
413 if (OpAExtend != OpBExtend)
416 if (*BinOp != Instruction::Mul)
419 if (InputTypeA != InputTypeB)
436 switch (
II->getIntrinsicID()) {
439 case Intrinsic::vector_reduce_fadd:
473 return getST()->hasTailCall();
480 if (!
I->getType()->isVectorTy() || !
I->isShift())
483 Value *V =
I->getOperand(1);
493 Ops.push_back(&
I->getOperandUse(1));
510 unsigned NumElts = VecTy->getNumElements();
515 bool AnyOutOfBounds =
false;
517 for (
unsigned I = 0;
I < NumElts; ++
I) {
548 if (Index >= NumElts) {
549 AnyOutOfBounds =
true;
553 Indexes[
I] = NumElts;
560 auto *V1 =
II.getArgOperand(0);
564 return Builder.CreateShuffleVector(V1, V2,
ArrayRef(Indexes, NumElts));
567std::optional<Instruction *>
572 case Intrinsic::wasm_swizzle:
573 case Intrinsic::wasm_relaxed_swizzle:
575 II, IC.
Builder, IID == Intrinsic::wasm_relaxed_swizzle)) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
Cost tables and simple lookup functions.
static const int MaxVecSize
This file provides the interface for the instcombine pass implementation.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static const unsigned MaxInterleaveFactor
Maximum vectorization interleave count.
static const Function * getCalledFunction(const Value *V)
uint64_t IntrinsicInst * II
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
std::pair< InstructionCost, MVT > getTypeLegalizationCost(Type *Ty) const
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
This is an important base class in LLVM.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
The core instruction combiner logic.
IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
static InstructionCost getInvalid(CostType Val=0)
A wrapper class for inspecting calls to intrinsic functions.
Represents a single loop in the control flow graph.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
The main scalar evolution driver.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *Ty, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond, bool UseMaskForGaps) const override
bool supportsTailCalls() const override
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override
std::optional< Instruction * > instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
bool isProfitableToSinkOperands(Instruction *I, SmallVectorImpl< Use * > &Ops) const override
InstructionCost getPartialReductionCost(unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType, ElementCount VF, TTI::PartialReductionExtendKind OpAExtend, TTI::PartialReductionExtendKind OpBExtend, std::optional< unsigned > BinOp, TTI::TargetCostKind CostKind) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1) const override
TTI::ReductionShuffle getPreferredExpandedReductionShuffle(const IntrinsicInst *II) const override
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) const override
TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
unsigned getNumberOfRegisters(unsigned ClassID) const override
constexpr ScalarTy getFixedValue() const
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ SIGN_EXTEND
Conversion operators.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
bool match(Val *V, const Pattern &P)
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
This is an optimization pass for GlobalISel generic memory operations.
const CostTblEntryT< CostType > * CostTableLookup(ArrayRef< CostTblEntryT< CostType > > Tbl, int ISD, MVT Ty)
Find in cost table.
TypeConversionCostTblEntryT< unsigned > TypeConversionCostTblEntry
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
CostTblEntryT< unsigned > CostTblEntry
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
const TypeConversionCostTblEntryT< CostType > * ConvertCostTableLookup(ArrayRef< TypeConversionCostTblEntryT< CostType > > Tbl, int ISD, MVT Dst, MVT Src)
Find in type conversion cost table.
This struct is a compact representation of a valid (non-zero power of two) alignment.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.