xref: /freebsd/contrib/llvm-project/llvm/lib/Target/ARM/ARMTargetTransformInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- ARMTargetTransformInfo.h - ARM specific TTI --------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// This file a TargetTransformInfo::Concept conforming object specific to the
110b57cec5SDimitry Andric /// ARM target machine. It uses the target's detailed information to
120b57cec5SDimitry Andric /// provide more precise answers to certain TTI queries, while letting the
130b57cec5SDimitry Andric /// target independent and default TTI implementations handle the rest.
140b57cec5SDimitry Andric //
150b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H
180b57cec5SDimitry Andric #define LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric #include "ARM.h"
210b57cec5SDimitry Andric #include "ARMSubtarget.h"
220b57cec5SDimitry Andric #include "ARMTargetMachine.h"
230b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
240b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/BasicTTIImpl.h"
260b57cec5SDimitry Andric #include "llvm/IR/Constant.h"
270b57cec5SDimitry Andric #include "llvm/IR/Function.h"
2806c3fb27SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
29bdd1243dSDimitry Andric #include <optional>
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric namespace llvm {
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric class APInt;
340b57cec5SDimitry Andric class ARMTargetLowering;
350b57cec5SDimitry Andric class Instruction;
360b57cec5SDimitry Andric class Loop;
370b57cec5SDimitry Andric class SCEV;
380b57cec5SDimitry Andric class ScalarEvolution;
390b57cec5SDimitry Andric class Type;
400b57cec5SDimitry Andric class Value;
410b57cec5SDimitry Andric 
425ffd83dbSDimitry Andric namespace TailPredication {
435ffd83dbSDimitry Andric   enum Mode {
445ffd83dbSDimitry Andric     Disabled = 0,
455ffd83dbSDimitry Andric     EnabledNoReductions,
465ffd83dbSDimitry Andric     Enabled,
475ffd83dbSDimitry Andric     ForceEnabledNoReductions,
485ffd83dbSDimitry Andric     ForceEnabled
495ffd83dbSDimitry Andric   };
505ffd83dbSDimitry Andric }
515ffd83dbSDimitry Andric 
52fe6060f1SDimitry Andric // For controlling conversion of memcpy into Tail Predicated loop.
53fe6060f1SDimitry Andric namespace TPLoop {
54fe6060f1SDimitry Andric enum MemTransfer { ForceDisabled = 0, ForceEnabled, Allow };
55fe6060f1SDimitry Andric }
56fe6060f1SDimitry Andric 
570b57cec5SDimitry Andric class ARMTTIImpl : public BasicTTIImplBase<ARMTTIImpl> {
580b57cec5SDimitry Andric   using BaseT = BasicTTIImplBase<ARMTTIImpl>;
590b57cec5SDimitry Andric   using TTI = TargetTransformInfo;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric   friend BaseT;
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   const ARMSubtarget *ST;
640b57cec5SDimitry Andric   const ARMTargetLowering *TLI;
650b57cec5SDimitry Andric 
665ffd83dbSDimitry Andric   // Currently the following features are excluded from InlineFeaturesAllowed.
670b57cec5SDimitry Andric   // ModeThumb, FeatureNoARM, ModeSoftFloat, FeatureFP64, FeatureD32
680b57cec5SDimitry Andric   // Depending on whether they are set or unset, different
690b57cec5SDimitry Andric   // instructions/registers are available. For example, inlining a callee with
700b57cec5SDimitry Andric   // -thumb-mode in a caller with +thumb-mode, may cause the assembler to
710b57cec5SDimitry Andric   // fail if the callee uses ARM only instructions, e.g. in inline asm.
725ffd83dbSDimitry Andric   const FeatureBitset InlineFeaturesAllowed = {
730b57cec5SDimitry Andric       ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureNEON, ARM::FeatureThumb2,
740b57cec5SDimitry Andric       ARM::FeatureFP16, ARM::FeatureVFP4, ARM::FeatureFPARMv8,
750b57cec5SDimitry Andric       ARM::FeatureFullFP16, ARM::FeatureFP16FML, ARM::FeatureHWDivThumb,
760b57cec5SDimitry Andric       ARM::FeatureHWDivARM, ARM::FeatureDB, ARM::FeatureV7Clrex,
770b57cec5SDimitry Andric       ARM::FeatureAcquireRelease, ARM::FeatureSlowFPBrcc,
780b57cec5SDimitry Andric       ARM::FeaturePerfMon, ARM::FeatureTrustZone, ARM::Feature8MSecExt,
790b57cec5SDimitry Andric       ARM::FeatureCrypto, ARM::FeatureCRC, ARM::FeatureRAS,
800b57cec5SDimitry Andric       ARM::FeatureFPAO, ARM::FeatureFuseAES, ARM::FeatureZCZeroing,
810b57cec5SDimitry Andric       ARM::FeatureProfUnpredicate, ARM::FeatureSlowVGETLNi32,
820b57cec5SDimitry Andric       ARM::FeatureSlowVDUP32, ARM::FeaturePreferVMOVSR,
830b57cec5SDimitry Andric       ARM::FeaturePrefISHSTBarrier, ARM::FeatureMuxedUnits,
840b57cec5SDimitry Andric       ARM::FeatureSlowOddRegister, ARM::FeatureSlowLoadDSubreg,
850b57cec5SDimitry Andric       ARM::FeatureDontWidenVMOVS, ARM::FeatureExpandMLx,
860b57cec5SDimitry Andric       ARM::FeatureHasVMLxHazards, ARM::FeatureNEONForFPMovs,
870b57cec5SDimitry Andric       ARM::FeatureNEONForFP, ARM::FeatureCheckVLDnAlign,
88480093f4SDimitry Andric       ARM::FeatureHasSlowFPVMLx, ARM::FeatureHasSlowFPVFMx,
89480093f4SDimitry Andric       ARM::FeatureVMLxForwarding, ARM::FeaturePref32BitThumb,
90480093f4SDimitry Andric       ARM::FeatureAvoidPartialCPSR, ARM::FeatureCheapPredicableCPSR,
91480093f4SDimitry Andric       ARM::FeatureAvoidMOVsShOp, ARM::FeatureHasRetAddrStack,
92480093f4SDimitry Andric       ARM::FeatureHasNoBranchPredictor, ARM::FeatureDSP, ARM::FeatureMP,
93480093f4SDimitry Andric       ARM::FeatureVirtualization, ARM::FeatureMClass, ARM::FeatureRClass,
94480093f4SDimitry Andric       ARM::FeatureAClass, ARM::FeatureNaClTrap, ARM::FeatureStrictAlign,
95480093f4SDimitry Andric       ARM::FeatureLongCalls, ARM::FeatureExecuteOnly, ARM::FeatureReserveR9,
96480093f4SDimitry Andric       ARM::FeatureNoMovt, ARM::FeatureNoNegativeImmediates
970b57cec5SDimitry Andric   };
980b57cec5SDimitry Andric 
getST()990b57cec5SDimitry Andric   const ARMSubtarget *getST() const { return ST; }
getTLI()1000b57cec5SDimitry Andric   const ARMTargetLowering *getTLI() const { return TLI; }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric public:
ARMTTIImpl(const ARMBaseTargetMachine * TM,const Function & F)1030b57cec5SDimitry Andric   explicit ARMTTIImpl(const ARMBaseTargetMachine *TM, const Function &F)
104*0fca6ea1SDimitry Andric       : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),
1050b57cec5SDimitry Andric         TLI(ST->getTargetLowering()) {}
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric   bool areInlineCompatible(const Function *Caller,
1080b57cec5SDimitry Andric                            const Function *Callee) const;
1090b57cec5SDimitry Andric 
enableInterleavedAccessVectorization()1100b57cec5SDimitry Andric   bool enableInterleavedAccessVectorization() { return true; }
1110b57cec5SDimitry Andric 
112fe6060f1SDimitry Andric   TTI::AddressingModeKind
113fe6060f1SDimitry Andric     getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const;
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   /// Floating-point computation using ARMv8 AArch32 Advanced
1160b57cec5SDimitry Andric   /// SIMD instructions remains unchanged from ARMv7. Only AArch64 SIMD
1178bcb0991SDimitry Andric   /// and Arm MVE are IEEE-754 compliant.
isFPVectorizationPotentiallyUnsafe()1180b57cec5SDimitry Andric   bool isFPVectorizationPotentiallyUnsafe() {
1198bcb0991SDimitry Andric     return !ST->isTargetDarwin() && !ST->hasMVEFloatOps();
1200b57cec5SDimitry Andric   }
1210b57cec5SDimitry Andric 
122bdd1243dSDimitry Andric   std::optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
123e8d8bef9SDimitry Andric                                                     IntrinsicInst &II) const;
124bdd1243dSDimitry Andric   std::optional<Value *> simplifyDemandedVectorEltsIntrinsic(
125349cc55cSDimitry Andric       InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
126349cc55cSDimitry Andric       APInt &UndefElts2, APInt &UndefElts3,
127349cc55cSDimitry Andric       std::function<void(Instruction *, unsigned, APInt, APInt &)>
128349cc55cSDimitry Andric           SimplifyAndSetOp) const;
129e8d8bef9SDimitry Andric 
1300b57cec5SDimitry Andric   /// \name Scalar TTI Implementations
1310b57cec5SDimitry Andric   /// @{
1320b57cec5SDimitry Andric 
133fe6060f1SDimitry Andric   InstructionCost getIntImmCodeSizeCost(unsigned Opcode, unsigned Idx,
134fe6060f1SDimitry Andric                                         const APInt &Imm, Type *Ty);
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric   using BaseT::getIntImmCost;
137fe6060f1SDimitry Andric   InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,
138fe6060f1SDimitry Andric                                 TTI::TargetCostKind CostKind);
1390b57cec5SDimitry Andric 
140fe6060f1SDimitry Andric   InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx,
141fe6060f1SDimitry Andric                                     const APInt &Imm, Type *Ty,
142fe6060f1SDimitry Andric                                     TTI::TargetCostKind CostKind,
143e8d8bef9SDimitry Andric                                     Instruction *Inst = nullptr);
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   /// @}
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   /// \name Vector TTI Implementations
1480b57cec5SDimitry Andric   /// @{
1490b57cec5SDimitry Andric 
getNumberOfRegisters(unsigned ClassID)1508bcb0991SDimitry Andric   unsigned getNumberOfRegisters(unsigned ClassID) const {
1518bcb0991SDimitry Andric     bool Vector = (ClassID == 1);
1520b57cec5SDimitry Andric     if (Vector) {
1530b57cec5SDimitry Andric       if (ST->hasNEON())
1540b57cec5SDimitry Andric         return 16;
1558bcb0991SDimitry Andric       if (ST->hasMVEIntegerOps())
1568bcb0991SDimitry Andric         return 8;
1570b57cec5SDimitry Andric       return 0;
1580b57cec5SDimitry Andric     }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric     if (ST->isThumb1Only())
1610b57cec5SDimitry Andric       return 8;
1620b57cec5SDimitry Andric     return 13;
1630b57cec5SDimitry Andric   }
1640b57cec5SDimitry Andric 
getRegisterBitWidth(TargetTransformInfo::RegisterKind K)165fe6060f1SDimitry Andric   TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const {
166fe6060f1SDimitry Andric     switch (K) {
167fe6060f1SDimitry Andric     case TargetTransformInfo::RGK_Scalar:
168fe6060f1SDimitry Andric       return TypeSize::getFixed(32);
169fe6060f1SDimitry Andric     case TargetTransformInfo::RGK_FixedWidthVector:
1700b57cec5SDimitry Andric       if (ST->hasNEON())
171fe6060f1SDimitry Andric         return TypeSize::getFixed(128);
1728bcb0991SDimitry Andric       if (ST->hasMVEIntegerOps())
173fe6060f1SDimitry Andric         return TypeSize::getFixed(128);
174fe6060f1SDimitry Andric       return TypeSize::getFixed(0);
175fe6060f1SDimitry Andric     case TargetTransformInfo::RGK_ScalableVector:
176fe6060f1SDimitry Andric       return TypeSize::getScalable(0);
1770b57cec5SDimitry Andric     }
178fe6060f1SDimitry Andric     llvm_unreachable("Unsupported register kind");
1790b57cec5SDimitry Andric   }
1800b57cec5SDimitry Andric 
getMaxInterleaveFactor(ElementCount VF)18106c3fb27SDimitry Andric   unsigned getMaxInterleaveFactor(ElementCount VF) {
1820b57cec5SDimitry Andric     return ST->getMaxInterleaveFactor();
1830b57cec5SDimitry Andric   }
1840b57cec5SDimitry Andric 
1855ffd83dbSDimitry Andric   bool isProfitableLSRChainElement(Instruction *I);
1868bcb0991SDimitry Andric 
1875ffd83dbSDimitry Andric   bool isLegalMaskedLoad(Type *DataTy, Align Alignment);
1885ffd83dbSDimitry Andric 
isLegalMaskedStore(Type * DataTy,Align Alignment)1895ffd83dbSDimitry Andric   bool isLegalMaskedStore(Type *DataTy, Align Alignment) {
1908bcb0991SDimitry Andric     return isLegalMaskedLoad(DataTy, Alignment);
1918bcb0991SDimitry Andric   }
1928bcb0991SDimitry Andric 
forceScalarizeMaskedGather(VectorType * VTy,Align Alignment)19304eeddc0SDimitry Andric   bool forceScalarizeMaskedGather(VectorType *VTy, Align Alignment) {
19404eeddc0SDimitry Andric     // For MVE, we have a custom lowering pass that will already have custom
19504eeddc0SDimitry Andric     // legalised any gathers that we can lower to MVE intrinsics, and want to
19604eeddc0SDimitry Andric     // expand all the rest. The pass runs before the masked intrinsic lowering
19704eeddc0SDimitry Andric     // pass.
19804eeddc0SDimitry Andric     return true;
19904eeddc0SDimitry Andric   }
20004eeddc0SDimitry Andric 
forceScalarizeMaskedScatter(VectorType * VTy,Align Alignment)20104eeddc0SDimitry Andric   bool forceScalarizeMaskedScatter(VectorType *VTy, Align Alignment) {
20204eeddc0SDimitry Andric     return forceScalarizeMaskedGather(VTy, Alignment);
20304eeddc0SDimitry Andric   }
20404eeddc0SDimitry Andric 
2055ffd83dbSDimitry Andric   bool isLegalMaskedGather(Type *Ty, Align Alignment);
206480093f4SDimitry Andric 
isLegalMaskedScatter(Type * Ty,Align Alignment)2075ffd83dbSDimitry Andric   bool isLegalMaskedScatter(Type *Ty, Align Alignment) {
2085ffd83dbSDimitry Andric     return isLegalMaskedGather(Ty, Alignment);
2095ffd83dbSDimitry Andric   }
210480093f4SDimitry Andric 
211fe6060f1SDimitry Andric   InstructionCost getMemcpyCost(const Instruction *I);
2120b57cec5SDimitry Andric 
getMaxMemIntrinsicInlineSizeThreshold()21306c3fb27SDimitry Andric   uint64_t getMaxMemIntrinsicInlineSizeThreshold() const {
21406c3fb27SDimitry Andric     return ST->getMaxInlineSizeThreshold();
21506c3fb27SDimitry Andric   }
21606c3fb27SDimitry Andric 
217e8d8bef9SDimitry Andric   int getNumMemOps(const IntrinsicInst *I) const;
218e8d8bef9SDimitry Andric 
219fe6060f1SDimitry Andric   InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *Tp,
220bdd1243dSDimitry Andric                                  ArrayRef<int> Mask,
221bdd1243dSDimitry Andric                                  TTI::TargetCostKind CostKind, int Index,
22281ad6265SDimitry Andric                                  VectorType *SubTp,
223*0fca6ea1SDimitry Andric                                  ArrayRef<const Value *> Args = std::nullopt,
224*0fca6ea1SDimitry Andric                                  const Instruction *CxtI = nullptr);
2250b57cec5SDimitry Andric 
226e8d8bef9SDimitry Andric   bool preferInLoopReduction(unsigned Opcode, Type *Ty,
227e8d8bef9SDimitry Andric                              TTI::ReductionFlags Flags) const;
22813138422SDimitry Andric 
229e8d8bef9SDimitry Andric   bool preferPredicatedReductionSelect(unsigned Opcode, Type *Ty,
230e8d8bef9SDimitry Andric                                        TTI::ReductionFlags Flags) const;
23113138422SDimitry Andric 
shouldExpandReduction(const IntrinsicInst * II)232e8d8bef9SDimitry Andric   bool shouldExpandReduction(const IntrinsicInst *II) const { return false; }
233e8d8bef9SDimitry Andric 
234fe6060f1SDimitry Andric   InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
2350b57cec5SDimitry Andric                                  const Instruction *I = nullptr);
2360b57cec5SDimitry Andric 
237fe6060f1SDimitry Andric   InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
238fe6060f1SDimitry Andric                                    TTI::CastContextHint CCH,
239fe6060f1SDimitry Andric                                    TTI::TargetCostKind CostKind,
240fe6060f1SDimitry Andric                                    const Instruction *I = nullptr);
241fe6060f1SDimitry Andric 
242fe6060f1SDimitry Andric   InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
243e8d8bef9SDimitry Andric                                      CmpInst::Predicate VecPred,
2445ffd83dbSDimitry Andric                                      TTI::TargetCostKind CostKind,
2450b57cec5SDimitry Andric                                      const Instruction *I = nullptr);
2460b57cec5SDimitry Andric 
247bdd1243dSDimitry Andric   using BaseT::getVectorInstrCost;
248fe6060f1SDimitry Andric   InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val,
249bdd1243dSDimitry Andric                                      TTI::TargetCostKind CostKind,
250bdd1243dSDimitry Andric                                      unsigned Index, Value *Op0, Value *Op1);
2510b57cec5SDimitry Andric 
252fe6060f1SDimitry Andric   InstructionCost getAddressComputationCost(Type *Val, ScalarEvolution *SE,
2530b57cec5SDimitry Andric                                             const SCEV *Ptr);
2540b57cec5SDimitry Andric 
255fe6060f1SDimitry Andric   InstructionCost getArithmeticInstrCost(
256349cc55cSDimitry Andric       unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
257bdd1243dSDimitry Andric       TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None},
258bdd1243dSDimitry Andric       TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},
259*0fca6ea1SDimitry Andric       ArrayRef<const Value *> Args = std::nullopt,
260480093f4SDimitry Andric       const Instruction *CxtI = nullptr);
2610b57cec5SDimitry Andric 
262bdd1243dSDimitry Andric   InstructionCost
263bdd1243dSDimitry Andric   getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment,
264bdd1243dSDimitry Andric                   unsigned AddressSpace, TTI::TargetCostKind CostKind,
265bdd1243dSDimitry Andric                   TTI::OperandValueInfo OpInfo = {TTI::OK_AnyValue, TTI::OP_None},
2665ffd83dbSDimitry Andric                   const Instruction *I = nullptr);
2675ffd83dbSDimitry Andric 
268fe6060f1SDimitry Andric   InstructionCost getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
269fe6060f1SDimitry Andric                                         Align Alignment, unsigned AddressSpace,
270e8d8bef9SDimitry Andric                                         TTI::TargetCostKind CostKind);
271e8d8bef9SDimitry Andric 
272fe6060f1SDimitry Andric   InstructionCost getInterleavedMemoryOpCost(
2735ffd83dbSDimitry Andric       unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
274349cc55cSDimitry Andric       Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
2755ffd83dbSDimitry Andric       bool UseMaskForCond = false, bool UseMaskForGaps = false);
2765ffd83dbSDimitry Andric 
277fe6060f1SDimitry Andric   InstructionCost getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
2785ffd83dbSDimitry Andric                                          const Value *Ptr, bool VariableMask,
279fe6060f1SDimitry Andric                                          Align Alignment,
280fe6060f1SDimitry Andric                                          TTI::TargetCostKind CostKind,
2815ffd83dbSDimitry Andric                                          const Instruction *I = nullptr);
2820b57cec5SDimitry Andric 
283fe6060f1SDimitry Andric   InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *ValTy,
284bdd1243dSDimitry Andric                                              std::optional<FastMathFlags> FMF,
285e8d8bef9SDimitry Andric                                              TTI::TargetCostKind CostKind);
286bdd1243dSDimitry Andric   InstructionCost getExtendedReductionCost(unsigned Opcode, bool IsUnsigned,
287e8d8bef9SDimitry Andric                                            Type *ResTy, VectorType *ValTy,
28806c3fb27SDimitry Andric                                            FastMathFlags FMF,
289bdd1243dSDimitry Andric                                            TTI::TargetCostKind CostKind);
290bdd1243dSDimitry Andric   InstructionCost getMulAccReductionCost(bool IsUnsigned, Type *ResTy,
291bdd1243dSDimitry Andric                                          VectorType *ValTy,
292e8d8bef9SDimitry Andric                                          TTI::TargetCostKind CostKind);
293e8d8bef9SDimitry Andric 
2945f757f3fSDimitry Andric   InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty,
2955f757f3fSDimitry Andric                                          FastMathFlags FMF,
2965f757f3fSDimitry Andric                                          TTI::TargetCostKind CostKind);
2975f757f3fSDimitry Andric 
298fe6060f1SDimitry Andric   InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
299e8d8bef9SDimitry Andric                                         TTI::TargetCostKind CostKind);
300e8d8bef9SDimitry Andric 
301bdd1243dSDimitry Andric   /// getScalingFactorCost - Return the cost of the scaling used in
302bdd1243dSDimitry Andric   /// addressing mode represented by AM.
303bdd1243dSDimitry Andric   /// If the AM is supported, the return value must be >= 0.
304bdd1243dSDimitry Andric   /// If the AM is not supported, the return value must be negative.
305bdd1243dSDimitry Andric   InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,
306*0fca6ea1SDimitry Andric                                        StackOffset BaseOffset, bool HasBaseReg,
307bdd1243dSDimitry Andric                                        int64_t Scale, unsigned AddrSpace) const;
308bdd1243dSDimitry Andric 
309e8d8bef9SDimitry Andric   bool maybeLoweredToCall(Instruction &I);
3100b57cec5SDimitry Andric   bool isLoweredToCall(const Function *F);
3110b57cec5SDimitry Andric   bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
3120b57cec5SDimitry Andric                                 AssumptionCache &AC,
3130b57cec5SDimitry Andric                                 TargetLibraryInfo *LibInfo,
3140b57cec5SDimitry Andric                                 HardwareLoopInfo &HWLoopInfo);
31506c3fb27SDimitry Andric   bool preferPredicateOverEpilogue(TailFoldingInfo *TFI);
3160b57cec5SDimitry Andric   void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
317349cc55cSDimitry Andric                                TTI::UnrollingPreferences &UP,
318349cc55cSDimitry Andric                                OptimizationRemarkEmitter *ORE);
3190b57cec5SDimitry Andric 
32006c3fb27SDimitry Andric   TailFoldingStyle
32106c3fb27SDimitry Andric   getPreferredTailFoldingStyle(bool IVUpdateMayOverflow = true) const;
3225ffd83dbSDimitry Andric 
3235ffd83dbSDimitry Andric   void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
3245ffd83dbSDimitry Andric                              TTI::PeelingPreferences &PP);
shouldBuildLookupTablesForConstant(Constant * C)3250b57cec5SDimitry Andric   bool shouldBuildLookupTablesForConstant(Constant *C) const {
3260b57cec5SDimitry Andric     // In the ROPI and RWPI relocation models we can't have pointers to global
3270b57cec5SDimitry Andric     // variables or functions in constant data, so don't convert switches to
3280b57cec5SDimitry Andric     // lookup tables if any of the values would need relocation.
3290b57cec5SDimitry Andric     if (ST->isROPI() || ST->isRWPI())
330fe6060f1SDimitry Andric       return !C->needsDynamicRelocation();
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric     return true;
3330b57cec5SDimitry Andric   }
33406c3fb27SDimitry Andric 
33506c3fb27SDimitry Andric   bool hasArmWideBranch(bool Thumb) const;
33606c3fb27SDimitry Andric 
3370b57cec5SDimitry Andric   /// @}
3380b57cec5SDimitry Andric };
3390b57cec5SDimitry Andric 
340fe6060f1SDimitry Andric /// isVREVMask - Check if a vector shuffle corresponds to a VREV
341fe6060f1SDimitry Andric /// instruction with the specified blocksize.  (The order of the elements
342fe6060f1SDimitry Andric /// within each block of the vector is reversed.)
isVREVMask(ArrayRef<int> M,EVT VT,unsigned BlockSize)343fe6060f1SDimitry Andric inline bool isVREVMask(ArrayRef<int> M, EVT VT, unsigned BlockSize) {
344fe6060f1SDimitry Andric   assert((BlockSize == 16 || BlockSize == 32 || BlockSize == 64) &&
345fe6060f1SDimitry Andric          "Only possible block sizes for VREV are: 16, 32, 64");
346fe6060f1SDimitry Andric 
347fe6060f1SDimitry Andric   unsigned EltSz = VT.getScalarSizeInBits();
348fe6060f1SDimitry Andric   if (EltSz != 8 && EltSz != 16 && EltSz != 32)
349fe6060f1SDimitry Andric     return false;
350fe6060f1SDimitry Andric 
351fe6060f1SDimitry Andric   unsigned BlockElts = M[0] + 1;
352fe6060f1SDimitry Andric   // If the first shuffle index is UNDEF, be optimistic.
353fe6060f1SDimitry Andric   if (M[0] < 0)
354fe6060f1SDimitry Andric     BlockElts = BlockSize / EltSz;
355fe6060f1SDimitry Andric 
356fe6060f1SDimitry Andric   if (BlockSize <= EltSz || BlockSize != BlockElts * EltSz)
357fe6060f1SDimitry Andric     return false;
358fe6060f1SDimitry Andric 
359fe6060f1SDimitry Andric   for (unsigned i = 0, e = M.size(); i < e; ++i) {
360fe6060f1SDimitry Andric     if (M[i] < 0)
361fe6060f1SDimitry Andric       continue; // ignore UNDEF indices
362fe6060f1SDimitry Andric     if ((unsigned)M[i] != (i - i % BlockElts) + (BlockElts - 1 - i % BlockElts))
363fe6060f1SDimitry Andric       return false;
364fe6060f1SDimitry Andric   }
365fe6060f1SDimitry Andric 
366fe6060f1SDimitry Andric   return true;
367fe6060f1SDimitry Andric }
368fe6060f1SDimitry Andric 
3690b57cec5SDimitry Andric } // end namespace llvm
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H
372