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 *CxtI = nullptr) const override;
132 InstructionCost getInterleavedMemoryOpCost(
133 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
134 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
135 bool UseMaskForCond = false, bool UseMaskForGaps = false) const override;
136 InstructionCost getCmpSelInstrCost(
137 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
138 TTI::TargetCostKind CostKind,
139 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
140 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
141 const Instruction *I = nullptr) const override;
142 InstructionCost getArithmeticInstrCost(
143 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
144 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
145 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
146 ArrayRef<const Value *> Args = {},
147 const Instruction *CxtI = nullptr) const override;
148 InstructionCost
149 getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
150 TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
151 const Instruction *I = nullptr) const override;
152 using BaseT::getVectorInstrCost;
153 InstructionCost
154 getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind,
155 unsigned Index, const Value *Op0, const Value *Op1,
156 TTI::VectorInstrContext VIC =
157 TTI::VectorInstrContext::None) const override;
158
159 InstructionCost
160 getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
161 const Instruction *I = nullptr) const override {
162 return 1;
163 }
164 bool shouldExpandReduction(const IntrinsicInst *II) const override;
165 bool isLegalMaskedStore(Type *DataType, Align Alignment,
166 unsigned AddressSpace,
167 TTI::MaskKind MaskKind) const override;
168 bool isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddressSpace,
169 TTI::MaskKind MaskKind) const override;
170 bool isLegalMaskedGather(Type *Ty, Align Alignment) const override;
171 bool isLegalMaskedScatter(Type *Ty, Align Alignment) const override;
172 bool forceScalarizeMaskedGather(VectorType *VTy,
173 Align Alignment) const override;
174 bool forceScalarizeMaskedScatter(VectorType *VTy,
175 Align Alignment) const override;
176
177 InstructionCost getPartialReductionCost(
178 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
179 ElementCount VF, TTI::PartialReductionExtendKind OpAExtend,
180 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
181 TTI::TargetCostKind CostKind,
182 std::optional<FastMathFlags> FMF) const override {
183 return InstructionCost::getInvalid();
184 }
185
186 /// @}
187
188 InstructionCost
189 getInstructionCost(const User *U, ArrayRef<const Value *> Operands,
190 TTI::TargetCostKind CostKind) const override;
191
192 // Hexagon specific decision to generate a lookup table.
193 bool shouldBuildLookupTables() const override;
194
195 bool areInlineCompatible(const Function *Caller,
196 const Function *Callee) const override;
197};
198
199} // end namespace llvm
200#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H
201