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 final : 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
53public:
54 explicit HexagonTTIImpl(const HexagonTargetMachine *TM, const Function &F)
55 : BaseT(TM, F.getDataLayout()),
56 ST(*TM->getSubtargetImpl(F)), TLI(*ST.getTargetLowering()) {}
57
58 /// \name Scalar TTI Implementations
59 /// @{
60
61 TTI::PopcntSupportKind
62 getPopcntSupport(unsigned IntTyWidthInBit) const override;
63
64 // The Hexagon target can unroll loops with run-time trip counts.
65 void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
66 TTI::UnrollingPreferences &UP,
67 OptimizationRemarkEmitter *ORE) const override;
68
69 void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
70 TTI::PeelingPreferences &PP) const override;
71
72 /// Bias LSR towards creating post-increment opportunities.
73 TTI::AddressingModeKind
74 getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const override;
75
76 // L1 cache prefetch.
77 unsigned getPrefetchDistance() const override;
78 unsigned getCacheLineSize() const override;
79
80 /// @}
81
82 /// \name Vector TTI Implementations
83 /// @{
84
85 unsigned getNumberOfRegisters(unsigned ClassID) const override;
86 unsigned getMaxInterleaveFactor(ElementCount VF,
87 bool HasUnorderedReductions) const override;
88 TypeSize
89 getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override;
90 unsigned getMinVectorRegisterBitWidth() const override;
91 ElementCount getMinimumVF(unsigned ElemWidth, bool IsScalable) const override;
92
93 bool shouldMaximizeVectorBandwidth(
94 TargetTransformInfo::RegisterKind K) const override {
95 return true;
96 }
97 bool supportsEfficientVectorElementLoadStore() const override {
98 return false;
99 }
100 bool hasBranchDivergence(const Function *F = nullptr) const override {
101 return false;
102 }
103 bool enableAggressiveInterleaving(bool LoopHasReductions) const override {
104 return false;
105 }
106 bool prefersVectorizedAddressing() const override { return false; }
107 bool enableInterleavedAccessVectorization() const override { return true; }
108
109 InstructionCost getCallInstrCost(Function *F, Type *RetTy,
110 ArrayRef<Type *> Tys,
111 TTI::TargetCostKind CostKind) const override;
112 InstructionCost
113 getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
114 TTI::TargetCostKind CostKind) const override;
115 InstructionCost
116 getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *S,
117 TTI::TargetCostKind CostKind) const override;
118 InstructionCost getMemoryOpCost(
119 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
120 TTI::TargetCostKind CostKind,
121 TTI::OperandValueInfo OpInfo = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
122 const Instruction *I = nullptr) const override;
123 InstructionCost
124 getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
125 ArrayRef<int> Mask, TTI::TargetCostKind CostKind, int Index,
126 VectorType *SubTp, ArrayRef<const Value *> Args = {},
127 const Instruction *CxtI = nullptr) const override;
128 InstructionCost getInterleavedMemoryOpCost(
129 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
130 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
131 bool UseMaskForCond = false, bool UseMaskForGaps = false) const override;
132 InstructionCost getCmpSelInstrCost(
133 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
134 TTI::TargetCostKind CostKind,
135 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
136 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
137 const Instruction *I = nullptr) const override;
138 InstructionCost getArithmeticInstrCost(
139 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
140 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
141 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
142 ArrayRef<const Value *> Args = {},
143 const Instruction *CxtI = nullptr) const override;
144 InstructionCost
145 getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
146 TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
147 const Instruction *I = nullptr) const override;
148 using BaseT::getVectorInstrCost;
149 InstructionCost
150 getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind,
151 unsigned Index, const Value *Op0, const Value *Op1,
152 TTI::VectorInstrContext VIC =
153 TTI::VectorInstrContext::None) const override;
154
155 InstructionCost
156 getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
157 const Instruction *I = nullptr) const override {
158 return 1;
159 }
160 bool shouldExpandReduction(const IntrinsicInst *II) const override;
161 bool isLegalMaskedStore(Type *DataType, Align Alignment,
162 unsigned AddressSpace,
163 TTI::MaskKind MaskKind) const override;
164 bool isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddressSpace,
165 TTI::MaskKind MaskKind) const override;
166 bool isLegalMaskedGather(Type *Ty, Align Alignment) const override;
167 bool isLegalMaskedScatter(Type *Ty, Align Alignment) const override;
168 bool forceScalarizeMaskedGather(VectorType *VTy,
169 Align Alignment) const override;
170 bool forceScalarizeMaskedScatter(VectorType *VTy,
171 Align Alignment) const override;
172
173 InstructionCost getPartialReductionCost(
174 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
175 ElementCount VF, TTI::PartialReductionExtendKind OpAExtend,
176 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
177 TTI::TargetCostKind CostKind,
178 std::optional<FastMathFlags> FMF) const override {
179 return InstructionCost::getInvalid();
180 }
181
182 /// @}
183
184 InstructionCost
185 getInstructionCost(const User *U, ArrayRef<const Value *> Operands,
186 TTI::TargetCostKind CostKind) const override;
187
188 // Hexagon specific decision to generate a lookup table.
189 bool shouldBuildLookupTables() const override;
190};
191
192} // end namespace llvm
193#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H
194