• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- ARMTargetTransformInfo.h - ARM 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 //
10 /// \file
11 /// This file a TargetTransformInfo::Concept conforming object specific to the
12 /// ARM target machine. It uses the target's detailed information to
13 /// provide more precise answers to certain TTI queries, while letting the
14 /// target independent and default TTI implementations handle the rest.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H
19 #define LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H
20 
21 #include "ARM.h"
22 #include "ARMSubtarget.h"
23 #include "ARMTargetMachine.h"
24 #include "llvm/ADT/ArrayRef.h"
25 #include "llvm/Analysis/TargetTransformInfo.h"
26 #include "llvm/CodeGen/BasicTTIImpl.h"
27 #include "llvm/IR/Constant.h"
28 #include "llvm/IR/Function.h"
29 #include "llvm/MC/SubtargetFeature.h"
30 
31 namespace llvm {
32 
33 class APInt;
34 class ARMTargetLowering;
35 class Instruction;
36 class Loop;
37 class SCEV;
38 class ScalarEvolution;
39 class Type;
40 class Value;
41 
42 class ARMTTIImpl : public BasicTTIImplBase<ARMTTIImpl> {
43   using BaseT = BasicTTIImplBase<ARMTTIImpl>;
44   using TTI = TargetTransformInfo;
45 
46   friend BaseT;
47 
48   const ARMSubtarget *ST;
49   const ARMTargetLowering *TLI;
50 
51   // Currently the following features are excluded from InlineFeatureWhitelist.
52   // ModeThumb, FeatureNoARM, ModeSoftFloat, FeatureVFPOnlySP, FeatureD16
53   // Depending on whether they are set or unset, different
54   // instructions/registers are available. For example, inlining a callee with
55   // -thumb-mode in a caller with +thumb-mode, may cause the assembler to
56   // fail if the callee uses ARM only instructions, e.g. in inline asm.
57   const FeatureBitset InlineFeatureWhitelist = {
58       ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureNEON, ARM::FeatureThumb2,
59       ARM::FeatureFP16, ARM::FeatureVFP4, ARM::FeatureFPARMv8,
60       ARM::FeatureFullFP16, ARM::FeatureHWDivThumb,
61       ARM::FeatureHWDivARM, ARM::FeatureDB, ARM::FeatureV7Clrex,
62       ARM::FeatureAcquireRelease, ARM::FeatureSlowFPBrcc,
63       ARM::FeaturePerfMon, ARM::FeatureTrustZone, ARM::Feature8MSecExt,
64       ARM::FeatureCrypto, ARM::FeatureCRC, ARM::FeatureRAS,
65       ARM::FeatureFPAO, ARM::FeatureFuseAES, ARM::FeatureZCZeroing,
66       ARM::FeatureProfUnpredicate, ARM::FeatureSlowVGETLNi32,
67       ARM::FeatureSlowVDUP32, ARM::FeaturePreferVMOVSR,
68       ARM::FeaturePrefISHSTBarrier, ARM::FeatureMuxedUnits,
69       ARM::FeatureSlowOddRegister, ARM::FeatureSlowLoadDSubreg,
70       ARM::FeatureDontWidenVMOVS, ARM::FeatureExpandMLx,
71       ARM::FeatureHasVMLxHazards, ARM::FeatureNEONForFPMovs,
72       ARM::FeatureNEONForFP, ARM::FeatureCheckVLDnAlign,
73       ARM::FeatureHasSlowFPVMLx, ARM::FeatureVMLxForwarding,
74       ARM::FeaturePref32BitThumb, ARM::FeatureAvoidPartialCPSR,
75       ARM::FeatureCheapPredicableCPSR, ARM::FeatureAvoidMOVsShOp,
76       ARM::FeatureHasRetAddrStack, ARM::FeatureHasNoBranchPredictor,
77       ARM::FeatureDSP, ARM::FeatureMP, ARM::FeatureVirtualization,
78       ARM::FeatureMClass, ARM::FeatureRClass, ARM::FeatureAClass,
79       ARM::FeatureNaClTrap, ARM::FeatureStrictAlign, ARM::FeatureLongCalls,
80       ARM::FeatureExecuteOnly, ARM::FeatureReserveR9, ARM::FeatureNoMovt,
81       ARM::FeatureNoNegativeImmediates
82   };
83 
getST()84   const ARMSubtarget *getST() const { return ST; }
getTLI()85   const ARMTargetLowering *getTLI() const { return TLI; }
86 
87 public:
ARMTTIImpl(const ARMBaseTargetMachine * TM,const Function & F)88   explicit ARMTTIImpl(const ARMBaseTargetMachine *TM, const Function &F)
89       : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)),
90         TLI(ST->getTargetLowering()) {}
91 
92   bool areInlineCompatible(const Function *Caller,
93                            const Function *Callee) const;
94 
enableInterleavedAccessVectorization()95   bool enableInterleavedAccessVectorization() { return true; }
96 
97   /// Floating-point computation using ARMv8 AArch32 Advanced
98   /// SIMD instructions remains unchanged from ARMv7. Only AArch64 SIMD
99   /// is IEEE-754 compliant, but it's not covered in this target.
isFPVectorizationPotentiallyUnsafe()100   bool isFPVectorizationPotentiallyUnsafe() {
101     return !ST->isTargetDarwin();
102   }
103 
104   /// \name Scalar TTI Implementations
105   /// @{
106 
107   int getIntImmCodeSizeCost(unsigned Opcode, unsigned Idx, const APInt &Imm,
108                             Type *Ty);
109 
110   using BaseT::getIntImmCost;
111   int getIntImmCost(const APInt &Imm, Type *Ty);
112 
113   int getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty);
114 
115   /// @}
116 
117   /// \name Vector TTI Implementations
118   /// @{
119 
getNumberOfRegisters(bool Vector)120   unsigned getNumberOfRegisters(bool Vector) {
121     if (Vector) {
122       if (ST->hasNEON())
123         return 16;
124       return 0;
125     }
126 
127     if (ST->isThumb1Only())
128       return 8;
129     return 13;
130   }
131 
getRegisterBitWidth(bool Vector)132   unsigned getRegisterBitWidth(bool Vector) const {
133     if (Vector) {
134       if (ST->hasNEON())
135         return 128;
136       return 0;
137     }
138 
139     return 32;
140   }
141 
getMaxInterleaveFactor(unsigned VF)142   unsigned getMaxInterleaveFactor(unsigned VF) {
143     return ST->getMaxInterleaveFactor();
144   }
145 
146   int getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index, Type *SubTp);
147 
148   int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
149                        const Instruction *I = nullptr);
150 
151   int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
152                          const Instruction *I = nullptr);
153 
154   int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index);
155 
156   int getAddressComputationCost(Type *Val, ScalarEvolution *SE,
157                                 const SCEV *Ptr);
158 
159   int getArithmeticInstrCost(
160       unsigned Opcode, Type *Ty,
161       TTI::OperandValueKind Op1Info = TTI::OK_AnyValue,
162       TTI::OperandValueKind Op2Info = TTI::OK_AnyValue,
163       TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None,
164       TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None,
165       ArrayRef<const Value *> Args = ArrayRef<const Value *>());
166 
167   int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
168                       unsigned AddressSpace, const Instruction *I = nullptr);
169 
170   int getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor,
171                                  ArrayRef<unsigned> Indices, unsigned Alignment,
172                                  unsigned AddressSpace);
173 
174   void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
175                                TTI::UnrollingPreferences &UP);
176 
shouldBuildLookupTablesForConstant(Constant * C)177   bool shouldBuildLookupTablesForConstant(Constant *C) const {
178     // In the ROPI and RWPI relocation models we can't have pointers to global
179     // variables or functions in constant data, so don't convert switches to
180     // lookup tables if any of the values would need relocation.
181     if (ST->isROPI() || ST->isRWPI())
182       return !C->needsRelocation();
183 
184     return true;
185   }
186   /// @}
187 };
188 
189 } // end namespace llvm
190 
191 #endif // LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H
192