/// \brief Information about a load/store intrinsic defined by the target.
struct MemIntrinsicInfo {
MemIntrinsicInfo()
- : ReadMem(false), WriteMem(false), Vol(false), MatchingId(0),
+ : ReadMem(false), WriteMem(false), IsSimple(false), MatchingId(0),
NumMemRefs(0), PtrVal(nullptr) {}
bool ReadMem;
bool WriteMem;
- bool Vol;
+ /// True only if this memory operation is non-volatile, non-atomic, and
+ /// unordered. (See LoadInst/StoreInst for details on each)
+ bool IsSimple;
// Same Id is set by the target for corresponding load/store intrinsics.
unsigned short MatchingId;
int NumMemRefs;
///
/// The TTI implementation will reflect the information in the DataLayout
/// provided if non-null.
- explicit TargetTransformInfo(const DataLayout *DL);
+ explicit TargetTransformInfo(const DataLayout &DL);
// Provide move semantics.
TargetTransformInfo(TargetTransformInfo &&Arg);
///
/// Many APIs in this interface return a cost. This enum defines the
/// fundamental values that should be used to interpret (and produce) those
- /// costs. The costs are returned as an unsigned rather than a member of this
+ /// costs. The costs are returned as an int rather than a member of this
/// enumeration because it is expected that the cost of one IR instruction
/// may have a multiplicative factor to it or otherwise won't fit directly
/// into the enum. Moreover, it is common to sum or average costs which works
/// better as simple integral values. Thus this enum only provides constants.
+ /// Also note that the returned costs are signed integers to make it natural
+ /// to add, subtract, and test with zero (a common boundary condition). It is
+ /// not expected that 2^32 is a realistic cost to be modeling at any point.
///
/// Note that these costs should usually reflect the intersection of code-size
/// cost and execution cost. A free instruction is typically one that folds
///
/// The returned cost is defined in terms of \c TargetCostConstants, see its
/// comments for a detailed explanation of the cost values.
- unsigned getOperationCost(unsigned Opcode, Type *Ty,
- Type *OpTy = nullptr) const;
+ int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy = nullptr) const;
/// \brief Estimate the cost of a GEP operation when lowered.
///
/// The contract for this function is the same as \c getOperationCost except
/// that it supports an interface that provides extra information specific to
/// the GEP operation.
- unsigned getGEPCost(const Value *Ptr, ArrayRef<const Value *> Operands) const;
+ int getGEPCost(Type *PointeeType, const Value *Ptr,
+ ArrayRef<const Value *> Operands) const;
/// \brief Estimate the cost of a function call when lowered.
///
/// This is the most basic query for estimating call cost: it only knows the
/// function type and (potentially) the number of arguments at the call site.
/// The latter is only interesting for varargs function types.
- unsigned getCallCost(FunctionType *FTy, int NumArgs = -1) const;
+ int getCallCost(FunctionType *FTy, int NumArgs = -1) const;
/// \brief Estimate the cost of calling a specific function when lowered.
///
/// This overload adds the ability to reason about the particular function
/// being called in the event it is a library call with special lowering.
- unsigned getCallCost(const Function *F, int NumArgs = -1) const;
+ int getCallCost(const Function *F, int NumArgs = -1) const;
/// \brief Estimate the cost of calling a specific function when lowered.
///
/// This overload allows specifying a set of candidate argument values.
- unsigned getCallCost(const Function *F,
- ArrayRef<const Value *> Arguments) const;
+ int getCallCost(const Function *F, ArrayRef<const Value *> Arguments) const;
/// \brief Estimate the cost of an intrinsic when lowered.
///
/// Mirrors the \c getCallCost method but uses an intrinsic identifier.
- unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys) const;
+ int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
+ ArrayRef<Type *> ParamTys) const;
/// \brief Estimate the cost of an intrinsic when lowered.
///
/// Mirrors the \c getCallCost method but uses an intrinsic identifier.
- unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments) const;
+ int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
+ ArrayRef<const Value *> Arguments) const;
/// \brief Estimate the cost of a given IR user when lowered.
///
///
/// The returned cost is defined in terms of \c TargetCostConstants, see its
/// comments for a detailed explanation of the cost values.
- unsigned getUserCost(const User *U) const;
+ int getUserCost(const User *U) const;
- /// \brief hasBranchDivergence - Return true if branch divergence exists.
+ /// \brief Return true if branch divergence exists.
+ ///
/// Branch divergence has a significantly negative impact on GPU performance
/// when threads in the same wavefront take different paths due to conditional
/// branches.
bool hasBranchDivergence() const;
+ /// \brief Returns whether V is a source of divergence.
+ ///
+ /// This function provides the target-dependent information for
+ /// the target-independent DivergenceAnalysis. DivergenceAnalysis first
+ /// builds the dependency graph, and then runs the reachability algorithm
+ /// starting with the sources of divergence.
+ bool isSourceOfDivergence(const Value *V) const;
+
/// \brief Test whether calls to a function lower to actual program function
/// calls.
///
/// Parameters that control the generic loop unrolling transformation.
struct UnrollingPreferences {
- /// The cost threshold for the unrolled loop, compared to
- /// CodeMetrics.NumInsts aggregated over all basic blocks in the loop body.
- /// The unrolling factor is set such that the unrolled loop body does not
- /// exceed this cost. Set this to UINT_MAX to disable the loop body cost
+ /// The cost threshold for the unrolled loop. Should be relative to the
+ /// getUserCost values returned by this API, and the expectation is that
+ /// the unrolled loop's instructions when run through that interface should
+ /// not exceed this cost. However, this is only an estimate. Also, specific
+ /// loops may be unrolled even with a cost above this threshold if deemed
+ /// profitable. Set this to UINT_MAX to disable the loop body cost
/// restriction.
unsigned Threshold;
- /// If complete unrolling could help other optimizations (e.g. InstSimplify)
- /// to remove N% of instructions, then we can go beyond unroll threshold.
- /// This value set the minimal percent for allowing that.
- unsigned MinPercentOfOptimized;
- /// The absolute cost threshold. We won't go beyond this even if complete
- /// unrolling could result in optimizing out 90% of instructions.
- unsigned AbsoluteThreshold;
+ /// If complete unrolling will reduce the cost of the loop below its
+ /// expected dynamic cost while rolled by this percentage, apply a discount
+ /// (below) to its unrolled cost.
+ unsigned PercentDynamicCostSavedThreshold;
+ /// The discount applied to the unrolled cost when the *dynamic* cost
+ /// savings of unrolling exceed the \c PercentDynamicCostSavedThreshold.
+ unsigned DynamicCostSavingsDiscount;
/// The cost threshold for the unrolled loop when optimizing for size (set
/// to UINT_MAX to disable).
unsigned OptSizeThreshold;
/// loop body even when the number of loop iterations is not known at
/// compile time).
bool Runtime;
+ /// Allow emitting expensive instructions (such as divisions) when computing
+ /// the trip count of a loop for runtime unrolling.
+ bool AllowExpensiveTripCount;
};
/// \brief Get target-customized preferences for the generic loop unrolling
/// mode is legal for a load/store of any legal type.
/// TODO: Handle pre/postinc as well.
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) const;
+ bool HasBaseReg, int64_t Scale,
+ unsigned AddrSpace = 0) const;
+
+ /// \brief Return true if the target supports masked load/store
+ /// AVX2 and AVX-512 targets allow masks for consecutive load and store for
+ /// 32 and 64 bit elements.
+ bool isLegalMaskedStore(Type *DataType) const;
+ bool isLegalMaskedLoad(Type *DataType) const;
- /// \brief Return true if the target works with masked instruction
- /// AVX2 allows masks for consecutive load and store for i32 and i64 elements.
- /// AVX-512 architecture will also allow masks for non-consecutive memory
- /// accesses.
- bool isLegalMaskedStore(Type *DataType, int Consecutive) const;
- bool isLegalMaskedLoad(Type *DataType, int Consecutive) const;
+ /// \brief Return true if the target supports masked gather/scatter
+ /// AVX-512 fully supports gather and scatter for vectors with 32 and 64
+ /// bits scalar type.
+ bool isLegalMaskedScatter(Type *DataType) const;
+ bool isLegalMaskedGather(Type *DataType) const;
/// \brief Return the cost of the scaling factor used in the addressing
/// mode represented by AM for this target, for a load/store
/// If the AM is not supported, it returns a negative value.
/// TODO: Handle pre/postinc as well.
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) const;
+ bool HasBaseReg, int64_t Scale,
+ unsigned AddrSpace = 0) const;
/// \brief Return true if it's free to truncate a value of type Ty1 to type
/// Ty2. e.g. On x86 it's free to truncate a i32 value in register EAX to i16
/// \brief Don't restrict interleaved unrolling to small loops.
bool enableAggressiveInterleaving(bool LoopHasReductions) const;
+ /// \brief Enable matching of interleaved access groups.
+ bool enableInterleavedAccessVectorization() const;
+
/// \brief Return hardware support for population count.
PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const;
/// \brief Return the expected cost of supporting the floating point operation
/// of the specified type.
- unsigned getFPOpCost(Type *Ty) const;
+ int getFPOpCost(Type *Ty) const;
/// \brief Return the expected cost of materializing for the given integer
/// immediate of the specified type.
- unsigned getIntImmCost(const APInt &Imm, Type *Ty) const;
+ int getIntImmCost(const APInt &Imm, Type *Ty) const;
/// \brief Return the expected cost of materialization for the given integer
/// immediate of the specified type for a given instruction. The cost can be
/// zero if the immediate can be folded into the specified instruction.
- unsigned getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm,
- Type *Ty) const;
- unsigned getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
- Type *Ty) const;
+ int getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm,
+ Type *Ty) const;
+ int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
+ Type *Ty) const;
/// @}
/// \name Vector Target Information
/// \return The maximum interleave factor that any transform should try to
/// perform for this target. This number depends on the level of parallelism
/// and the number of execution units in the CPU.
- unsigned getMaxInterleaveFactor() const;
+ unsigned getMaxInterleaveFactor(unsigned VF) const;
/// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc.
- unsigned
- getArithmeticInstrCost(unsigned Opcode, Type *Ty,
- OperandValueKind Opd1Info = OK_AnyValue,
- OperandValueKind Opd2Info = OK_AnyValue,
- OperandValueProperties Opd1PropInfo = OP_None,
- OperandValueProperties Opd2PropInfo = OP_None) const;
+ int getArithmeticInstrCost(
+ unsigned Opcode, Type *Ty, OperandValueKind Opd1Info = OK_AnyValue,
+ OperandValueKind Opd2Info = OK_AnyValue,
+ OperandValueProperties Opd1PropInfo = OP_None,
+ OperandValueProperties Opd2PropInfo = OP_None) const;
/// \return The cost of a shuffle instruction of kind Kind and of type Tp.
/// The index and subtype parameters are used by the subvector insertion and
/// extraction shuffle kinds.
- unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index = 0,
- Type *SubTp = nullptr) const;
+ int getShuffleCost(ShuffleKind Kind, Type *Tp, int Index = 0,
+ Type *SubTp = nullptr) const;
/// \return The expected cost of cast instructions, such as bitcast, trunc,
/// zext, etc.
- unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) const;
+ int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) const;
/// \return The expected cost of control-flow related instructions such as
/// Phi, Ret, Br.
- unsigned getCFInstrCost(unsigned Opcode) const;
+ int getCFInstrCost(unsigned Opcode) const;
/// \returns The expected cost of compare and select instructions.
- unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
- Type *CondTy = nullptr) const;
+ int getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
+ Type *CondTy = nullptr) const;
/// \return The expected cost of vector Insert and Extract.
/// Use -1 to indicate that there is no information on the index value.
- unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
- unsigned Index = -1) const;
+ int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index = -1) const;
/// \return The cost of Load and Store instructions.
- unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
- unsigned AddressSpace) const;
+ int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
+ unsigned AddressSpace) const;
/// \return The cost of masked Load and Store instructions.
- unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
+ int getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
+ unsigned AddressSpace) const;
+
+ /// \return The cost of the interleaved memory operation.
+ /// \p Opcode is the memory operation code
+ /// \p VecTy is the vector type of the interleaved access.
+ /// \p Factor is the interleave factor
+ /// \p Indices is the indices for interleaved load members (as interleaved
+ /// load allows gaps)
+ /// \p Alignment is the alignment of the memory operation
+ /// \p AddressSpace is address space of the pointer.
+ int getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor,
+ ArrayRef<unsigned> Indices, unsigned Alignment,
unsigned AddressSpace) const;
/// \brief Calculate the cost of performing a vector reduction.
/// Split:
/// (v0, v1, v2, v3)
/// ((v0+v2), (v1+v3), undef, undef)
- unsigned getReductionCost(unsigned Opcode, Type *Ty,
- bool IsPairwiseForm) const;
+ int getReductionCost(unsigned Opcode, Type *Ty, bool IsPairwiseForm) const;
/// \returns The cost of Intrinsic instructions.
- unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Type *> Tys) const;
+ int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
+ ArrayRef<Type *> Tys) const;
+
+ /// \returns The cost of Call instructions.
+ int getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys) const;
/// \returns The number of pieces into which the provided type must be
/// split during legalization. Zero is returned when the answer is unknown.
/// The 'IsComplex' parameter is a hint that the address computation is likely
/// to involve multiple instructions and as such unlikely to be merged into
/// the address indexing mode.
- unsigned getAddressComputationCost(Type *Ty, bool IsComplex = false) const;
+ int getAddressComputationCost(Type *Ty, bool IsComplex = false) const;
/// \returns The cost, if any, of keeping values of the given types alive
/// over a callsite.
Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
Type *ExpectedType) const;
+ /// \returns True if the two functions have compatible attributes for inlining
+ /// purposes.
+ bool areInlineCompatible(const Function *Caller,
+ const Function *Callee) const;
+
/// @}
private:
class TargetTransformInfo::Concept {
public:
virtual ~Concept() = 0;
-
- virtual unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) = 0;
- virtual unsigned getGEPCost(const Value *Ptr,
- ArrayRef<const Value *> Operands) = 0;
- virtual unsigned getCallCost(FunctionType *FTy, int NumArgs) = 0;
- virtual unsigned getCallCost(const Function *F, int NumArgs) = 0;
- virtual unsigned getCallCost(const Function *F,
+ virtual const DataLayout &getDataLayout() const = 0;
+ virtual int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) = 0;
+ virtual int getGEPCost(Type *PointeeType, const Value *Ptr,
+ ArrayRef<const Value *> Operands) = 0;
+ virtual int getCallCost(FunctionType *FTy, int NumArgs) = 0;
+ virtual int getCallCost(const Function *F, int NumArgs) = 0;
+ virtual int getCallCost(const Function *F,
+ ArrayRef<const Value *> Arguments) = 0;
+ virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
+ ArrayRef<Type *> ParamTys) = 0;
+ virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
ArrayRef<const Value *> Arguments) = 0;
- virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys) = 0;
- virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments) = 0;
- virtual unsigned getUserCost(const User *U) = 0;
+ virtual int getUserCost(const User *U) = 0;
virtual bool hasBranchDivergence() = 0;
+ virtual bool isSourceOfDivergence(const Value *V) = 0;
virtual bool isLoweredToCall(const Function *F) = 0;
virtual void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) = 0;
virtual bool isLegalAddImmediate(int64_t Imm) = 0;
virtual bool isLegalICmpImmediate(int64_t Imm) = 0;
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
int64_t BaseOffset, bool HasBaseReg,
- int64_t Scale) = 0;
- virtual bool isLegalMaskedStore(Type *DataType, int Consecutive) = 0;
- virtual bool isLegalMaskedLoad(Type *DataType, int Consecutive) = 0;
+ int64_t Scale,
+ unsigned AddrSpace) = 0;
+ virtual bool isLegalMaskedStore(Type *DataType) = 0;
+ virtual bool isLegalMaskedLoad(Type *DataType) = 0;
+ virtual bool isLegalMaskedScatter(Type *DataType) = 0;
+ virtual bool isLegalMaskedGather(Type *DataType) = 0;
virtual int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,
int64_t BaseOffset, bool HasBaseReg,
- int64_t Scale) = 0;
+ int64_t Scale, unsigned AddrSpace) = 0;
virtual bool isTruncateFree(Type *Ty1, Type *Ty2) = 0;
virtual bool isProfitableToHoist(Instruction *I) = 0;
virtual bool isTypeLegal(Type *Ty) = 0;
virtual unsigned getJumpBufSize() = 0;
virtual bool shouldBuildLookupTables() = 0;
virtual bool enableAggressiveInterleaving(bool LoopHasReductions) = 0;
+ virtual bool enableInterleavedAccessVectorization() = 0;
virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) = 0;
virtual bool haveFastSqrt(Type *Ty) = 0;
- virtual unsigned getFPOpCost(Type *Ty) = 0;
- virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) = 0;
- virtual unsigned getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm,
- Type *Ty) = 0;
- virtual unsigned getIntImmCost(Intrinsic::ID IID, unsigned Idx,
- const APInt &Imm, Type *Ty) = 0;
+ virtual int getFPOpCost(Type *Ty) = 0;
+ virtual int getIntImmCost(const APInt &Imm, Type *Ty) = 0;
+ virtual int getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm,
+ Type *Ty) = 0;
+ virtual int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
+ Type *Ty) = 0;
virtual unsigned getNumberOfRegisters(bool Vector) = 0;
virtual unsigned getRegisterBitWidth(bool Vector) = 0;
- virtual unsigned getMaxInterleaveFactor() = 0;
+ virtual unsigned getMaxInterleaveFactor(unsigned VF) = 0;
virtual unsigned
getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueKind Opd1Info,
OperandValueKind Opd2Info,
OperandValueProperties Opd1PropInfo,
OperandValueProperties Opd2PropInfo) = 0;
- virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
- Type *SubTp) = 0;
- virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) = 0;
- virtual unsigned getCFInstrCost(unsigned Opcode) = 0;
- virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
- Type *CondTy) = 0;
- virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
- unsigned Index) = 0;
- virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src,
- unsigned Alignment,
- unsigned AddressSpace) = 0;
- virtual unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
+ virtual int getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
+ Type *SubTp) = 0;
+ virtual int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) = 0;
+ virtual int getCFInstrCost(unsigned Opcode) = 0;
+ virtual int getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
+ Type *CondTy) = 0;
+ virtual int getVectorInstrCost(unsigned Opcode, Type *Val,
+ unsigned Index) = 0;
+ virtual int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
+ unsigned AddressSpace) = 0;
+ virtual int getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
+ unsigned Alignment,
+ unsigned AddressSpace) = 0;
+ virtual int getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
+ unsigned Factor,
+ ArrayRef<unsigned> Indices,
unsigned Alignment,
unsigned AddressSpace) = 0;
- virtual unsigned getReductionCost(unsigned Opcode, Type *Ty,
- bool IsPairwiseForm) = 0;
- virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Type *> Tys) = 0;
+ virtual int getReductionCost(unsigned Opcode, Type *Ty,
+ bool IsPairwiseForm) = 0;
+ virtual int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
+ ArrayRef<Type *> Tys) = 0;
+ virtual int getCallInstrCost(Function *F, Type *RetTy,
+ ArrayRef<Type *> Tys) = 0;
virtual unsigned getNumberOfParts(Type *Tp) = 0;
- virtual unsigned getAddressComputationCost(Type *Ty, bool IsComplex) = 0;
+ virtual int getAddressComputationCost(Type *Ty, bool IsComplex) = 0;
virtual unsigned getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) = 0;
virtual bool getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) = 0;
virtual Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
Type *ExpectedType) = 0;
+ virtual bool areInlineCompatible(const Function *Caller,
+ const Function *Callee) const = 0;
};
template <typename T>
Model(T Impl) : Impl(std::move(Impl)) {}
~Model() override {}
- unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) override {
+ const DataLayout &getDataLayout() const override {
+ return Impl.getDataLayout();
+ }
+
+ int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) override {
return Impl.getOperationCost(Opcode, Ty, OpTy);
}
- unsigned getGEPCost(const Value *Ptr,
- ArrayRef<const Value *> Operands) override {
- return Impl.getGEPCost(Ptr, Operands);
+ int getGEPCost(Type *PointeeType, const Value *Ptr,
+ ArrayRef<const Value *> Operands) override {
+ return Impl.getGEPCost(PointeeType, Ptr, Operands);
}
- unsigned getCallCost(FunctionType *FTy, int NumArgs) override {
+ int getCallCost(FunctionType *FTy, int NumArgs) override {
return Impl.getCallCost(FTy, NumArgs);
}
- unsigned getCallCost(const Function *F, int NumArgs) override {
+ int getCallCost(const Function *F, int NumArgs) override {
return Impl.getCallCost(F, NumArgs);
}
- unsigned getCallCost(const Function *F,
- ArrayRef<const Value *> Arguments) override {
+ int getCallCost(const Function *F,
+ ArrayRef<const Value *> Arguments) override {
return Impl.getCallCost(F, Arguments);
}
- unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys) override {
+ int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
+ ArrayRef<Type *> ParamTys) override {
return Impl.getIntrinsicCost(IID, RetTy, ParamTys);
}
- unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments) override {
+ int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
+ ArrayRef<const Value *> Arguments) override {
return Impl.getIntrinsicCost(IID, RetTy, Arguments);
}
- unsigned getUserCost(const User *U) override { return Impl.getUserCost(U); }
+ int getUserCost(const User *U) override { return Impl.getUserCost(U); }
bool hasBranchDivergence() override { return Impl.hasBranchDivergence(); }
+ bool isSourceOfDivergence(const Value *V) override {
+ return Impl.isSourceOfDivergence(V);
+ }
bool isLoweredToCall(const Function *F) override {
return Impl.isLoweredToCall(F);
}
return Impl.isLegalICmpImmediate(Imm);
}
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) override {
+ bool HasBaseReg, int64_t Scale,
+ unsigned AddrSpace) override {
return Impl.isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
- Scale);
+ Scale, AddrSpace);
}
- bool isLegalMaskedStore(Type *DataType, int Consecutive) override {
- return Impl.isLegalMaskedStore(DataType, Consecutive);
+ bool isLegalMaskedStore(Type *DataType) override {
+ return Impl.isLegalMaskedStore(DataType);
}
- bool isLegalMaskedLoad(Type *DataType, int Consecutive) override {
- return Impl.isLegalMaskedLoad(DataType, Consecutive);
+ bool isLegalMaskedLoad(Type *DataType) override {
+ return Impl.isLegalMaskedLoad(DataType);
+ }
+ bool isLegalMaskedScatter(Type *DataType) override {
+ return Impl.isLegalMaskedScatter(DataType);
+ }
+ bool isLegalMaskedGather(Type *DataType) override {
+ return Impl.isLegalMaskedGather(DataType);
}
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) override {
- return Impl.getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, Scale);
+ bool HasBaseReg, int64_t Scale,
+ unsigned AddrSpace) override {
+ return Impl.getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg,
+ Scale, AddrSpace);
}
bool isTruncateFree(Type *Ty1, Type *Ty2) override {
return Impl.isTruncateFree(Ty1, Ty2);
bool enableAggressiveInterleaving(bool LoopHasReductions) override {
return Impl.enableAggressiveInterleaving(LoopHasReductions);
}
+ bool enableInterleavedAccessVectorization() override {
+ return Impl.enableInterleavedAccessVectorization();
+ }
PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) override {
return Impl.getPopcntSupport(IntTyWidthInBit);
}
bool haveFastSqrt(Type *Ty) override { return Impl.haveFastSqrt(Ty); }
- unsigned getFPOpCost(Type *Ty) override {
- return Impl.getFPOpCost(Ty);
- }
+ int getFPOpCost(Type *Ty) override { return Impl.getFPOpCost(Ty); }
- unsigned getIntImmCost(const APInt &Imm, Type *Ty) override {
+ int getIntImmCost(const APInt &Imm, Type *Ty) override {
return Impl.getIntImmCost(Imm, Ty);
}
- unsigned getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm,
- Type *Ty) override {
+ int getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm,
+ Type *Ty) override {
return Impl.getIntImmCost(Opc, Idx, Imm, Ty);
}
- unsigned getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
- Type *Ty) override {
+ int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
+ Type *Ty) override {
return Impl.getIntImmCost(IID, Idx, Imm, Ty);
}
unsigned getNumberOfRegisters(bool Vector) override {
unsigned getRegisterBitWidth(bool Vector) override {
return Impl.getRegisterBitWidth(Vector);
}
- unsigned getMaxInterleaveFactor() override {
- return Impl.getMaxInterleaveFactor();
+ unsigned getMaxInterleaveFactor(unsigned VF) override {
+ return Impl.getMaxInterleaveFactor(VF);
}
unsigned
getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueKind Opd1Info,
return Impl.getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info,
Opd1PropInfo, Opd2PropInfo);
}
- unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
- Type *SubTp) override {
+ int getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
+ Type *SubTp) override {
return Impl.getShuffleCost(Kind, Tp, Index, SubTp);
}
- unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) override {
+ int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) override {
return Impl.getCastInstrCost(Opcode, Dst, Src);
}
- unsigned getCFInstrCost(unsigned Opcode) override {
+ int getCFInstrCost(unsigned Opcode) override {
return Impl.getCFInstrCost(Opcode);
}
- unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
- Type *CondTy) override {
+ int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy) override {
return Impl.getCmpSelInstrCost(Opcode, ValTy, CondTy);
}
- unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
- unsigned Index) override {
+ int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) override {
return Impl.getVectorInstrCost(Opcode, Val, Index);
}
- unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
- unsigned AddressSpace) override {
+ int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
+ unsigned AddressSpace) override {
return Impl.getMemoryOpCost(Opcode, Src, Alignment, AddressSpace);
}
- unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
- unsigned AddressSpace) override {
+ int getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
+ unsigned AddressSpace) override {
return Impl.getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace);
}
- unsigned getReductionCost(unsigned Opcode, Type *Ty,
- bool IsPairwiseForm) override {
+ int getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor,
+ ArrayRef<unsigned> Indices, unsigned Alignment,
+ unsigned AddressSpace) override {
+ return Impl.getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
+ Alignment, AddressSpace);
+ }
+ int getReductionCost(unsigned Opcode, Type *Ty,
+ bool IsPairwiseForm) override {
return Impl.getReductionCost(Opcode, Ty, IsPairwiseForm);
}
- unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Type *> Tys) override {
+ int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
+ ArrayRef<Type *> Tys) override {
return Impl.getIntrinsicInstrCost(ID, RetTy, Tys);
}
+ int getCallInstrCost(Function *F, Type *RetTy,
+ ArrayRef<Type *> Tys) override {
+ return Impl.getCallInstrCost(F, RetTy, Tys);
+ }
unsigned getNumberOfParts(Type *Tp) override {
return Impl.getNumberOfParts(Tp);
}
- unsigned getAddressComputationCost(Type *Ty, bool IsComplex) override {
+ int getAddressComputationCost(Type *Ty, bool IsComplex) override {
return Impl.getAddressComputationCost(Ty, IsComplex);
}
unsigned getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) override {
Type *ExpectedType) override {
return Impl.getOrCreateResultFromMemIntrinsic(Inst, ExpectedType);
}
+ bool areInlineCompatible(const Function *Caller,
+ const Function *Callee) const override {
+ return Impl.areInlineCompatible(Caller, Callee);
+ }
};
template <typename T>
///
/// The callback will be called with a particular function for which the TTI
/// is needed and must return a TTI object for that function.
- TargetIRAnalysis(std::function<Result(Function &)> TTICallback);
+ TargetIRAnalysis(std::function<Result(const Function &)> TTICallback);
// Value semantics. We spell out the constructors for MSVC.
TargetIRAnalysis(const TargetIRAnalysis &Arg)
return *this;
}
- Result run(Function &F);
+ Result run(const Function &F);
private:
static char PassID;
/// the analysis and thus use a function_ref which would be lighter weight.
/// This may also be less error prone as the callback is likely to reference
/// the external TargetMachine, and that reference needs to never dangle.
- std::function<Result(Function &)> TTICallback;
+ std::function<Result(const Function &)> TTICallback;
/// \brief Helper function used as the callback in the default constructor.
- static Result getDefaultTTI(Function &F);
+ static Result getDefaultTTI(const Function &F);
};
/// \brief Wrapper pass for TargetTransformInfo.
explicit TargetTransformInfoWrapperPass(TargetIRAnalysis TIRA);
- TargetTransformInfo &getTTI(Function &F);
+ TargetTransformInfo &getTTI(const Function &F);
};
/// \brief Create an analysis pass wrapper around a TTI object.