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 getAddressComputationCost(Type *Tp, ScalarEvolution *SE,
115 const SCEV *S) const override;
116 InstructionCost getMemoryOpCost(
117 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
118 TTI::TargetCostKind CostKind,
119 TTI::OperandValueInfo OpInfo = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
120 const Instruction *I = nullptr) const override;
121 InstructionCost
122 getMaskedMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
123 unsigned AddressSpace,
124 TTI::TargetCostKind CostKind) const override;
125 InstructionCost
126 getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
127 ArrayRef<int> Mask, TTI::TargetCostKind CostKind, int Index,
128 VectorType *SubTp, ArrayRef<const Value *> Args = {},
129 const Instruction *CxtI = nullptr) const override;
130 InstructionCost getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
131 const Value *Ptr, bool VariableMask,
132 Align Alignment,
133 TTI::TargetCostKind CostKind,
134 const Instruction *I) const override;
135 InstructionCost getInterleavedMemoryOpCost(
136 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
137 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
138 bool UseMaskForCond = false, bool UseMaskForGaps = false) const override;
139 InstructionCost getCmpSelInstrCost(
140 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
141 TTI::TargetCostKind CostKind,
142 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
143 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
144 const Instruction *I = nullptr) const override;
145 InstructionCost getArithmeticInstrCost(
146 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
147 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
148 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
149 ArrayRef<const Value *> Args = {},
150 const Instruction *CxtI = nullptr) const override;
151 InstructionCost
152 getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
153 TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
154 const Instruction *I = nullptr) const override;
155 using BaseT::getVectorInstrCost;
156 InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val,
157 TTI::TargetCostKind CostKind,
158 unsigned Index, const Value *Op0,
159 const Value *Op1) const override;
160
161 InstructionCost
162 getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
163 const Instruction *I = nullptr) const override {
164 return 1;
165 }
166
167 bool isLegalMaskedStore(Type *DataType, Align Alignment,
168 unsigned AddressSpace) const override;
169 bool isLegalMaskedLoad(Type *DataType, Align Alignment,
170 unsigned AddressSpace) 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