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   bool shouldFavorPostInc() const;
71 
72   // L1 cache prefetch.
73   unsigned getPrefetchDistance() const override;
74   unsigned getCacheLineSize() const override;
75 
76   /// @}
77 
78   /// \name Vector TTI Implementations
79   /// @{
80 
81   unsigned getNumberOfRegisters(bool vector) const;
82   unsigned getMaxInterleaveFactor(unsigned VF);
83   unsigned getRegisterBitWidth(bool Vector) const;
84   unsigned getMinVectorRegisterBitWidth() const;
85   unsigned getMinimumVF(unsigned ElemWidth) const;
86 
87   bool shouldMaximizeVectorBandwidth(bool OptSize) const {
88     return true;
89   }
90   bool supportsEfficientVectorElementLoadStore() {
91     return false;
92   }
93   bool hasBranchDivergence() {
94     return false;
95   }
96   bool enableAggressiveInterleaving(bool LoopHasReductions) {
97     return false;
98   }
99   bool prefersVectorizedAddressing() {
100     return false;
101   }
102   bool enableInterleavedAccessVectorization() {
103     return true;
104   }
105 
106   unsigned getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts,
107                                     bool Insert, bool Extract);
108   unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
109                                             unsigned VF);
110   unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type*> Tys,
111                             TTI::TargetCostKind CostKind);
112   unsigned getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
113                                  TTI::TargetCostKind CostKind);
114   unsigned getAddressComputationCost(Type *Tp, ScalarEvolution *SE,
115             const SCEV *S);
116   unsigned getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment,
117                            unsigned AddressSpace,
118                            TTI::TargetCostKind CostKind,
119                            const Instruction *I = nullptr);
120   unsigned
121   getMaskedMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
122                         unsigned AddressSpace,
123                         TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency);
124   unsigned getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index,
125             Type *SubTp);
126   unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
127                                   const Value *Ptr, bool VariableMask,
128                                   Align Alignment, TTI::TargetCostKind CostKind,
129                                   const Instruction *I);
130   unsigned getInterleavedMemoryOpCost(
131       unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
132       Align Alignment, unsigned AddressSpace,
133       TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency,
134       bool UseMaskForCond = false, bool UseMaskForGaps = false);
135   unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
136 
137                               CmpInst::Predicate VecPred,
138                               TTI::TargetCostKind CostKind,
139                               const Instruction *I = nullptr);
140   unsigned getArithmeticInstrCost(
141       unsigned Opcode, Type *Ty,
142       TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
143       TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue,
144       TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue,
145       TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None,
146       TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None,
147       ArrayRef<const Value *> Args = ArrayRef<const Value *>(),
148       const Instruction *CxtI = nullptr);
149   unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
150                             TTI::CastContextHint CCH,
151                             TTI::TargetCostKind CostKind,
152                             const Instruction *I = nullptr);
153   unsigned getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index);
154 
155   unsigned getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind) {
156     return 1;
157   }
158 
159   bool isLegalMaskedStore(Type *DataType, Align Alignment);
160   bool isLegalMaskedLoad(Type *DataType, Align Alignment);
161 
162   /// @}
163 
164   int getUserCost(const User *U, ArrayRef<const Value *> Operands,
165                   TTI::TargetCostKind CostKind);
166 
167   // Hexagon specific decision to generate a lookup table.
168   bool shouldBuildLookupTables() const;
169 };
170 
171 } // end namespace llvm
172 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H
173