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
26namespace llvm {
27
28class Loop;
29class ScalarEvolution;
30class User;
31class Value;
32
33class 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 isTypeForHVX(Type *VecTy) 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
53public:
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
67  void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
68                             TTI::PeelingPreferences &PP);
69
70  /// Bias LSR towards creating post-increment opportunities.
71  bool shouldFavorPostInc() 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  unsigned getRegisterBitWidth(bool Vector) const;
85  unsigned getMinVectorRegisterBitWidth() const;
86  unsigned getMinimumVF(unsigned ElemWidth) const;
87
88  bool shouldMaximizeVectorBandwidth(bool OptSize) 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  unsigned getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts,
108                                    bool Insert, bool Extract);
109  unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
110                                            unsigned VF);
111  unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type*> Tys,
112                            TTI::TargetCostKind CostKind);
113  unsigned getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
114                                 TTI::TargetCostKind CostKind);
115  unsigned getAddressComputationCost(Type *Tp, ScalarEvolution *SE,
116            const SCEV *S);
117  unsigned getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment,
118                           unsigned AddressSpace,
119                           TTI::TargetCostKind CostKind,
120                           const Instruction *I = nullptr);
121  unsigned
122  getMaskedMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
123                        unsigned AddressSpace,
124                        TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency);
125  unsigned getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index,
126            Type *SubTp);
127  unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
128                                  const Value *Ptr, bool VariableMask,
129                                  Align Alignment, TTI::TargetCostKind CostKind,
130                                  const Instruction *I);
131  unsigned getInterleavedMemoryOpCost(
132      unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
133      Align Alignment, unsigned AddressSpace,
134      TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency,
135      bool UseMaskForCond = false, bool UseMaskForGaps = false);
136  unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
137                              TTI::TargetCostKind CostKind,
138                              const Instruction *I = nullptr);
139  unsigned getArithmeticInstrCost(
140      unsigned Opcode, Type *Ty,
141      TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
142      TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue,
143      TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue,
144      TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None,
145      TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None,
146      ArrayRef<const Value *> Args = ArrayRef<const Value *>(),
147      const Instruction *CxtI = nullptr);
148  unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
149            TTI::TargetCostKind CostKind,
150            const Instruction *I = nullptr);
151  unsigned getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index);
152
153  unsigned getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind) {
154    return 1;
155  }
156
157  /// @}
158
159  int getUserCost(const User *U, ArrayRef<const Value *> Operands,
160                  TTI::TargetCostKind CostKind);
161
162  // Hexagon specific decision to generate a lookup table.
163  bool shouldBuildLookupTables() const;
164};
165
166} // end namespace llvm
167#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H
168