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