1 //==- HexagonTargetTransformInfo.cpp - Hexagon specific TTI pass -*- C++ -*-==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 /// \file
8 /// This file implements a TargetTransformInfo analysis pass specific to the
9 /// Hexagon target machine. It uses the target's detailed information to provide
10 /// more precise answers to certain TTI queries, while letting the target
11 /// independent and default TTI implementations handle the rest.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H
16 #define LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H
17 
18 #include "Hexagon.h"
19 #include "HexagonSubtarget.h"
20 #include "HexagonTargetMachine.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/Analysis/TargetTransformInfo.h"
23 #include "llvm/CodeGen/BasicTTIImpl.h"
24 #include "llvm/IR/Function.h"
25 
26 namespace llvm {
27 
28 class Loop;
29 class ScalarEvolution;
30 class User;
31 class Value;
32 
33 class HexagonTTIImpl : public BasicTTIImplBase<HexagonTTIImpl> {
34   using BaseT = BasicTTIImplBase<HexagonTTIImpl>;
35   using TTI = TargetTransformInfo;
36 
37   friend BaseT;
38 
39   const HexagonSubtarget &ST;
40   const HexagonTargetLowering &TLI;
41 
42   const HexagonSubtarget *getST() const { return &ST; }
43   const HexagonTargetLowering *getTLI() const { return &TLI; }
44 
45   bool useHVX() const;
46 
47   // Returns the number of vector elements of Ty, if Ty is a vector type,
48   // or 1 if Ty is a scalar type. It is incorrect to call this function
49   // with any other type.
50   unsigned getTypeNumElements(Type *Ty) const;
51 
52 public:
53   explicit HexagonTTIImpl(const HexagonTargetMachine *TM, const Function &F)
54       : BaseT(TM, F.getParent()->getDataLayout()),
55         ST(*TM->getSubtargetImpl(F)), TLI(*ST.getTargetLowering()) {}
56 
57   /// \name Scalar TTI Implementations
58   /// @{
59 
60   TTI::PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const;
61 
62   // The Hexagon target can unroll loops with run-time trip counts.
63   void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
64                                TTI::UnrollingPreferences &UP);
65 
66   void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
67                              TTI::PeelingPreferences &PP);
68 
69   /// Bias LSR towards creating post-increment opportunities.
70   TTI::AddressingModeKind
71     getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const;
72 
73   // L1 cache prefetch.
74   unsigned getPrefetchDistance() const override;
75   unsigned getCacheLineSize() const override;
76 
77   /// @}
78 
79   /// \name Vector TTI Implementations
80   /// @{
81 
82   unsigned getNumberOfRegisters(bool vector) const;
83   unsigned getMaxInterleaveFactor(unsigned VF);
84   TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const;
85   unsigned getMinVectorRegisterBitWidth() const;
86   ElementCount getMinimumVF(unsigned ElemWidth, bool IsScalable) const;
87 
88   bool shouldMaximizeVectorBandwidth() const {
89     return true;
90   }
91   bool supportsEfficientVectorElementLoadStore() {
92     return false;
93   }
94   bool hasBranchDivergence() {
95     return false;
96   }
97   bool enableAggressiveInterleaving(bool LoopHasReductions) {
98     return false;
99   }
100   bool prefersVectorizedAddressing() {
101     return false;
102   }
103   bool enableInterleavedAccessVectorization() {
104     return true;
105   }
106 
107   InstructionCost getScalarizationOverhead(VectorType *Ty,
108                                            const APInt &DemandedElts,
109                                            bool Insert, bool Extract);
110   InstructionCost getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
111                                                    ArrayRef<Type *> Tys);
112   InstructionCost getCallInstrCost(Function *F, Type *RetTy,
113                                    ArrayRef<Type *> Tys,
114                                    TTI::TargetCostKind CostKind);
115   InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
116                                         TTI::TargetCostKind CostKind);
117   InstructionCost getAddressComputationCost(Type *Tp, ScalarEvolution *SE,
118                                             const SCEV *S);
119   InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src,
120                                   MaybeAlign Alignment, unsigned AddressSpace,
121                                   TTI::TargetCostKind CostKind,
122                                   const Instruction *I = nullptr);
123   InstructionCost
124   getMaskedMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
125                         unsigned AddressSpace,
126                         TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency);
127   InstructionCost getShuffleCost(TTI::ShuffleKind Kind, Type *Tp,
128                                  ArrayRef<int> Mask, int Index, Type *SubTp);
129   InstructionCost getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
130                                          const Value *Ptr, bool VariableMask,
131                                          Align Alignment,
132                                          TTI::TargetCostKind CostKind,
133                                          const Instruction *I);
134   InstructionCost getInterleavedMemoryOpCost(
135       unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
136       Align Alignment, unsigned AddressSpace,
137       TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency,
138       bool UseMaskForCond = false, bool UseMaskForGaps = false);
139   InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
140                                      CmpInst::Predicate VecPred,
141                                      TTI::TargetCostKind CostKind,
142                                      const Instruction *I = nullptr);
143   InstructionCost getArithmeticInstrCost(
144       unsigned Opcode, Type *Ty,
145       TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
146       TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue,
147       TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue,
148       TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None,
149       TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None,
150       ArrayRef<const Value *> Args = ArrayRef<const Value *>(),
151       const Instruction *CxtI = nullptr);
152   InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
153                                    TTI::CastContextHint CCH,
154                                    TTI::TargetCostKind CostKind,
155                                    const Instruction *I = nullptr);
156   InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val,
157                                      unsigned Index);
158 
159   InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
160                                  const Instruction *I = nullptr) {
161     return 1;
162   }
163 
164   bool isLegalMaskedStore(Type *DataType, Align Alignment);
165   bool isLegalMaskedLoad(Type *DataType, Align Alignment);
166 
167   /// @}
168 
169   InstructionCost getUserCost(const User *U, ArrayRef<const Value *> Operands,
170                               TTI::TargetCostKind CostKind);
171 
172   // Hexagon specific decision to generate a lookup table.
173   bool shouldBuildLookupTables() const;
174 };
175 
176 } // end namespace llvm
177 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H
178