1 //===-- AArch64TargetTransformInfo.h - AArch64 specific TTI -----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file a TargetTransformInfo::Concept conforming object specific to the
11 /// AArch64 target machine. It uses the target's detailed information to
12 /// provide more precise answers to certain TTI queries, while letting the
13 /// target independent and default TTI implementations handle the rest.
14 ///
15 //===----------------------------------------------------------------------===//
16 
17 #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64TARGETTRANSFORMINFO_H
18 #define LLVM_LIB_TARGET_AARCH64_AARCH64TARGETTRANSFORMINFO_H
19 
20 #include "AArch64.h"
21 #include "AArch64TargetMachine.h"
22 #include "llvm/Analysis/TargetTransformInfo.h"
23 #include "llvm/CodeGen/BasicTTIImpl.h"
24 #include "llvm/Target/TargetLowering.h"
25 #include <algorithm>
26 
27 namespace llvm {
28 
29 class AArch64TTIImpl : public BasicTTIImplBase<AArch64TTIImpl> {
30   typedef BasicTTIImplBase<AArch64TTIImpl> BaseT;
31   typedef TargetTransformInfo TTI;
32   friend BaseT;
33 
34   const AArch64TargetMachine *TM;
35   const AArch64Subtarget *ST;
36   const AArch64TargetLowering *TLI;
37 
38   /// Estimate the overhead of scalarizing an instruction. Insert and Extract
39   /// are set if the result needs to be inserted and/or extracted from vectors.
40   unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract);
41 
getST()42   const AArch64Subtarget *getST() const { return ST; }
getTLI()43   const AArch64TargetLowering *getTLI() const { return TLI; }
44 
45   enum MemIntrinsicType {
46     VECTOR_LDST_TWO_ELEMENTS,
47     VECTOR_LDST_THREE_ELEMENTS,
48     VECTOR_LDST_FOUR_ELEMENTS
49   };
50 
51 public:
AArch64TTIImpl(const AArch64TargetMachine * TM,Function & F)52   explicit AArch64TTIImpl(const AArch64TargetMachine *TM, Function &F)
53       : BaseT(TM), TM(TM), ST(TM->getSubtargetImpl(F)),
54         TLI(ST->getTargetLowering()) {}
55 
56   // Provide value semantics. MSVC requires that we spell all of these out.
AArch64TTIImpl(const AArch64TTIImpl & Arg)57   AArch64TTIImpl(const AArch64TTIImpl &Arg)
58       : BaseT(static_cast<const BaseT &>(Arg)), TM(Arg.TM), ST(Arg.ST),
59         TLI(Arg.TLI) {}
AArch64TTIImpl(AArch64TTIImpl && Arg)60   AArch64TTIImpl(AArch64TTIImpl &&Arg)
61       : BaseT(std::move(static_cast<BaseT &>(Arg))), TM(std::move(Arg.TM)),
62         ST(std::move(Arg.ST)), TLI(std::move(Arg.TLI)) {}
63   AArch64TTIImpl &operator=(const AArch64TTIImpl &RHS) {
64     BaseT::operator=(static_cast<const BaseT &>(RHS));
65     TM = RHS.TM;
66     ST = RHS.ST;
67     TLI = RHS.TLI;
68     return *this;
69   }
70   AArch64TTIImpl &operator=(AArch64TTIImpl &&RHS) {
71     BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
72     TM = std::move(RHS.TM);
73     ST = std::move(RHS.ST);
74     TLI = std::move(RHS.TLI);
75     return *this;
76   }
77 
78   /// \name Scalar TTI Implementations
79   /// @{
80 
81   using BaseT::getIntImmCost;
82   unsigned getIntImmCost(int64_t Val);
83   unsigned getIntImmCost(const APInt &Imm, Type *Ty);
84   unsigned getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm,
85                          Type *Ty);
86   unsigned getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
87                          Type *Ty);
88   TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth);
89 
90   /// @}
91 
92   /// \name Vector TTI Implementations
93   /// @{
94 
getNumberOfRegisters(bool Vector)95   unsigned getNumberOfRegisters(bool Vector) {
96     if (Vector) {
97       if (ST->hasNEON())
98         return 32;
99       return 0;
100     }
101     return 31;
102   }
103 
getRegisterBitWidth(bool Vector)104   unsigned getRegisterBitWidth(bool Vector) {
105     if (Vector) {
106       if (ST->hasNEON())
107         return 128;
108       return 0;
109     }
110     return 64;
111   }
112 
113   unsigned getMaxInterleaveFactor();
114 
115   unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src);
116 
117   unsigned getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index);
118 
119   unsigned getArithmeticInstrCost(
120       unsigned Opcode, Type *Ty,
121       TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue,
122       TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue,
123       TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None,
124       TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None);
125 
126   unsigned getAddressComputationCost(Type *Ty, bool IsComplex);
127 
128   unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy);
129 
130   unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
131                            unsigned AddressSpace);
132 
133   unsigned getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys);
134 
135   void getUnrollingPreferences(Loop *L, TTI::UnrollingPreferences &UP);
136 
137   Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
138                                            Type *ExpectedType);
139 
140   bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info);
141 
142   /// @}
143 };
144 
145 } // end namespace llvm
146 
147 #endif
148