1 //===---- RISCVISelDAGToDAG.h - A dag to dag inst selector for RISC-V -----===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines an instruction selector for the RISC-V target. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H 14 #define LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H 15 16 #include "RISCV.h" 17 #include "RISCVTargetMachine.h" 18 #include "llvm/CodeGen/SelectionDAGISel.h" 19 #include "llvm/Support/KnownBits.h" 20 21 // RISC-V specific code to select RISC-V machine instructions for 22 // SelectionDAG operations. 23 namespace llvm { 24 class RISCVDAGToDAGISel : public SelectionDAGISel { 25 const RISCVSubtarget *Subtarget = nullptr; 26 27 public: 28 RISCVDAGToDAGISel() = delete; 29 RISCVDAGToDAGISel(RISCVTargetMachine & TargetMachine,CodeGenOptLevel OptLevel)30 explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine, 31 CodeGenOptLevel OptLevel) 32 : SelectionDAGISel(TargetMachine, OptLevel) {} 33 runOnMachineFunction(MachineFunction & MF)34 bool runOnMachineFunction(MachineFunction &MF) override { 35 Subtarget = &MF.getSubtarget<RISCVSubtarget>(); 36 return SelectionDAGISel::runOnMachineFunction(MF); 37 } 38 39 void PreprocessISelDAG() override; 40 void PostprocessISelDAG() override; 41 42 void Select(SDNode *Node) override; 43 44 bool SelectInlineAsmMemoryOperand(const SDValue &Op, 45 InlineAsm::ConstraintCode ConstraintID, 46 std::vector<SDValue> &OutOps) override; 47 48 bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset); 49 bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset); 50 bool SelectAddrRegImm9(SDValue Addr, SDValue &Base, SDValue &Offset); 51 bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset); 52 53 bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount, 54 SDValue &Base, SDValue &Index, SDValue &Scale); 55 56 template <unsigned MaxShift> SelectAddrRegRegScale(SDValue Addr,SDValue & Base,SDValue & Index,SDValue & Scale)57 bool SelectAddrRegRegScale(SDValue Addr, SDValue &Base, SDValue &Index, 58 SDValue &Scale) { 59 return SelectAddrRegRegScale(Addr, MaxShift, Base, Index, Scale); 60 } 61 62 template <unsigned MaxShift, unsigned Bits> SelectAddrRegZextRegScale(SDValue Addr,SDValue & Base,SDValue & Index,SDValue & Scale)63 bool SelectAddrRegZextRegScale(SDValue Addr, SDValue &Base, SDValue &Index, 64 SDValue &Scale) { 65 if (SelectAddrRegRegScale(Addr, MaxShift, Base, Index, Scale)) { 66 if (Index.getOpcode() == ISD::AND) { 67 auto *C = dyn_cast<ConstantSDNode>(Index.getOperand(1)); 68 if (C && C->getZExtValue() == maskTrailingOnes<uint64_t>(Bits)) { 69 Index = Index.getOperand(0); 70 return true; 71 } 72 } 73 } 74 return false; 75 } 76 77 bool SelectAddrRegReg(SDValue Addr, SDValue &Base, SDValue &Offset); 78 79 bool tryShrinkShlLogicImm(SDNode *Node); 80 bool trySignedBitfieldExtract(SDNode *Node); 81 bool trySignedBitfieldInsertInSign(SDNode *Node); 82 bool trySignedBitfieldInsertInMask(SDNode *Node); 83 bool tryUnsignedBitfieldExtract(SDNode *Node, const SDLoc &DL, MVT VT, 84 SDValue X, unsigned Msb, unsigned Lsb); 85 bool tryUnsignedBitfieldInsertInZero(SDNode *Node, const SDLoc &DL, MVT VT, 86 SDValue X, unsigned Msb, unsigned Lsb); 87 bool tryIndexedLoad(SDNode *Node); 88 89 bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt); selectShiftMaskXLen(SDValue N,SDValue & ShAmt)90 bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) { 91 return selectShiftMask(N, Subtarget->getXLen(), ShAmt); 92 } selectShiftMask32(SDValue N,SDValue & ShAmt)93 bool selectShiftMask32(SDValue N, SDValue &ShAmt) { 94 return selectShiftMask(N, 32, ShAmt); 95 } 96 97 bool selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal, SDValue &Val); selectSETNE(SDValue N,SDValue & Val)98 bool selectSETNE(SDValue N, SDValue &Val) { 99 return selectSETCC(N, ISD::SETNE, Val); 100 } selectSETEQ(SDValue N,SDValue & Val)101 bool selectSETEQ(SDValue N, SDValue &Val) { 102 return selectSETCC(N, ISD::SETEQ, Val); 103 } 104 105 bool selectSExtBits(SDValue N, unsigned Bits, SDValue &Val); selectSExtBits(SDValue N,SDValue & Val)106 template <unsigned Bits> bool selectSExtBits(SDValue N, SDValue &Val) { 107 return selectSExtBits(N, Bits, Val); 108 } 109 bool selectZExtBits(SDValue N, unsigned Bits, SDValue &Val); selectZExtBits(SDValue N,SDValue & Val)110 template <unsigned Bits> bool selectZExtBits(SDValue N, SDValue &Val) { 111 return selectZExtBits(N, Bits, Val); 112 } 113 114 bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val); selectSHXADDOp(SDValue N,SDValue & Val)115 template <unsigned ShAmt> bool selectSHXADDOp(SDValue N, SDValue &Val) { 116 return selectSHXADDOp(N, ShAmt, Val); 117 } 118 119 bool selectSHXADD_UWOp(SDValue N, unsigned ShAmt, SDValue &Val); selectSHXADD_UWOp(SDValue N,SDValue & Val)120 template <unsigned ShAmt> bool selectSHXADD_UWOp(SDValue N, SDValue &Val) { 121 return selectSHXADD_UWOp(N, ShAmt, Val); 122 } 123 124 bool selectZExtImm32(SDValue N, SDValue &Val); 125 bool selectNegImm(SDValue N, SDValue &Val); 126 bool selectInvLogicImm(SDValue N, SDValue &Val); 127 128 bool orDisjoint(const SDNode *Node) const; 129 bool hasAllNBitUsers(SDNode *Node, unsigned Bits, 130 const unsigned Depth = 0) const; hasAllBUsers(SDNode * Node)131 bool hasAllBUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 8); } hasAllHUsers(SDNode * Node)132 bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); } hasAllWUsers(SDNode * Node)133 bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); } 134 135 bool selectSimm5Shl2(SDValue N, SDValue &Simm5, SDValue &Shl2); 136 137 bool selectVLOp(SDValue N, SDValue &VL); 138 139 bool selectVSplat(SDValue N, SDValue &SplatVal); 140 bool selectVSplatSimm5(SDValue N, SDValue &SplatVal); 141 bool selectVSplatUimm(SDValue N, unsigned Bits, SDValue &SplatVal); selectVSplatUimmBits(SDValue N,SDValue & Val)142 template <unsigned Bits> bool selectVSplatUimmBits(SDValue N, SDValue &Val) { 143 return selectVSplatUimm(N, Bits, Val); 144 } 145 bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal); 146 bool selectVSplatSimm5Plus1NoDec(SDValue N, SDValue &SplatVal); 147 bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal); 148 bool selectVSplatImm64Neg(SDValue N, SDValue &SplatVal); 149 // Matches the splat of a value which can be extended or truncated, such that 150 // only the bottom 8 bits are preserved. 151 bool selectLow8BitsVSplat(SDValue N, SDValue &SplatVal); 152 bool selectScalarFPAsInt(SDValue N, SDValue &Imm); 153 154 bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm); selectRVVSimm5(SDValue N,SDValue & Imm)155 template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) { 156 return selectRVVSimm5(N, Width, Imm); 157 } 158 159 void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm, 160 const SDLoc &DL, unsigned CurOp, 161 bool IsMasked, bool IsStridedOrIndexed, 162 SmallVectorImpl<SDValue> &Operands, 163 bool IsLoad = false, MVT *IndexVT = nullptr); 164 165 void selectVLSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided); 166 void selectVLSEGFF(SDNode *Node, unsigned NF, bool IsMasked); 167 void selectVLXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered); 168 void selectVSSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided); 169 void selectVSXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered); 170 171 void selectVSETVLI(SDNode *Node); 172 173 void selectSF_VC_X_SE(SDNode *Node); 174 175 // Return the RISC-V condition code that matches the given DAG integer 176 // condition code. The CondCode must be one of those supported by the RISC-V 177 // ISA (see translateSetCCForBranch). getRISCVCCForIntCC(ISD::CondCode CC)178 static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) { 179 switch (CC) { 180 default: 181 llvm_unreachable("Unsupported CondCode"); 182 case ISD::SETEQ: 183 return RISCVCC::COND_EQ; 184 case ISD::SETNE: 185 return RISCVCC::COND_NE; 186 case ISD::SETLT: 187 return RISCVCC::COND_LT; 188 case ISD::SETGE: 189 return RISCVCC::COND_GE; 190 case ISD::SETULT: 191 return RISCVCC::COND_LTU; 192 case ISD::SETUGE: 193 return RISCVCC::COND_GEU; 194 } 195 } 196 197 // Include the pieces autogenerated from the target description. 198 #define GET_DAGISEL_DECL 199 #include "RISCVGenDAGISel.inc" 200 201 private: 202 bool doPeepholeSExtW(SDNode *Node); 203 bool doPeepholeMaskedRVV(MachineSDNode *Node); 204 bool doPeepholeNoRegPassThru(); 205 bool performCombineVMergeAndVOps(SDNode *N); 206 bool selectImm64IfCheaper(int64_t Imm, int64_t OrigImm, SDValue N, 207 SDValue &Val); 208 }; 209 210 class RISCVDAGToDAGISelLegacy : public SelectionDAGISelLegacy { 211 public: 212 static char ID; 213 explicit RISCVDAGToDAGISelLegacy(RISCVTargetMachine &TargetMachine, 214 CodeGenOptLevel OptLevel); 215 }; 216 217 } // namespace llvm 218 219 #endif 220