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