brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.6 KiB · 0c09fb6 Raw
294 lines · c
1//=- LoongArchISelLowering.h - LoongArch DAG 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// This file defines the interfaces that LoongArch uses to lower LLVM code into10// a selection DAG.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H15#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H16 17#include "LoongArch.h"18#include "llvm/CodeGen/CallingConvLower.h"19#include "llvm/CodeGen/SelectionDAG.h"20#include "llvm/CodeGen/TargetLowering.h"21 22namespace llvm {23class LoongArchSubtarget;24 25class LoongArchTargetLowering : public TargetLowering {26  const LoongArchSubtarget &Subtarget;27 28public:29  explicit LoongArchTargetLowering(const TargetMachine &TM,30                                   const LoongArchSubtarget &STI);31 32  const LoongArchSubtarget &getSubtarget() const { return Subtarget; }33 34  bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;35 36  // Provide custom lowering hooks for some operations.37  SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;38  void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,39                          SelectionDAG &DAG) const override;40 41  SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;42 43  // Lower incoming arguments, copy physregs into vregs.44  SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,45                               bool IsVarArg,46                               const SmallVectorImpl<ISD::InputArg> &Ins,47                               const SDLoc &DL, SelectionDAG &DAG,48                               SmallVectorImpl<SDValue> &InVals) const override;49  bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,50                      bool IsVarArg,51                      const SmallVectorImpl<ISD::OutputArg> &Outs,52                      LLVMContext &Context, const Type *RetTy) const override;53  SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,54                      const SmallVectorImpl<ISD::OutputArg> &Outs,55                      const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,56                      SelectionDAG &DAG) const override;57  SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,58                    SmallVectorImpl<SDValue> &InVals) const override;59  bool isCheapToSpeculateCttz(Type *Ty) const override;60  bool isCheapToSpeculateCtlz(Type *Ty) const override;61  bool hasAndNot(SDValue Y) const override;62  TargetLowering::AtomicExpansionKind63  shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;64  void emitExpandAtomicRMW(AtomicRMWInst *AI) const override;65 66  Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI,67                                      Value *AlignedAddr, Value *Incr,68                                      Value *Mask, Value *ShiftAmt,69                                      AtomicOrdering Ord) const override;70 71  EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,72                         EVT VT) const override;73  TargetLowering::AtomicExpansionKind74  shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override;75  Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder,76                                          AtomicCmpXchgInst *CI,77                                          Value *AlignedAddr, Value *CmpVal,78                                          Value *NewVal, Value *Mask,79                                          AtomicOrdering Ord) const override;80 81  bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,82                          MachineFunction &MF,83                          unsigned Intrinsic) const override;84 85  bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,86                                  EVT VT) const override;87 88  Register89  getExceptionPointerRegister(const Constant *PersonalityFn) const override;90 91  Register92  getExceptionSelectorRegister(const Constant *PersonalityFn) const override;93 94  bool isFsqrtCheap(SDValue Operand, SelectionDAG &DAG) const override {95    return true;96  }97 98  SDValue getSqrtEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled,99                          int &RefinementSteps, bool &UseOneConstNR,100                          bool Reciprocal) const override;101 102  SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled,103                           int &RefinementSteps) const override;104 105  ISD::NodeType getExtendForAtomicOps() const override {106    return ISD::SIGN_EXTEND;107  }108 109  ISD::NodeType getExtendForAtomicCmpSwapArg() const override;110 111  Register getRegisterByName(const char *RegName, LLT VT,112                             const MachineFunction &MF) const override;113  bool mayBeEmittedAsTailCall(const CallInst *CI) const override;114 115  bool decomposeMulByConstant(LLVMContext &Context, EVT VT,116                              SDValue C) const override;117 118  bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;119 120  bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,121                             unsigned AS,122                             Instruction *I = nullptr) const override;123 124  bool isLegalICmpImmediate(int64_t Imm) const override;125  bool isLegalAddImmediate(int64_t Imm) const override;126  bool isZExtFree(SDValue Val, EVT VT2) const override;127  bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override;128  bool signExtendConstant(const ConstantInt *CI) const override;129 130  bool hasAndNotCompare(SDValue Y) const override;131 132  bool convertSelectOfConstantsToMath(EVT VT) const override { return true; }133 134  bool allowsMisalignedMemoryAccesses(135      EVT VT, unsigned AddrSpace = 0, Align Alignment = Align(1),136      MachineMemOperand::Flags Flags = MachineMemOperand::MONone,137      unsigned *Fast = nullptr) const override;138 139  bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override {140    if (!VT.isSimple())141      return false;142 143    // Not for i1 vectors144    if (VT.getSimpleVT().getScalarType() == MVT::i1)145      return false;146 147    return isTypeLegal(VT.getSimpleVT());148  }149  bool shouldConsiderGEPOffsetSplit() const override { return true; }150  bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const override;151  bool shouldExtendTypeInLibCall(EVT Type) const override;152 153  bool shouldAlignPointerArgs(CallInst *CI, unsigned &MinSize,154                              Align &PrefAlign) const override;155 156  bool isFPImmVLDILegal(const APFloat &Imm, EVT VT) const;157  LegalizeTypeAction getPreferredVectorAction(MVT VT) const override;158 159  bool SimplifyDemandedBitsForTargetNode(SDValue Op, const APInt &DemandedBits,160                                         const APInt &DemandedElts,161                                         KnownBits &Known,162                                         TargetLoweringOpt &TLO,163                                         unsigned Depth) const override;164 165  bool shouldScalarizeBinop(SDValue VecOp) const override;166  bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,167                               unsigned Index) const override;168  bool isExtractVecEltCheap(EVT VT, unsigned Index) const override;169 170  /// Check if a constant splat can be generated using [x]vldi, where imm[12]171  /// is 1.172  std::pair<bool, uint64_t>173  isImmVLDILegalForMode1(const APInt &SplatValue,174                         const unsigned SplatBitSize) const;175 176private:177  /// Target-specific function used to lower LoongArch calling conventions.178  typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI,179                                   unsigned ValNo, MVT ValVT,180                                   CCValAssign::LocInfo LocInfo,181                                   ISD::ArgFlagsTy ArgFlags, CCState &State,182                                   bool IsRet, Type *OrigTy);183 184  void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo,185                        const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet,186                        LoongArchCCAssignFn Fn) const;187  void analyzeOutputArgs(MachineFunction &MF, CCState &CCInfo,188                         const SmallVectorImpl<ISD::OutputArg> &Outs,189                         bool IsRet, CallLoweringInfo *CLI,190                         LoongArchCCAssignFn Fn) const;191 192  template <class NodeTy>193  SDValue getAddr(NodeTy *N, SelectionDAG &DAG, CodeModel::Model M,194                  bool IsLocal = true) const;195  SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,196                           unsigned Opc, bool UseGOT, bool Large = false) const;197  SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,198                            unsigned Opc, bool Large = false) const;199  SDValue getTLSDescAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,200                         unsigned Opc, bool Large = false) const;201  SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;202  SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;203  SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;204  SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;205  SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;206  SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;207 208  MachineBasicBlock *209  EmitInstrWithCustomInserter(MachineInstr &MI,210                              MachineBasicBlock *BB) const override;211  SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;212  SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;213  SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;214  SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;215  SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;216  SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;217  SDValue lowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;218  SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;219  SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;220  SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;221  SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;222  SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;223  SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;224  SDValue lowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG) const;225  SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;226  SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;227  SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;228  SDValue lowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;229  SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;230  SDValue lowerBITREVERSE(SDValue Op, SelectionDAG &DAG) const;231  SDValue lowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const;232  SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;233  SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;234  SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const;235  SDValue lowerFP_TO_FP16(SDValue Op, SelectionDAG &DAG) const;236  SDValue lowerFP16_TO_FP(SDValue Op, SelectionDAG &DAG) const;237  SDValue lowerFP_TO_BF16(SDValue Op, SelectionDAG &DAG) const;238  SDValue lowerBF16_TO_FP(SDValue Op, SelectionDAG &DAG) const;239  SDValue lowerVECREDUCE_ADD(SDValue Op, SelectionDAG &DAG) const;240  SDValue lowerVECREDUCE(SDValue Op, SelectionDAG &DAG) const;241  SDValue lowerConstantFP(SDValue Op, SelectionDAG &DAG) const;242  SDValue lowerRotate(SDValue Op, SelectionDAG &DAG) const;243 244  bool isFPImmLegal(const APFloat &Imm, EVT VT,245                    bool ForCodeSize) const override;246 247  bool shouldInsertFencesForAtomic(const Instruction *I) const override;248 249  ConstraintType getConstraintType(StringRef Constraint) const override;250 251  InlineAsm::ConstraintCode252  getInlineAsmMemConstraint(StringRef ConstraintCode) const override;253 254  std::pair<unsigned, const TargetRegisterClass *>255  getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,256                               StringRef Constraint, MVT VT) const override;257 258  void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,259                                    std::vector<SDValue> &Ops,260                                    SelectionDAG &DAG) const override;261 262  bool isEligibleForTailCallOptimization(263      CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,264      const SmallVectorImpl<CCValAssign> &ArgLocs) const;265 266  bool softPromoteHalfType() const override { return true; }267 268  bool269  splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val,270                              SDValue *Parts, unsigned NumParts, MVT PartVT,271                              std::optional<CallingConv::ID> CC) const override;272 273  SDValue274  joinRegisterPartsIntoValue(SelectionDAG &DAG, const SDLoc &DL,275                             const SDValue *Parts, unsigned NumParts,276                             MVT PartVT, EVT ValueVT,277                             std::optional<CallingConv::ID> CC) const override;278 279  /// Return the register type for a given MVT, ensuring vectors are treated280  /// as a series of gpr sized integers.281  MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,282                                    EVT VT) const override;283 284  /// Return the number of registers for a given MVT, ensuring vectors are285  /// treated as a series of gpr sized integers.286  unsigned getNumRegistersForCallingConv(LLVMContext &Context,287                                         CallingConv::ID CC,288                                         EVT VT) const override;289};290 291} // end namespace llvm292 293#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H294