10b57cec5SDimitry Andric //==- HexagonTargetTransformInfo.cpp - Hexagon specific TTI pass -*- C++ -*-==// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric /// \file 80b57cec5SDimitry Andric /// This file implements a TargetTransformInfo analysis pass specific to the 90b57cec5SDimitry Andric /// Hexagon target machine. It uses the target's detailed information to provide 100b57cec5SDimitry Andric /// more precise answers to certain TTI queries, while letting the target 110b57cec5SDimitry Andric /// independent and default TTI implementations handle the rest. 120b57cec5SDimitry Andric /// 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H 160b57cec5SDimitry Andric #define LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "Hexagon.h" 190b57cec5SDimitry Andric #include "HexagonSubtarget.h" 200b57cec5SDimitry Andric #include "HexagonTargetMachine.h" 210b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 220b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/BasicTTIImpl.h" 240b57cec5SDimitry Andric #include "llvm/IR/Function.h" 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric namespace llvm { 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric class Loop; 290b57cec5SDimitry Andric class ScalarEvolution; 300b57cec5SDimitry Andric class User; 310b57cec5SDimitry Andric class Value; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric class HexagonTTIImpl : public BasicTTIImplBase<HexagonTTIImpl> { 340b57cec5SDimitry Andric using BaseT = BasicTTIImplBase<HexagonTTIImpl>; 350b57cec5SDimitry Andric using TTI = TargetTransformInfo; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric friend BaseT; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric const HexagonSubtarget &ST; 400b57cec5SDimitry Andric const HexagonTargetLowering &TLI; 410b57cec5SDimitry Andric getST()420b57cec5SDimitry Andric const HexagonSubtarget *getST() const { return &ST; } getTLI()430b57cec5SDimitry Andric const HexagonTargetLowering *getTLI() const { return &TLI; } 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric bool useHVX() const; 46bdd1243dSDimitry Andric bool isHVXVectorType(Type *Ty) const; 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric // Returns the number of vector elements of Ty, if Ty is a vector type, 490b57cec5SDimitry Andric // or 1 if Ty is a scalar type. It is incorrect to call this function 500b57cec5SDimitry Andric // with any other type. 510b57cec5SDimitry Andric unsigned getTypeNumElements(Type *Ty) const; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric public: HexagonTTIImpl(const HexagonTargetMachine * TM,const Function & F)540b57cec5SDimitry Andric explicit HexagonTTIImpl(const HexagonTargetMachine *TM, const Function &F) 55*0fca6ea1SDimitry Andric : BaseT(TM, F.getDataLayout()), 560b57cec5SDimitry Andric ST(*TM->getSubtargetImpl(F)), TLI(*ST.getTargetLowering()) {} 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric /// \name Scalar TTI Implementations 590b57cec5SDimitry Andric /// @{ 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric TTI::PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric // The Hexagon target can unroll loops with run-time trip counts. 640b57cec5SDimitry Andric void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, 65349cc55cSDimitry Andric TTI::UnrollingPreferences &UP, 66349cc55cSDimitry Andric OptimizationRemarkEmitter *ORE); 670b57cec5SDimitry Andric 685ffd83dbSDimitry Andric void getPeelingPreferences(Loop *L, ScalarEvolution &SE, 695ffd83dbSDimitry Andric TTI::PeelingPreferences &PP); 705ffd83dbSDimitry Andric 710b57cec5SDimitry Andric /// Bias LSR towards creating post-increment opportunities. 72fe6060f1SDimitry Andric TTI::AddressingModeKind 73fe6060f1SDimitry Andric getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric // L1 cache prefetch. 768bcb0991SDimitry Andric unsigned getPrefetchDistance() const override; 778bcb0991SDimitry Andric unsigned getCacheLineSize() const override; 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric /// @} 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric /// \name Vector TTI Implementations 820b57cec5SDimitry Andric /// @{ 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric unsigned getNumberOfRegisters(bool vector) const; 8506c3fb27SDimitry Andric unsigned getMaxInterleaveFactor(ElementCount VF); 86fe6060f1SDimitry Andric TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const; 870b57cec5SDimitry Andric unsigned getMinVectorRegisterBitWidth() const; 88fe6060f1SDimitry Andric ElementCount getMinimumVF(unsigned ElemWidth, bool IsScalable) const; 890b57cec5SDimitry Andric 9081ad6265SDimitry Andric bool shouldMaximizeVectorBandwidth(TargetTransformInfo::RegisterKind K)9181ad6265SDimitry Andric shouldMaximizeVectorBandwidth(TargetTransformInfo::RegisterKind K) const { 920b57cec5SDimitry Andric return true; 930b57cec5SDimitry Andric } supportsEfficientVectorElementLoadStore()9481ad6265SDimitry Andric bool supportsEfficientVectorElementLoadStore() { return false; } 9506c3fb27SDimitry Andric bool hasBranchDivergence(const Function *F = nullptr) { return false; } enableAggressiveInterleaving(bool LoopHasReductions)960b57cec5SDimitry Andric bool enableAggressiveInterleaving(bool LoopHasReductions) { 970b57cec5SDimitry Andric return false; 980b57cec5SDimitry Andric } prefersVectorizedAddressing()990b57cec5SDimitry Andric bool prefersVectorizedAddressing() { 1000b57cec5SDimitry Andric return false; 1010b57cec5SDimitry Andric } enableInterleavedAccessVectorization()1020b57cec5SDimitry Andric bool enableInterleavedAccessVectorization() { 1030b57cec5SDimitry Andric return true; 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric 106fe6060f1SDimitry Andric InstructionCost getCallInstrCost(Function *F, Type *RetTy, 107fe6060f1SDimitry Andric ArrayRef<Type *> Tys, 1085ffd83dbSDimitry Andric TTI::TargetCostKind CostKind); 109fe6060f1SDimitry Andric InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, 1105ffd83dbSDimitry Andric TTI::TargetCostKind CostKind); 111fe6060f1SDimitry Andric InstructionCost getAddressComputationCost(Type *Tp, ScalarEvolution *SE, 1120b57cec5SDimitry Andric const SCEV *S); 113bdd1243dSDimitry Andric InstructionCost 114bdd1243dSDimitry Andric getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment, 115bdd1243dSDimitry Andric unsigned AddressSpace, TTI::TargetCostKind CostKind, 116bdd1243dSDimitry Andric TTI::OperandValueInfo OpInfo = {TTI::OK_AnyValue, TTI::OP_None}, 117480093f4SDimitry Andric const Instruction *I = nullptr); 118349cc55cSDimitry Andric InstructionCost getMaskedMemoryOpCost(unsigned Opcode, Type *Src, 119349cc55cSDimitry Andric Align Alignment, unsigned AddressSpace, 120349cc55cSDimitry Andric TTI::TargetCostKind CostKind); 121fe6060f1SDimitry Andric InstructionCost getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, 122bdd1243dSDimitry Andric ArrayRef<int> Mask, 123bdd1243dSDimitry Andric TTI::TargetCostKind CostKind, int Index, 124bdd1243dSDimitry Andric Type *SubTp, 125*0fca6ea1SDimitry Andric ArrayRef<const Value *> Args = std::nullopt, 126*0fca6ea1SDimitry Andric const Instruction *CxtI = nullptr); 127fe6060f1SDimitry Andric InstructionCost getGatherScatterOpCost(unsigned Opcode, Type *DataTy, 1285ffd83dbSDimitry Andric const Value *Ptr, bool VariableMask, 129fe6060f1SDimitry Andric Align Alignment, 130fe6060f1SDimitry Andric TTI::TargetCostKind CostKind, 1310b57cec5SDimitry Andric const Instruction *I); 132fe6060f1SDimitry Andric InstructionCost getInterleavedMemoryOpCost( 1335ffd83dbSDimitry Andric unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices, 134349cc55cSDimitry Andric Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, 1355ffd83dbSDimitry Andric bool UseMaskForCond = false, bool UseMaskForGaps = false); 136fe6060f1SDimitry Andric InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, 137e8d8bef9SDimitry Andric CmpInst::Predicate VecPred, 1385ffd83dbSDimitry Andric TTI::TargetCostKind CostKind, 1395ffd83dbSDimitry Andric const Instruction *I = nullptr); 140fe6060f1SDimitry Andric InstructionCost getArithmeticInstrCost( 141349cc55cSDimitry Andric unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, 142bdd1243dSDimitry Andric TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None}, 143bdd1243dSDimitry Andric TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None}, 144*0fca6ea1SDimitry Andric ArrayRef<const Value *> Args = std::nullopt, 145480093f4SDimitry Andric const Instruction *CxtI = nullptr); 146fe6060f1SDimitry Andric InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, 147e8d8bef9SDimitry Andric TTI::CastContextHint CCH, 1485ffd83dbSDimitry Andric TTI::TargetCostKind CostKind, 1490b57cec5SDimitry Andric const Instruction *I = nullptr); 150bdd1243dSDimitry Andric using BaseT::getVectorInstrCost; 151fe6060f1SDimitry Andric InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, 152bdd1243dSDimitry Andric TTI::TargetCostKind CostKind, 153bdd1243dSDimitry Andric unsigned Index, Value *Op0, Value *Op1); 1540b57cec5SDimitry Andric 155fe6060f1SDimitry Andric InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, 156fe6060f1SDimitry Andric const Instruction *I = nullptr) { 1570b57cec5SDimitry Andric return 1; 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric 160e8d8bef9SDimitry Andric bool isLegalMaskedStore(Type *DataType, Align Alignment); 161e8d8bef9SDimitry Andric bool isLegalMaskedLoad(Type *DataType, Align Alignment); 162e8d8bef9SDimitry Andric 1630b57cec5SDimitry Andric /// @} 1640b57cec5SDimitry Andric 165bdd1243dSDimitry Andric InstructionCost getInstructionCost(const User *U, 166bdd1243dSDimitry Andric ArrayRef<const Value *> Operands, 1675ffd83dbSDimitry Andric TTI::TargetCostKind CostKind); 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric // Hexagon specific decision to generate a lookup table. 1700b57cec5SDimitry Andric bool shouldBuildLookupTables() const; 1710b57cec5SDimitry Andric }; 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric } // end namespace llvm 1740b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H 175