/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/ARM/ARMTargetTransformInfo.h
Line | Count | Source (jump to first uncovered line) |
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 | | |
84 | 3.75k | const ARMSubtarget *getST() const { return ST; } |
85 | 557k | const ARMTargetLowering *getTLI() const { return TLI; } |
86 | | |
87 | | public: |
88 | | explicit ARMTTIImpl(const ARMBaseTargetMachine *TM, const Function &F) |
89 | | : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)), |
90 | 269k | TLI(ST->getTargetLowering()) {} |
91 | | |
92 | | bool areInlineCompatible(const Function *Caller, |
93 | | const Function *Callee) const; |
94 | | |
95 | 187 | 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. |
100 | 0 | bool isFPVectorizationPotentiallyUnsafe() { |
101 | 0 | return !ST->isTargetDarwin(); |
102 | 0 | } |
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 | | |
120 | 80.8k | unsigned getNumberOfRegisters(bool Vector) { |
121 | 80.8k | if (Vector80.8k ) { |
122 | 10.7k | if (ST->hasNEON()) |
123 | 8.94k | return 16; |
124 | 1.80k | return 0; |
125 | 10.7k | } |
126 | 80.8k | |
127 | 70.1k | if (70.1k ST->isThumb1Only()70.1k ) |
128 | 663 | return 8; |
129 | 69.4k | return 13; |
130 | 80.8k | } |
131 | | |
132 | 4.59k | unsigned getRegisterBitWidth(bool Vector) const { |
133 | 4.59k | if (Vector4.59k ) { |
134 | 4.59k | if (ST->hasNEON()) |
135 | 4.59k | return 128; |
136 | 0 | return 0; |
137 | 4.59k | } |
138 | 4.59k | |
139 | 0 | return 32; |
140 | 4.59k | } |
141 | | |
142 | 1.09k | unsigned getMaxInterleaveFactor(unsigned VF) { |
143 | 1.09k | return ST->getMaxInterleaveFactor(); |
144 | 1.09k | } |
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 getFPOpCost(Type *Ty); |
160 | | |
161 | | int getArithmeticInstrCost( |
162 | | unsigned Opcode, Type *Ty, |
163 | | TTI::OperandValueKind Op1Info = TTI::OK_AnyValue, |
164 | | TTI::OperandValueKind Op2Info = TTI::OK_AnyValue, |
165 | | TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None, |
166 | | TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None, |
167 | | ArrayRef<const Value *> Args = ArrayRef<const Value *>()); |
168 | | |
169 | | int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, |
170 | | unsigned AddressSpace, const Instruction *I = nullptr); |
171 | | |
172 | | int getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, |
173 | | ArrayRef<unsigned> Indices, unsigned Alignment, |
174 | | unsigned AddressSpace); |
175 | | |
176 | | void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, |
177 | | TTI::UnrollingPreferences &UP); |
178 | | |
179 | 6.95k | bool shouldBuildLookupTablesForConstant(Constant *C) const { |
180 | 6.95k | // In the ROPI and RWPI relocation models we can't have pointers to global |
181 | 6.95k | // variables or functions in constant data, so don't convert switches to |
182 | 6.95k | // lookup tables if any of the values would need relocation. |
183 | 6.95k | if (ST->isROPI() || 6.95k ST->isRWPI()6.92k ) |
184 | 54 | return !C->needsRelocation(); |
185 | 6.95k | |
186 | 6.90k | return true; |
187 | 6.95k | } |
188 | | /// @} |
189 | | }; |
190 | | |
191 | | } // end namespace llvm |
192 | | |
193 | | #endif // LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H |