brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.6 KiB · 9c0eff9 Raw
411 lines · c
1//===-- AMDGPUISelLowering.h - AMDGPU Lowering Interface --------*- C++ -*-===//2//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-exception6//7//===----------------------------------------------------------------------===//8//9/// \file10/// Interface definition of the TargetLowering class that is common11/// to all AMD GPUs.12//13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUISELLOWERING_H16#define LLVM_LIB_TARGET_AMDGPU_AMDGPUISELLOWERING_H17 18#include "llvm/CodeGen/CallingConvLower.h"19#include "llvm/CodeGen/TargetLowering.h"20 21namespace llvm {22 23class AMDGPUMachineFunction;24class AMDGPUSubtarget;25struct ArgDescriptor;26 27class AMDGPUTargetLowering : public TargetLowering {28private:29  const AMDGPUSubtarget *Subtarget;30 31  /// \returns AMDGPUISD::FFBH_U32 node if the incoming \p Op may have been32  /// legalized from a smaller type VT. Need to match pre-legalized type because33  /// the generic legalization inserts the add/sub between the select and34  /// compare.35  SDValue getFFBX_U32(SelectionDAG &DAG, SDValue Op, const SDLoc &DL, unsigned Opc) const;36 37public:38  /// \returns The minimum number of bits needed to store the value of \Op as an39  /// unsigned integer. Truncating to this size and then zero-extending to the40  /// original size will not change the value.41  static unsigned numBitsUnsigned(SDValue Op, SelectionDAG &DAG);42 43  /// \returns The minimum number of bits needed to store the value of \Op as a44  /// signed integer. Truncating to this size and then sign-extending to the45  /// original size will not change the value.46  static unsigned numBitsSigned(SDValue Op, SelectionDAG &DAG);47 48protected:49  SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;50  SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;51  /// Split a vector store into multiple scalar stores.52  /// \returns The resulting chain.53 54  SDValue LowerFREM(SDValue Op, SelectionDAG &DAG) const;55  SDValue LowerFCEIL(SDValue Op, SelectionDAG &DAG) const;56  SDValue LowerFTRUNC(SDValue Op, SelectionDAG &DAG) const;57  SDValue LowerFRINT(SDValue Op, SelectionDAG &DAG) const;58  SDValue LowerFNEARBYINT(SDValue Op, SelectionDAG &DAG) const;59 60  SDValue LowerFROUNDEVEN(SDValue Op, SelectionDAG &DAG) const;61  SDValue LowerFROUND(SDValue Op, SelectionDAG &DAG) const;62  SDValue LowerFFLOOR(SDValue Op, SelectionDAG &DAG) const;63 64  static bool allowApproxFunc(const SelectionDAG &DAG, SDNodeFlags Flags);65  static bool needsDenormHandlingF32(const SelectionDAG &DAG, SDValue Src,66                                     SDNodeFlags Flags);67  SDValue getIsLtSmallestNormal(SelectionDAG &DAG, SDValue Op,68                                SDNodeFlags Flags) const;69  SDValue getIsFinite(SelectionDAG &DAG, SDValue Op, SDNodeFlags Flags) const;70  std::pair<SDValue, SDValue> getScaledLogInput(SelectionDAG &DAG,71                                                const SDLoc SL, SDValue Op,72                                                SDNodeFlags Flags) const;73 74  SDValue LowerFLOG2(SDValue Op, SelectionDAG &DAG) const;75  SDValue LowerFLOGCommon(SDValue Op, SelectionDAG &DAG) const;76  SDValue LowerFLOG10(SDValue Op, SelectionDAG &DAG) const;77  SDValue LowerFLOGUnsafe(SDValue Op, const SDLoc &SL, SelectionDAG &DAG,78                          bool IsLog10, SDNodeFlags Flags) const;79  SDValue lowerFEXP2(SDValue Op, SelectionDAG &DAG) const;80 81  SDValue lowerFEXPUnsafe(SDValue Op, const SDLoc &SL, SelectionDAG &DAG,82                          SDNodeFlags Flags) const;83  SDValue lowerFEXP10Unsafe(SDValue Op, const SDLoc &SL, SelectionDAG &DAG,84                            SDNodeFlags Flags) const;85  SDValue lowerFEXP(SDValue Op, SelectionDAG &DAG) const;86 87  SDValue lowerCTLZResults(SDValue Op, SelectionDAG &DAG) const;88 89  SDValue LowerCTLZ_CTTZ(SDValue Op, SelectionDAG &DAG) const;90 91  SDValue LowerINT_TO_FP32(SDValue Op, SelectionDAG &DAG, bool Signed) const;92  SDValue LowerINT_TO_FP64(SDValue Op, SelectionDAG &DAG, bool Signed) const;93  SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;94  SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;95 96  SDValue LowerFP_TO_INT64(SDValue Op, SelectionDAG &DAG, bool Signed) const;97  SDValue LowerFP_TO_FP16(SDValue Op, SelectionDAG &DAG) const;98  SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;99 100  SDValue LowerF64ToF16Safe(SDValue Src, const SDLoc &DL,101                            SelectionDAG &DAG) const;102 103  SDValue LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG) const;104 105protected:106  bool shouldCombineMemoryType(EVT VT) const;107  SDValue performLoadCombine(SDNode *N, DAGCombinerInfo &DCI) const;108  SDValue performStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const;109  SDValue performAssertSZExtCombine(SDNode *N, DAGCombinerInfo &DCI) const;110  SDValue performIntrinsicWOChainCombine(SDNode *N, DAGCombinerInfo &DCI) const;111 112  SDValue splitBinaryBitConstantOpImpl(DAGCombinerInfo &DCI, const SDLoc &SL,113                                       unsigned Opc, SDValue LHS,114                                       uint32_t ValLo, uint32_t ValHi) const;115  SDValue performShlCombine(SDNode *N, DAGCombinerInfo &DCI) const;116  SDValue performSraCombine(SDNode *N, DAGCombinerInfo &DCI) const;117  SDValue performSrlCombine(SDNode *N, DAGCombinerInfo &DCI) const;118  SDValue performTruncateCombine(SDNode *N, DAGCombinerInfo &DCI) const;119  SDValue performMulCombine(SDNode *N, DAGCombinerInfo &DCI) const;120  SDValue performMulLoHiCombine(SDNode *N, DAGCombinerInfo &DCI) const;121  SDValue performMulhsCombine(SDNode *N, DAGCombinerInfo &DCI) const;122  SDValue performMulhuCombine(SDNode *N, DAGCombinerInfo &DCI) const;123  SDValue performCtlz_CttzCombine(const SDLoc &SL, SDValue Cond, SDValue LHS,124                             SDValue RHS, DAGCombinerInfo &DCI) const;125 126  SDValue foldFreeOpFromSelect(TargetLowering::DAGCombinerInfo &DCI,127                               SDValue N) const;128  SDValue performSelectCombine(SDNode *N, DAGCombinerInfo &DCI) const;129 130  TargetLowering::NegatibleCost131  getConstantNegateCost(const ConstantFPSDNode *C) const;132 133  bool isConstantCostlierToNegate(SDValue N) const;134  bool isConstantCheaperToNegate(SDValue N) const;135  SDValue performFNegCombine(SDNode *N, DAGCombinerInfo &DCI) const;136  SDValue performFAbsCombine(SDNode *N, DAGCombinerInfo &DCI) const;137  SDValue performRcpCombine(SDNode *N, DAGCombinerInfo &DCI) const;138 139  static EVT getEquivalentMemType(LLVMContext &Context, EVT VT);140 141  virtual SDValue LowerGlobalAddress(AMDGPUMachineFunction *MFI, SDValue Op,142                                     SelectionDAG &DAG) const;143 144  /// Return 64-bit value Op as two 32-bit integers.145  std::pair<SDValue, SDValue> split64BitValue(SDValue Op,146                                              SelectionDAG &DAG) const;147  SDValue getLoHalf64(SDValue Op, SelectionDAG &DAG) const;148  SDValue getHiHalf64(SDValue Op, SelectionDAG &DAG) const;149 150  /// Split a vector type into two parts. The first part is a power of two151  /// vector. The second part is whatever is left over, and is a scalar if it152  /// would otherwise be a 1-vector.153  std::pair<EVT, EVT> getSplitDestVTs(const EVT &VT, SelectionDAG &DAG) const;154 155  /// Split a vector value into two parts of types LoVT and HiVT. HiVT could be156  /// scalar.157  std::pair<SDValue, SDValue> splitVector(const SDValue &N, const SDLoc &DL,158                                          const EVT &LoVT, const EVT &HighVT,159                                          SelectionDAG &DAG) const;160 161  /// Split a vector load into 2 loads of half the vector.162  SDValue SplitVectorLoad(SDValue Op, SelectionDAG &DAG) const;163 164  /// Widen a suitably aligned v3 load. For all other cases, split the input165  /// vector load.166  SDValue WidenOrSplitVectorLoad(SDValue Op, SelectionDAG &DAG) const;167 168  /// Split a vector store into 2 stores of half the vector.169  SDValue SplitVectorStore(SDValue Op, SelectionDAG &DAG) const;170 171  SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;172  SDValue LowerSDIVREM(SDValue Op, SelectionDAG &DAG) const;173  SDValue LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;174  SDValue LowerDIVREM24(SDValue Op, SelectionDAG &DAG, bool sign) const;175  void LowerUDIVREM64(SDValue Op, SelectionDAG &DAG,176                                    SmallVectorImpl<SDValue> &Results) const;177 178  void analyzeFormalArgumentsCompute(179    CCState &State,180    const SmallVectorImpl<ISD::InputArg> &Ins) const;181 182public:183  AMDGPUTargetLowering(const TargetMachine &TM, const TargetSubtargetInfo &STI,184                       const AMDGPUSubtarget &AMDGPUSTI);185 186  bool mayIgnoreSignedZero(SDValue Op) const;187 188  static inline SDValue stripBitcast(SDValue Val) {189    return Val.getOpcode() == ISD::BITCAST ? Val.getOperand(0) : Val;190  }191 192  static bool shouldFoldFNegIntoSrc(SDNode *FNeg, SDValue FNegSrc);193  static bool allUsesHaveSourceMods(const SDNode *N,194                                    unsigned CostThreshold = 4);195  bool isFAbsFree(EVT VT) const override;196  bool isFNegFree(EVT VT) const override;197  bool isTruncateFree(EVT Src, EVT Dest) const override;198  bool isTruncateFree(Type *Src, Type *Dest) const override;199 200  bool isZExtFree(Type *Src, Type *Dest) const override;201  bool isZExtFree(EVT Src, EVT Dest) const override;202 203  SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG,204                               bool LegalOperations, bool ForCodeSize,205                               NegatibleCost &Cost,206                               unsigned Depth) const override;207 208  bool isNarrowingProfitable(SDNode *N, EVT SrcVT, EVT DestVT) const override;209 210  bool isDesirableToCommuteWithShift(const SDNode *N,211                                     CombineLevel Level) const override;212 213  EVT getTypeForExtReturn(LLVMContext &Context, EVT VT,214                          ISD::NodeType ExtendKind) const override;215 216  unsigned getVectorIdxWidth(const DataLayout &) const override;217  bool isSelectSupported(SelectSupportKind) const override;218 219  bool isFPImmLegal(const APFloat &Imm, EVT VT,220                    bool ForCodeSize) const override;221  bool ShouldShrinkFPConstant(EVT VT) const override;222  bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtType, EVT ExtVT,223                             std::optional<unsigned> ByteOffset) const override;224 225  bool isLoadBitCastBeneficial(EVT, EVT, const SelectionDAG &DAG,226                               const MachineMemOperand &MMO) const final;227 228  bool storeOfVectorConstantIsCheap(bool IsZero, EVT MemVT,229                                    unsigned NumElem,230                                    unsigned AS) const override;231  bool aggressivelyPreferBuildVectorSources(EVT VecVT) const override;232  bool isCheapToSpeculateCttz(Type *Ty) const override;233  bool isCheapToSpeculateCtlz(Type *Ty) const override;234 235  bool isSDNodeAlwaysUniform(const SDNode *N) const override;236 237  // FIXME: This hook should not exist238  AtomicExpansionKind shouldCastAtomicLoadInIR(LoadInst *LI) const override {239    return AtomicExpansionKind::None;240  }241 242  AtomicExpansionKind shouldCastAtomicStoreInIR(StoreInst *SI) const override {243    return AtomicExpansionKind::None;244  }245 246  AtomicExpansionKind shouldCastAtomicRMWIInIR(AtomicRMWInst *) const override {247    return AtomicExpansionKind::None;248  }249 250  static CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg);251  static CCAssignFn *CCAssignFnForReturn(CallingConv::ID CC, bool IsVarArg);252 253  SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,254                      const SmallVectorImpl<ISD::OutputArg> &Outs,255                      const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,256                      SelectionDAG &DAG) const override;257 258  SDValue addTokenForArgument(SDValue Chain,259                              SelectionDAG &DAG,260                              MachineFrameInfo &MFI,261                              int ClobberedFI) const;262 263  SDValue lowerUnhandledCall(CallLoweringInfo &CLI,264                             SmallVectorImpl<SDValue> &InVals,265                             StringRef Reason) const;266  SDValue LowerCall(CallLoweringInfo &CLI,267                    SmallVectorImpl<SDValue> &InVals) const override;268 269  SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;270  SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;271  SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;272  void ReplaceNodeResults(SDNode * N,273                          SmallVectorImpl<SDValue> &Results,274                          SelectionDAG &DAG) const override;275 276  SDValue combineFMinMaxLegacyImpl(const SDLoc &DL, EVT VT, SDValue LHS,277                                   SDValue RHS, SDValue True, SDValue False,278                                   SDValue CC, DAGCombinerInfo &DCI) const;279 280  SDValue combineFMinMaxLegacy(const SDLoc &DL, EVT VT, SDValue LHS,281                               SDValue RHS, SDValue True, SDValue False,282                               SDValue CC, DAGCombinerInfo &DCI) const;283 284  // FIXME: Turn off MergeConsecutiveStores() before Instruction Selection for285  // AMDGPU.  Commit r319036,286  // (https://github.com/llvm/llvm-project/commit/db77e57ea86d941a4262ef60261692f4cb6893e6)287  // turned on MergeConsecutiveStores() before Instruction Selection for all288  // targets.  Enough AMDGPU compiles go into an infinite loop (289  // MergeConsecutiveStores() merges two stores; LegalizeStoreOps() un-merges;290  // MergeConsecutiveStores() re-merges, etc. ) to warrant turning it off for291  // now.292  bool mergeStoresAfterLegalization(EVT) const override { return false; }293 294  bool isFsqrtCheap(SDValue Operand, SelectionDAG &DAG) const override {295    return true;296  }297  SDValue getSqrtEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled,298                           int &RefinementSteps, bool &UseOneConstNR,299                           bool Reciprocal) const override;300  SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled,301                           int &RefinementSteps) const override;302 303  virtual SDNode *PostISelFolding(MachineSDNode *N,304                                  SelectionDAG &DAG) const = 0;305 306  /// Determine which of the bits specified in \p Mask are known to be307  /// either zero or one and return them in the \p KnownZero and \p KnownOne308  /// bitsets.309  void computeKnownBitsForTargetNode(const SDValue Op,310                                     KnownBits &Known,311                                     const APInt &DemandedElts,312                                     const SelectionDAG &DAG,313                                     unsigned Depth = 0) const override;314 315  unsigned ComputeNumSignBitsForTargetNode(SDValue Op, const APInt &DemandedElts,316                                           const SelectionDAG &DAG,317                                           unsigned Depth = 0) const override;318 319  unsigned computeNumSignBitsForTargetInstr(GISelValueTracking &Analysis,320                                            Register R,321                                            const APInt &DemandedElts,322                                            const MachineRegisterInfo &MRI,323                                            unsigned Depth = 0) const override;324 325  bool canCreateUndefOrPoisonForTargetNode(SDValue Op,326                                           const APInt &DemandedElts,327                                           const SelectionDAG &DAG,328                                           bool PoisonOnly, bool ConsiderFlags,329                                           unsigned Depth) const override;330 331  bool isKnownNeverNaNForTargetNode(SDValue Op, const APInt &DemandedElts,332                                    const SelectionDAG &DAG, bool SNaN = false,333                                    unsigned Depth = 0) const override;334 335  bool isReassocProfitable(MachineRegisterInfo &MRI, Register N0,336                           Register N1) const override;337 338  /// Helper function that adds Reg to the LiveIn list of the DAG's339  /// MachineFunction.340  ///341  /// \returns a RegisterSDNode representing Reg if \p RawReg is true, otherwise342  /// a copy from the register.343  SDValue CreateLiveInRegister(SelectionDAG &DAG,344                               const TargetRegisterClass *RC,345                               Register Reg, EVT VT,346                               const SDLoc &SL,347                               bool RawReg = false) const;348  SDValue CreateLiveInRegister(SelectionDAG &DAG,349                               const TargetRegisterClass *RC,350                               Register Reg, EVT VT) const {351    return CreateLiveInRegister(DAG, RC, Reg, VT, SDLoc(DAG.getEntryNode()));352  }353 354  // Returns the raw live in register rather than a copy from it.355  SDValue CreateLiveInRegisterRaw(SelectionDAG &DAG,356                                  const TargetRegisterClass *RC,357                                  Register Reg, EVT VT) const {358    return CreateLiveInRegister(DAG, RC, Reg, VT, SDLoc(DAG.getEntryNode()), true);359  }360 361  /// Similar to CreateLiveInRegister, except value maybe loaded from a stack362  /// slot rather than passed in a register.363  SDValue loadStackInputValue(SelectionDAG &DAG,364                              EVT VT,365                              const SDLoc &SL,366                              int64_t Offset) const;367 368  SDValue storeStackInputValue(SelectionDAG &DAG,369                               const SDLoc &SL,370                               SDValue Chain,371                               SDValue ArgVal,372                               int64_t Offset) const;373 374  SDValue loadInputValue(SelectionDAG &DAG,375                         const TargetRegisterClass *RC,376                         EVT VT, const SDLoc &SL,377                         const ArgDescriptor &Arg) const;378 379  enum ImplicitParameter {380    FIRST_IMPLICIT,381    PRIVATE_BASE,382    SHARED_BASE,383    QUEUE_PTR,384  };385 386  /// Helper function that returns the byte offset of the given387  /// type of implicit parameter.388  uint32_t getImplicitParameterOffset(const MachineFunction &MF,389                                      const ImplicitParameter Param) const;390  uint32_t getImplicitParameterOffset(const uint64_t ExplicitKernArgSize,391                                      const ImplicitParameter Param) const;392 393  MVT getFenceOperandTy(const DataLayout &DL) const override {394    return MVT::i32;395  }396 397  bool hasMultipleConditionRegisters(EVT VT) const override {398    // FIXME: This is only partially true. If we have to do vector compares, any399    // SGPR pair can be a condition register. If we have a uniform condition, we400    // are better off doing SALU operations, where there is only one SCC. For401    // now, we don't have a way of knowing during instruction selection if a402    // condition will be uniform and we always use vector compares. Assume we403    // are using vector compares until that is fixed.404    return true;405  }406};407 408} // End namespace llvm409 410#endif411