xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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