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   bool isHVXVectorType(Type *Ty) const;
47 
48   // Returns the number of vector elements of Ty, if Ty is a vector type,
49   // or 1 if Ty is a scalar type. It is incorrect to call this function
50   // with any other type.
51   unsigned getTypeNumElements(Type *Ty) const;
52 
53 public:
54   explicit HexagonTTIImpl(const HexagonTargetMachine *TM, const Function &F)
55       : BaseT(TM, F.getParent()->getDataLayout()),
56         ST(*TM->getSubtargetImpl(F)), TLI(*ST.getTargetLowering()) {}
57 
58   /// \name Scalar TTI Implementations
59   /// @{
60 
61   TTI::PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const;
62 
63   // The Hexagon target can unroll loops with run-time trip counts.
64   void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
65                                TTI::UnrollingPreferences &UP,
66                                OptimizationRemarkEmitter *ORE);
67 
68   void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
69                              TTI::PeelingPreferences &PP);
70 
71   /// Bias LSR towards creating post-increment opportunities.
72   TTI::AddressingModeKind
73     getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const;
74 
75   // L1 cache prefetch.
76   unsigned getPrefetchDistance() const override;
77   unsigned getCacheLineSize() const override;
78 
79   /// @}
80 
81   /// \name Vector TTI Implementations
82   /// @{
83 
84   unsigned getNumberOfRegisters(bool vector) const;
85   unsigned getMaxInterleaveFactor(ElementCount VF);
86   TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const;
87   unsigned getMinVectorRegisterBitWidth() const;
88   ElementCount getMinimumVF(unsigned ElemWidth, bool IsScalable) const;
89 
90   bool
91   shouldMaximizeVectorBandwidth(TargetTransformInfo::RegisterKind K) const {
92     return true;
93   }
94   bool supportsEfficientVectorElementLoadStore() { return false; }
95   bool hasBranchDivergence(const Function *F = nullptr) { return false; }
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   InstructionCost getScalarizationOverhead(VectorType *Ty,
107                                            const APInt &DemandedElts,
108                                            bool Insert, bool Extract,
109                                            TTI::TargetCostKind CostKind);
110   InstructionCost
111   getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
112                                    ArrayRef<Type *> Tys,
113                                    TTI::TargetCostKind CostKind);
114   InstructionCost getCallInstrCost(Function *F, Type *RetTy,
115                                    ArrayRef<Type *> Tys,
116                                    TTI::TargetCostKind CostKind);
117   InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
118                                         TTI::TargetCostKind CostKind);
119   InstructionCost getAddressComputationCost(Type *Tp, ScalarEvolution *SE,
120                                             const SCEV *S);
121   InstructionCost
122   getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment,
123                   unsigned AddressSpace, TTI::TargetCostKind CostKind,
124                   TTI::OperandValueInfo OpInfo = {TTI::OK_AnyValue, TTI::OP_None},
125                   const Instruction *I = nullptr);
126   InstructionCost getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
127                                         Align Alignment, unsigned AddressSpace,
128                                         TTI::TargetCostKind CostKind);
129   InstructionCost getShuffleCost(TTI::ShuffleKind Kind, Type *Tp,
130                                  ArrayRef<int> Mask,
131                                  TTI::TargetCostKind CostKind, int Index,
132                                  Type *SubTp,
133                                  ArrayRef<const Value *> Args = std::nullopt);
134   InstructionCost getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
135                                          const Value *Ptr, bool VariableMask,
136                                          Align Alignment,
137                                          TTI::TargetCostKind CostKind,
138                                          const Instruction *I);
139   InstructionCost getInterleavedMemoryOpCost(
140       unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
141       Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
142       bool UseMaskForCond = false, bool UseMaskForGaps = false);
143   InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
144                                      CmpInst::Predicate VecPred,
145                                      TTI::TargetCostKind CostKind,
146                                      const Instruction *I = nullptr);
147   InstructionCost getArithmeticInstrCost(
148       unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
149       TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None},
150       TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},
151       ArrayRef<const Value *> Args = ArrayRef<const Value *>(),
152       const Instruction *CxtI = nullptr);
153   InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
154                                    TTI::CastContextHint CCH,
155                                    TTI::TargetCostKind CostKind,
156                                    const Instruction *I = nullptr);
157   using BaseT::getVectorInstrCost;
158   InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val,
159                                      TTI::TargetCostKind CostKind,
160                                      unsigned Index, Value *Op0, Value *Op1);
161 
162   InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
163                                  const Instruction *I = nullptr) {
164     return 1;
165   }
166 
167   bool isLegalMaskedStore(Type *DataType, Align Alignment);
168   bool isLegalMaskedLoad(Type *DataType, Align Alignment);
169 
170   /// @}
171 
172   InstructionCost getInstructionCost(const User *U,
173                                      ArrayRef<const Value *> Operands,
174                                      TTI::TargetCostKind CostKind);
175 
176   // Hexagon specific decision to generate a lookup table.
177   bool shouldBuildLookupTables() const;
178 };
179 
180 } // end namespace llvm
181 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H
182