//===-- NVPTXISelDAGToDAG.h - A dag to dag inst selector for NVPTX --------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines an instruction selector for the NVPTX target. // //===----------------------------------------------------------------------===// #ifndef LLVM_LIB_TARGET_NVPTX_NVPTXISELDAGTODAG_H #define LLVM_LIB_TARGET_NVPTX_NVPTXISELDAGTODAG_H #include "MCTargetDesc/NVPTXBaseInfo.h" #include "NVPTX.h" #include "NVPTXISelLowering.h" #include "NVPTXRegisterInfo.h" #include "NVPTXTargetMachine.h" #include "llvm/ADT/MapVector.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" #include "llvm/Support/Compiler.h" namespace llvm { struct NVPTXScopes { NVPTXScopes() = default; NVPTXScopes(LLVMContext &C); NVPTX::Scope operator[](SyncScope::ID ID) const; bool empty() const; private: SmallMapVector Scopes{}; }; class LLVM_LIBRARY_VISIBILITY NVPTXDAGToDAGISel : public SelectionDAGISel { const NVPTXTargetMachine &TM; NVPTX::DivPrecisionLevel getDivF32Level(const SDNode *N) const; bool usePrecSqrtF32(const SDNode *N) const; bool useF32FTZ() const; bool allowFMA() const; bool doRsqrtOpt() const; bool doMADWideOpt() const; NVPTXScopes Scopes{}; public: NVPTXDAGToDAGISel() = delete; explicit NVPTXDAGToDAGISel(NVPTXTargetMachine &tm, CodeGenOptLevel OptLevel); bool runOnMachineFunction(MachineFunction &MF) override; const NVPTXSubtarget *Subtarget = nullptr; bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector &OutOps) override; private: // Include the pieces autogenerated from the target description. #include "NVPTXGenDAGISel.inc" void Select(SDNode *N) override; bool tryIntrinsicChain(SDNode *N); bool tryIntrinsicVoid(SDNode *N); void SelectTexSurfHandle(SDNode *N); bool tryLoad(SDNode *N); bool tryLoadVector(SDNode *N); bool tryLDU(SDNode *N); bool tryLDG(MemSDNode *N); bool tryStore(SDNode *N); bool tryStoreVector(SDNode *N); bool tryFence(SDNode *N); void SelectAddrSpaceCast(SDNode *N); bool tryBFE(SDNode *N); bool tryBF16ArithToFMA(SDNode *N); bool tryConstantFP(SDNode *N); bool SelectSETP_F16X2(SDNode *N); bool SelectSETP_BF16X2(SDNode *N); bool tryUNPACK_VECTOR(SDNode *N); bool tryEXTRACT_VECTOR_ELEMENT(SDNode *N); void SelectV2I64toI128(SDNode *N); void SelectI128toV2I64(SDNode *N); void SelectCpAsyncBulkTensorG2SCommon(SDNode *N, bool IsIm2Col = false); void SelectCpAsyncBulkTensorReduceCommon(SDNode *N, unsigned RedOp, bool IsIm2Col = false); void SelectTcgen05Ld(SDNode *N, bool hasOffset = false); void SelectTcgen05St(SDNode *N, bool hasOffset = false); void selectAtomicSwap128(SDNode *N); inline SDValue getI32Imm(unsigned Imm, const SDLoc &DL) { return CurDAG->getTargetConstant(Imm, DL, MVT::i32); } NVPTX::Ordering getMemOrder(const MemSDNode *N) const; NVPTX::Scope getAtomicScope(const MemSDNode *N) const; bool SelectADDR(SDValue Addr, SDValue &Base, SDValue &Offset); SDValue getPTXCmpMode(const CondCodeSDNode &CondCode); SDValue selectPossiblyImm(SDValue V); // Returns the Memory Order and Scope that the PTX memory instruction should // use, and inserts appropriate fence instruction before the memory // instruction, if needed to implement the instructions memory order. Required // fences after the instruction need to be handled elsewhere. std::pair insertMemoryInstructionFence(SDLoc DL, SDValue &Chain, MemSDNode *N); NVPTX::Scope getOperationScope(MemSDNode *N, NVPTX::Ordering O) const; public: static NVPTX::AddressSpace getAddrSpace(const MemSDNode *N); static unsigned getFromTypeWidthForLoad(const MemSDNode *Mem); }; class NVPTXDAGToDAGISelLegacy : public SelectionDAGISelLegacy { public: static char ID; explicit NVPTXDAGToDAGISelLegacy(NVPTXTargetMachine &tm, CodeGenOptLevel OptLevel); }; } // end namespace llvm #endif