| Eugene Zelenko | 076468c | 2017-09-20 21:35:51 +0000 | [diff] [blame] | 1 | //===- ARMTargetTransformInfo.h - ARM specific TTI --------------*- C++ -*-===// | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 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 | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
| Eugene Zelenko | 076468c | 2017-09-20 21:35:51 +0000 | [diff] [blame] | 8 | // | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 9 | /// \file | 
|  | 10 | /// This file a TargetTransformInfo::Concept conforming object specific to the | 
|  | 11 | /// ARM 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. | 
| Eugene Zelenko | 076468c | 2017-09-20 21:35:51 +0000 | [diff] [blame] | 14 | // | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 15 | //===----------------------------------------------------------------------===// | 
|  | 16 |  | 
|  | 17 | #ifndef LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H | 
|  | 18 | #define LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H | 
|  | 19 |  | 
|  | 20 | #include "ARM.h" | 
| Eugene Zelenko | 076468c | 2017-09-20 21:35:51 +0000 | [diff] [blame] | 21 | #include "ARMSubtarget.h" | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 22 | #include "ARMTargetMachine.h" | 
| Eugene Zelenko | 076468c | 2017-09-20 21:35:51 +0000 | [diff] [blame] | 23 | #include "llvm/ADT/ArrayRef.h" | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 24 | #include "llvm/Analysis/TargetTransformInfo.h" | 
|  | 25 | #include "llvm/CodeGen/BasicTTIImpl.h" | 
| Eugene Zelenko | 076468c | 2017-09-20 21:35:51 +0000 | [diff] [blame] | 26 | #include "llvm/IR/Constant.h" | 
|  | 27 | #include "llvm/IR/Function.h" | 
|  | 28 | #include "llvm/MC/SubtargetFeature.h" | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 29 |  | 
|  | 30 | namespace llvm { | 
|  | 31 |  | 
| Eugene Zelenko | 076468c | 2017-09-20 21:35:51 +0000 | [diff] [blame] | 32 | class APInt; | 
|  | 33 | class ARMTargetLowering; | 
|  | 34 | class Instruction; | 
|  | 35 | class Loop; | 
|  | 36 | class SCEV; | 
|  | 37 | class ScalarEvolution; | 
|  | 38 | class Type; | 
|  | 39 | class Value; | 
|  | 40 |  | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 41 | class ARMTTIImpl : public BasicTTIImplBase<ARMTTIImpl> { | 
| Eugene Zelenko | 076468c | 2017-09-20 21:35:51 +0000 | [diff] [blame] | 42 | using BaseT = BasicTTIImplBase<ARMTTIImpl>; | 
|  | 43 | using TTI = TargetTransformInfo; | 
|  | 44 |  | 
| Chandler Carruth | c340ca8 | 2015-02-01 14:01:15 +0000 | [diff] [blame] | 45 | friend BaseT; | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 46 |  | 
|  | 47 | const ARMSubtarget *ST; | 
|  | 48 | const ARMTargetLowering *TLI; | 
|  | 49 |  | 
| Florian Hahn | 4adcfcf | 2017-07-13 08:26:17 +0000 | [diff] [blame] | 50 | // Currently the following features are excluded from InlineFeatureWhitelist. | 
| Simon Tatham | 760df47 | 2019-05-28 16:13:20 +0000 | [diff] [blame] | 51 | // ModeThumb, FeatureNoARM, ModeSoftFloat, FeatureFP64, FeatureD32 | 
| Florian Hahn | 4adcfcf | 2017-07-13 08:26:17 +0000 | [diff] [blame] | 52 | // Depending on whether they are set or unset, different | 
|  | 53 | // instructions/registers are available. For example, inlining a callee with | 
|  | 54 | // -thumb-mode in a caller with +thumb-mode, may cause the assembler to | 
|  | 55 | // fail if the callee uses ARM only instructions, e.g. in inline asm. | 
|  | 56 | const FeatureBitset InlineFeatureWhitelist = { | 
|  | 57 | ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureNEON, ARM::FeatureThumb2, | 
|  | 58 | ARM::FeatureFP16, ARM::FeatureVFP4, ARM::FeatureFPARMv8, | 
| Bernard Ogden | b828bb2 | 2018-08-17 11:29:49 +0000 | [diff] [blame] | 59 | ARM::FeatureFullFP16, ARM::FeatureFP16FML, ARM::FeatureHWDivThumb, | 
| Florian Hahn | 4adcfcf | 2017-07-13 08:26:17 +0000 | [diff] [blame] | 60 | ARM::FeatureHWDivARM, ARM::FeatureDB, ARM::FeatureV7Clrex, | 
|  | 61 | ARM::FeatureAcquireRelease, ARM::FeatureSlowFPBrcc, | 
|  | 62 | ARM::FeaturePerfMon, ARM::FeatureTrustZone, ARM::Feature8MSecExt, | 
|  | 63 | ARM::FeatureCrypto, ARM::FeatureCRC, ARM::FeatureRAS, | 
|  | 64 | ARM::FeatureFPAO, ARM::FeatureFuseAES, ARM::FeatureZCZeroing, | 
|  | 65 | ARM::FeatureProfUnpredicate, ARM::FeatureSlowVGETLNi32, | 
|  | 66 | ARM::FeatureSlowVDUP32, ARM::FeaturePreferVMOVSR, | 
|  | 67 | ARM::FeaturePrefISHSTBarrier, ARM::FeatureMuxedUnits, | 
|  | 68 | ARM::FeatureSlowOddRegister, ARM::FeatureSlowLoadDSubreg, | 
|  | 69 | ARM::FeatureDontWidenVMOVS, ARM::FeatureExpandMLx, | 
|  | 70 | ARM::FeatureHasVMLxHazards, ARM::FeatureNEONForFPMovs, | 
|  | 71 | ARM::FeatureNEONForFP, ARM::FeatureCheckVLDnAlign, | 
|  | 72 | ARM::FeatureHasSlowFPVMLx, ARM::FeatureVMLxForwarding, | 
|  | 73 | ARM::FeaturePref32BitThumb, ARM::FeatureAvoidPartialCPSR, | 
|  | 74 | ARM::FeatureCheapPredicableCPSR, ARM::FeatureAvoidMOVsShOp, | 
|  | 75 | ARM::FeatureHasRetAddrStack, ARM::FeatureHasNoBranchPredictor, | 
|  | 76 | ARM::FeatureDSP, ARM::FeatureMP, ARM::FeatureVirtualization, | 
|  | 77 | ARM::FeatureMClass, ARM::FeatureRClass, ARM::FeatureAClass, | 
|  | 78 | ARM::FeatureNaClTrap, ARM::FeatureStrictAlign, ARM::FeatureLongCalls, | 
|  | 79 | ARM::FeatureExecuteOnly, ARM::FeatureReserveR9, ARM::FeatureNoMovt, | 
|  | 80 | ARM::FeatureNoNegativeImmediates | 
|  | 81 | }; | 
|  | 82 |  | 
| Chandler Carruth | c956ab66 | 2015-02-01 14:22:17 +0000 | [diff] [blame] | 83 | const ARMSubtarget *getST() const { return ST; } | 
| Chandler Carruth | c340ca8 | 2015-02-01 14:01:15 +0000 | [diff] [blame] | 84 | const ARMTargetLowering *getTLI() const { return TLI; } | 
|  | 85 |  | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 86 | public: | 
| Eric Christopher | a4e5d3c | 2015-09-16 23:38:13 +0000 | [diff] [blame] | 87 | explicit ARMTTIImpl(const ARMBaseTargetMachine *TM, const Function &F) | 
| Mehdi Amini | 5010ebf | 2015-07-09 02:08:42 +0000 | [diff] [blame] | 88 | : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)), | 
|  | 89 | TLI(ST->getTargetLowering()) {} | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 90 |  | 
| Florian Hahn | 4adcfcf | 2017-07-13 08:26:17 +0000 | [diff] [blame] | 91 | bool areInlineCompatible(const Function *Caller, | 
|  | 92 | const Function *Callee) const; | 
|  | 93 |  | 
| Silviu Baranga | e748c9e | 2015-09-01 11:19:15 +0000 | [diff] [blame] | 94 | bool enableInterleavedAccessVectorization() { return true; } | 
|  | 95 |  | 
| Sam Parker | 67756c0 | 2019-02-07 13:32:54 +0000 | [diff] [blame] | 96 | bool shouldFavorBackedgeIndex(const Loop *L) const { | 
| Evandro Menezes | 85bd397 | 2019-04-04 22:40:06 +0000 | [diff] [blame] | 97 | if (L->getHeader()->getParent()->hasOptSize()) | 
| Sam Parker | 67756c0 | 2019-02-07 13:32:54 +0000 | [diff] [blame] | 98 | return false; | 
|  | 99 | return ST->isMClass() && ST->isThumb2() && L->getNumBlocks() == 1; | 
|  | 100 | } | 
|  | 101 |  | 
| Renato Golin | 4b18a51 | 2016-04-18 12:06:47 +0000 | [diff] [blame] | 102 | /// Floating-point computation using ARMv8 AArch32 Advanced | 
|  | 103 | /// SIMD instructions remains unchanged from ARMv7. Only AArch64 SIMD | 
|  | 104 | /// is IEEE-754 compliant, but it's not covered in this target. | 
| Renato Golin | 5cb666a | 2016-04-14 20:42:18 +0000 | [diff] [blame] | 105 | bool isFPVectorizationPotentiallyUnsafe() { | 
| Renato Golin | 4b18a51 | 2016-04-18 12:06:47 +0000 | [diff] [blame] | 106 | return !ST->isTargetDarwin(); | 
| Renato Golin | 5cb666a | 2016-04-14 20:42:18 +0000 | [diff] [blame] | 107 | } | 
|  | 108 |  | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 109 | /// \name Scalar TTI Implementations | 
|  | 110 | /// @{ | 
|  | 111 |  | 
| Sjoerd Meijer | 38c2cd0 | 2016-07-14 07:44:20 +0000 | [diff] [blame] | 112 | int getIntImmCodeSizeCost(unsigned Opcode, unsigned Idx, const APInt &Imm, | 
|  | 113 | Type *Ty); | 
|  | 114 |  | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 115 | using BaseT::getIntImmCost; | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 116 | int getIntImmCost(const APInt &Imm, Type *Ty); | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 117 |  | 
| Tim Northover | 903f81b | 2016-04-15 18:17:18 +0000 | [diff] [blame] | 118 | int getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty); | 
| Tim Northover | 5c02f9a | 2016-04-13 23:08:27 +0000 | [diff] [blame] | 119 |  | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 120 | /// @} | 
|  | 121 |  | 
|  | 122 | /// \name Vector TTI Implementations | 
|  | 123 | /// @{ | 
|  | 124 |  | 
|  | 125 | unsigned getNumberOfRegisters(bool Vector) { | 
|  | 126 | if (Vector) { | 
|  | 127 | if (ST->hasNEON()) | 
|  | 128 | return 16; | 
|  | 129 | return 0; | 
|  | 130 | } | 
|  | 131 |  | 
|  | 132 | if (ST->isThumb1Only()) | 
|  | 133 | return 8; | 
|  | 134 | return 13; | 
|  | 135 | } | 
|  | 136 |  | 
| Daniel Neilson | c0112ae | 2017-06-12 14:22:21 +0000 | [diff] [blame] | 137 | unsigned getRegisterBitWidth(bool Vector) const { | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 138 | if (Vector) { | 
|  | 139 | if (ST->hasNEON()) | 
|  | 140 | return 128; | 
|  | 141 | return 0; | 
|  | 142 | } | 
|  | 143 |  | 
|  | 144 | return 32; | 
|  | 145 | } | 
|  | 146 |  | 
| Wei Mi | 062c744 | 2015-05-06 17:12:25 +0000 | [diff] [blame] | 147 | unsigned getMaxInterleaveFactor(unsigned VF) { | 
| Diana Picus | 92423ce | 2016-06-27 09:08:23 +0000 | [diff] [blame] | 148 | return ST->getMaxInterleaveFactor(); | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 149 | } | 
|  | 150 |  | 
| Sjoerd Meijer | ea31ddb | 2019-04-30 10:28:50 +0000 | [diff] [blame] | 151 | int getMemcpyCost(const Instruction *I); | 
|  | 152 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 153 | int getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index, Type *SubTp); | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 154 |  | 
| Jonas Paulsson | fccc7d6 | 2017-04-12 11:49:08 +0000 | [diff] [blame] | 155 | int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, | 
|  | 156 | const Instruction *I = nullptr); | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 157 |  | 
| Jonas Paulsson | fccc7d6 | 2017-04-12 11:49:08 +0000 | [diff] [blame] | 158 | int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, | 
|  | 159 | const Instruction *I = nullptr); | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 160 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 161 | int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index); | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 162 |  | 
| Fangrui Song | f78650a | 2018-07-30 19:41:25 +0000 | [diff] [blame] | 163 | int getAddressComputationCost(Type *Val, ScalarEvolution *SE, | 
| Mohammed Agabaria | 23599ba | 2017-01-05 14:03:41 +0000 | [diff] [blame] | 164 | const SCEV *Ptr); | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 165 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 166 | int getArithmeticInstrCost( | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 167 | unsigned Opcode, Type *Ty, | 
|  | 168 | TTI::OperandValueKind Op1Info = TTI::OK_AnyValue, | 
|  | 169 | TTI::OperandValueKind Op2Info = TTI::OK_AnyValue, | 
|  | 170 | TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None, | 
| Mohammed Agabaria | 2c96c43 | 2017-01-11 08:23:37 +0000 | [diff] [blame] | 171 | TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None, | 
|  | 172 | ArrayRef<const Value *> Args = ArrayRef<const Value *>()); | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 173 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 174 | int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, | 
| Jonas Paulsson | fccc7d6 | 2017-04-12 11:49:08 +0000 | [diff] [blame] | 175 | unsigned AddressSpace, const Instruction *I = nullptr); | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 176 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 177 | int getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, | 
|  | 178 | ArrayRef<unsigned> Indices, unsigned Alignment, | 
| Dorit Nuzman | 34da6dd | 2018-10-31 09:57:56 +0000 | [diff] [blame] | 179 | unsigned AddressSpace, | 
|  | 180 | bool UseMaskForCond = false, | 
|  | 181 | bool UseMaskForGaps = false); | 
| Oliver Stannard | 4df1cc0 | 2016-10-07 08:48:24 +0000 | [diff] [blame] | 182 |  | 
| Sam Parker | 19a08e4 | 2017-07-25 08:51:30 +0000 | [diff] [blame] | 183 | void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, | 
|  | 184 | TTI::UnrollingPreferences &UP); | 
|  | 185 |  | 
| Oliver Stannard | 4df1cc0 | 2016-10-07 08:48:24 +0000 | [diff] [blame] | 186 | bool shouldBuildLookupTablesForConstant(Constant *C) const { | 
|  | 187 | // In the ROPI and RWPI relocation models we can't have pointers to global | 
|  | 188 | // variables or functions in constant data, so don't convert switches to | 
|  | 189 | // lookup tables if any of the values would need relocation. | 
|  | 190 | if (ST->isROPI() || ST->isRWPI()) | 
|  | 191 | return !C->needsRelocation(); | 
|  | 192 |  | 
|  | 193 | return true; | 
|  | 194 | } | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 195 | /// @} | 
|  | 196 | }; | 
|  | 197 |  | 
|  | 198 | } // end namespace llvm | 
|  | 199 |  | 
| Eugene Zelenko | 076468c | 2017-09-20 21:35:51 +0000 | [diff] [blame] | 200 | #endif // LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H |