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 
26 namespace llvm {
27 
28 class Loop;
29 class ScalarEvolution;
30 class User;
31 class Value;
32 
33 class HexagonTTIImpl : 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 isTypeForHVX(Type *VecTy) 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 
53 public:
54   explicit HexagonTTIImpl(const HexagonTargetMachine *TM, const Function &F)
55       : BaseT(TM, F.getParent()->getDataLayout()),
56         ST(*TM->getSubtargetImpl(F)), TLI(*ST.getTargetLowering()) {}
57 
58   /// \name Scalar TTI Implementations
59   /// @{
60 
61   TTI::PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const;
62 
63   // The Hexagon target can unroll loops with run-time trip counts.
64   void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
65                                TTI::UnrollingPreferences &UP);
66 
67   /// Bias LSR towards creating post-increment opportunities.
68   bool shouldFavorPostInc() const;
69 
70   // L1 cache prefetch.
71   unsigned getPrefetchDistance() const;
72   unsigned getCacheLineSize() const;
73 
74   /// @}
75 
76   /// \name Vector TTI Implementations
77   /// @{
78 
79   unsigned getNumberOfRegisters(bool vector) const;
80   unsigned getMaxInterleaveFactor(unsigned VF);
81   unsigned getRegisterBitWidth(bool Vector) const;
82   unsigned getMinVectorRegisterBitWidth() const;
83   unsigned getMinimumVF(unsigned ElemWidth) const;
84 
85   bool shouldMaximizeVectorBandwidth(bool OptSize) const {
86     return true;
87   }
88   bool supportsEfficientVectorElementLoadStore() {
89     return false;
90   }
91   bool hasBranchDivergence() {
92     return false;
93   }
94   bool enableAggressiveInterleaving(bool LoopHasReductions) {
95     return false;
96   }
97   bool prefersVectorizedAddressing() {
98     return false;
99   }
100   bool enableInterleavedAccessVectorization() {
101     return true;
102   }
103 
104   unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract);
105   unsigned getOperandsScalarizationOverhead(ArrayRef<const Value*> Args,
106             unsigned VF);
107   unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type*> Tys);
108   unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
109             ArrayRef<Value*> Args, FastMathFlags FMF, unsigned VF);
110   unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
111             ArrayRef<Type*> Tys, FastMathFlags FMF,
112             unsigned ScalarizationCostPassed = UINT_MAX);
113   unsigned getAddressComputationCost(Type *Tp, ScalarEvolution *SE,
114             const SCEV *S);
115   unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
116             unsigned AddressSpace, const Instruction *I = nullptr);
117   unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
118             unsigned AddressSpace);
119   unsigned getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index,
120             Type *SubTp);
121   unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy, Value *Ptr,
122             bool VariableMask, unsigned Alignment);
123   unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
124             unsigned Factor, ArrayRef<unsigned> Indices, unsigned Alignment,
125             unsigned AddressSpace, bool UseMaskForCond = false,
126             bool UseMaskForGaps = false);
127   unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
128             const Instruction *I);
129   unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
130             TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue,
131             TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue,
132             TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None,
133             TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None,
134             ArrayRef<const Value *> Args = ArrayRef<const Value *>());
135   unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
136             const Instruction *I = nullptr);
137   unsigned getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index);
138 
139   unsigned getCFInstrCost(unsigned Opcode) {
140     return 1;
141   }
142 
143   /// @}
144 
145   int getUserCost(const User *U, ArrayRef<const Value *> Operands);
146 
147   // Hexagon specific decision to generate a lookup table.
148   bool shouldBuildLookupTables() const;
149 };
150 
151 } // end namespace llvm
152 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H
153