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) const override;
87 TypeSize
88 getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override;
89 unsigned getMinVectorRegisterBitWidth() const override;
90 ElementCount getMinimumVF(unsigned ElemWidth, bool IsScalable) const override;
91
92 bool shouldMaximizeVectorBandwidth(
93 TargetTransformInfo::RegisterKind K) const override {
94 return true;
95 }
96 bool supportsEfficientVectorElementLoadStore() const override {
97 return false;
98 }
99 bool hasBranchDivergence(const Function *F = nullptr) const override {
100 return false;
101 }
102 bool enableAggressiveInterleaving(bool LoopHasReductions) const override {
103 return false;
104 }
105 bool prefersVectorizedAddressing() const override { return false; }
106 bool enableInterleavedAccessVectorization() const override { return true; }
107
108 InstructionCost getCallInstrCost(Function *F, Type *RetTy,
109 ArrayRef<Type *> Tys,
110 TTI::TargetCostKind CostKind) const override;
111 InstructionCost
112 getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
113 TTI::TargetCostKind CostKind) const override;
114 InstructionCost
115 getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *S,
116 TTI::TargetCostKind CostKind) const override;
117 InstructionCost getMemoryOpCost(
118 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
119 TTI::TargetCostKind CostKind,
120 TTI::OperandValueInfo OpInfo = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
121 const Instruction *I = nullptr) const override;
122 InstructionCost
123 getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
124 ArrayRef<int> Mask, TTI::TargetCostKind CostKind, int Index,
125 VectorType *SubTp, ArrayRef<const Value *> Args = {},
126 const Instruction *CxtI = nullptr) const override;
127 InstructionCost getInterleavedMemoryOpCost(
128 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
129 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
130 bool UseMaskForCond = false, bool UseMaskForGaps = false) const override;
131 InstructionCost getCmpSelInstrCost(
132 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
133 TTI::TargetCostKind CostKind,
134 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
135 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
136 const Instruction *I = nullptr) const override;
137 InstructionCost getArithmeticInstrCost(
138 unsigned Opcode, Type *Ty, 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 ArrayRef<const Value *> Args = {},
142 const Instruction *CxtI = nullptr) const override;
143 InstructionCost
144 getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
145 TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
146 const Instruction *I = nullptr) const override;
147 using BaseT::getVectorInstrCost;
148 InstructionCost
149 getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind,
150 unsigned Index, const Value *Op0, const Value *Op1,
151 TTI::VectorInstrContext VIC =
152 TTI::VectorInstrContext::None) const override;
153
154 InstructionCost
155 getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
156 const Instruction *I = nullptr) const override {
157 return 1;
158 }
159
160 bool isLegalMaskedStore(Type *DataType, Align Alignment,
161 unsigned AddressSpace,
162 TTI::MaskKind MaskKind) const override;
163 bool isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddressSpace,
164 TTI::MaskKind MaskKind) const override;
165 bool isLegalMaskedGather(Type *Ty, Align Alignment) const override;
166 bool isLegalMaskedScatter(Type *Ty, Align Alignment) const override;
167 bool forceScalarizeMaskedGather(VectorType *VTy,
168 Align Alignment) const override;
169 bool forceScalarizeMaskedScatter(VectorType *VTy,
170 Align Alignment) const override;
171
172 /// @}
173
174 InstructionCost
175 getInstructionCost(const User *U, ArrayRef<const Value *> Operands,
176 TTI::TargetCostKind CostKind) const override;
177
178 // Hexagon specific decision to generate a lookup table.
179 bool shouldBuildLookupTables() const override;
180};
181
182} // end namespace llvm
183#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H
184