Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | //===- TargetGlobalISel.td - Common code for GlobalISel ----*- tablegen -*-===// |
| 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 the target-independent interfaces used to support |
||
| 10 | // SelectionDAG instruction selection patterns (specified in |
||
| 11 | // TargetSelectionDAG.td) when generating GlobalISel instruction selectors. |
||
| 12 | // |
||
| 13 | // This is intended as a compatibility layer, to enable reuse of target |
||
| 14 | // descriptions written for SelectionDAG without requiring explicit GlobalISel |
||
| 15 | // support. It will eventually supersede SelectionDAG patterns. |
||
| 16 | // |
||
| 17 | //===----------------------------------------------------------------------===// |
||
| 18 | |||
| 19 | // Declare that a generic Instruction is 'equivalent' to an SDNode, that is, |
||
| 20 | // SelectionDAG patterns involving the SDNode can be transformed to match the |
||
| 21 | // Instruction instead. |
||
| 22 | class GINodeEquiv<Instruction i, SDNode node> { |
||
| 23 | Instruction I = i; |
||
| 24 | SDNode Node = node; |
||
| 25 | |||
| 26 | // SelectionDAG has separate nodes for atomic and non-atomic memory operations |
||
| 27 | // (ISD::LOAD, ISD::ATOMIC_LOAD, ISD::STORE, ISD::ATOMIC_STORE) but GlobalISel |
||
| 28 | // stores this information in the MachineMemoryOperand. |
||
| 29 | bit CheckMMOIsNonAtomic = false; |
||
| 30 | bit CheckMMOIsAtomic = false; |
||
| 31 | |||
| 32 | // SelectionDAG has one node for all loads and uses predicates to |
||
| 33 | // differentiate them. GlobalISel on the other hand uses separate opcodes. |
||
| 34 | // When this is true, the resulting opcode is G_LOAD/G_SEXTLOAD/G_ZEXTLOAD |
||
| 35 | // depending on the predicates on the node. |
||
| 36 | Instruction IfSignExtend = ?; |
||
| 37 | Instruction IfZeroExtend = ?; |
||
| 38 | |||
| 39 | // SelectionDAG has one setcc for all compares. This differentiates |
||
| 40 | // for G_ICMP and G_FCMP. |
||
| 41 | Instruction IfFloatingPoint = ?; |
||
| 42 | } |
||
| 43 | |||
| 44 | // These are defined in the same order as the G_* instructions. |
||
| 45 | def : GINodeEquiv<G_ANYEXT, anyext>; |
||
| 46 | def : GINodeEquiv<G_SEXT, sext>; |
||
| 47 | def : GINodeEquiv<G_ZEXT, zext>; |
||
| 48 | def : GINodeEquiv<G_TRUNC, trunc>; |
||
| 49 | def : GINodeEquiv<G_BITCAST, bitconvert>; |
||
| 50 | // G_INTTOPTR - SelectionDAG has no equivalent. |
||
| 51 | // G_PTRTOINT - SelectionDAG has no equivalent. |
||
| 52 | def : GINodeEquiv<G_CONSTANT, imm>; |
||
| 53 | // timm must not be materialized and therefore has no GlobalISel equivalent |
||
| 54 | def : GINodeEquiv<G_FCONSTANT, fpimm>; |
||
| 55 | def : GINodeEquiv<G_IMPLICIT_DEF, undef>; |
||
| 56 | def : GINodeEquiv<G_FRAME_INDEX, frameindex>; |
||
| 57 | def : GINodeEquiv<G_BLOCK_ADDR, blockaddress>; |
||
| 58 | def : GINodeEquiv<G_PTR_ADD, ptradd>; |
||
| 59 | def : GINodeEquiv<G_ADD, add>; |
||
| 60 | def : GINodeEquiv<G_SUB, sub>; |
||
| 61 | def : GINodeEquiv<G_MUL, mul>; |
||
| 62 | def : GINodeEquiv<G_UMULH, mulhu>; |
||
| 63 | def : GINodeEquiv<G_SMULH, mulhs>; |
||
| 64 | def : GINodeEquiv<G_SDIV, sdiv>; |
||
| 65 | def : GINodeEquiv<G_UDIV, udiv>; |
||
| 66 | def : GINodeEquiv<G_SREM, srem>; |
||
| 67 | def : GINodeEquiv<G_UREM, urem>; |
||
| 68 | def : GINodeEquiv<G_AND, and>; |
||
| 69 | def : GINodeEquiv<G_OR, or>; |
||
| 70 | def : GINodeEquiv<G_XOR, xor>; |
||
| 71 | def : GINodeEquiv<G_SHL, shl>; |
||
| 72 | def : GINodeEquiv<G_LSHR, srl>; |
||
| 73 | def : GINodeEquiv<G_ASHR, sra>; |
||
| 74 | def : GINodeEquiv<G_SADDSAT, saddsat>; |
||
| 75 | def : GINodeEquiv<G_UADDSAT, uaddsat>; |
||
| 76 | def : GINodeEquiv<G_SSUBSAT, ssubsat>; |
||
| 77 | def : GINodeEquiv<G_USUBSAT, usubsat>; |
||
| 78 | def : GINodeEquiv<G_SSHLSAT, sshlsat>; |
||
| 79 | def : GINodeEquiv<G_USHLSAT, ushlsat>; |
||
| 80 | def : GINodeEquiv<G_SMULFIX, smulfix>; |
||
| 81 | def : GINodeEquiv<G_UMULFIX, umulfix>; |
||
| 82 | def : GINodeEquiv<G_SMULFIXSAT, smulfixsat>; |
||
| 83 | def : GINodeEquiv<G_UMULFIXSAT, umulfixsat>; |
||
| 84 | def : GINodeEquiv<G_SDIVFIX, sdivfix>; |
||
| 85 | def : GINodeEquiv<G_UDIVFIX, udivfix>; |
||
| 86 | def : GINodeEquiv<G_SDIVFIXSAT, sdivfixsat>; |
||
| 87 | def : GINodeEquiv<G_UDIVFIXSAT, udivfixsat>; |
||
| 88 | def : GINodeEquiv<G_SELECT, select>; |
||
| 89 | def : GINodeEquiv<G_FNEG, fneg>; |
||
| 90 | def : GINodeEquiv<G_FPEXT, fpextend>; |
||
| 91 | def : GINodeEquiv<G_FPTRUNC, fpround>; |
||
| 92 | def : GINodeEquiv<G_FPTOSI, fp_to_sint>; |
||
| 93 | def : GINodeEquiv<G_FPTOUI, fp_to_uint>; |
||
| 94 | def : GINodeEquiv<G_SITOFP, sint_to_fp>; |
||
| 95 | def : GINodeEquiv<G_UITOFP, uint_to_fp>; |
||
| 96 | def : GINodeEquiv<G_FADD, fadd>; |
||
| 97 | def : GINodeEquiv<G_FSUB, fsub>; |
||
| 98 | def : GINodeEquiv<G_FMA, fma>; |
||
| 99 | def : GINodeEquiv<G_FMAD, fmad>; |
||
| 100 | def : GINodeEquiv<G_FMUL, fmul>; |
||
| 101 | def : GINodeEquiv<G_FDIV, fdiv>; |
||
| 102 | def : GINodeEquiv<G_FREM, frem>; |
||
| 103 | def : GINodeEquiv<G_FPOW, fpow>; |
||
| 104 | def : GINodeEquiv<G_FEXP2, fexp2>; |
||
| 105 | def : GINodeEquiv<G_FLOG2, flog2>; |
||
| 106 | def : GINodeEquiv<G_FCANONICALIZE, fcanonicalize>; |
||
| 107 | def : GINodeEquiv<G_IS_FPCLASS, is_fpclass>; |
||
| 108 | def : GINodeEquiv<G_INTRINSIC, intrinsic_wo_chain>; |
||
| 109 | // ISD::INTRINSIC_VOID can also be handled with G_INTRINSIC_W_SIDE_EFFECTS. |
||
| 110 | def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_void>; |
||
| 111 | def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_w_chain>; |
||
| 112 | def : GINodeEquiv<G_BR, br>; |
||
| 113 | def : GINodeEquiv<G_BSWAP, bswap>; |
||
| 114 | def : GINodeEquiv<G_BITREVERSE, bitreverse>; |
||
| 115 | def : GINodeEquiv<G_FSHL, fshl>; |
||
| 116 | def : GINodeEquiv<G_FSHR, fshr>; |
||
| 117 | def : GINodeEquiv<G_CTLZ, ctlz>; |
||
| 118 | def : GINodeEquiv<G_CTTZ, cttz>; |
||
| 119 | def : GINodeEquiv<G_CTLZ_ZERO_UNDEF, ctlz_zero_undef>; |
||
| 120 | def : GINodeEquiv<G_CTTZ_ZERO_UNDEF, cttz_zero_undef>; |
||
| 121 | def : GINodeEquiv<G_CTPOP, ctpop>; |
||
| 122 | def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, extractelt>; |
||
| 123 | def : GINodeEquiv<G_CONCAT_VECTORS, concat_vectors>; |
||
| 124 | def : GINodeEquiv<G_BUILD_VECTOR, build_vector>; |
||
| 125 | def : GINodeEquiv<G_FCEIL, fceil>; |
||
| 126 | def : GINodeEquiv<G_FCOS, fcos>; |
||
| 127 | def : GINodeEquiv<G_FSIN, fsin>; |
||
| 128 | def : GINodeEquiv<G_FABS, fabs>; |
||
| 129 | def : GINodeEquiv<G_FSQRT, fsqrt>; |
||
| 130 | def : GINodeEquiv<G_FFLOOR, ffloor>; |
||
| 131 | def : GINodeEquiv<G_FRINT, frint>; |
||
| 132 | def : GINodeEquiv<G_FNEARBYINT, fnearbyint>; |
||
| 133 | def : GINodeEquiv<G_INTRINSIC_TRUNC, ftrunc>; |
||
| 134 | def : GINodeEquiv<G_INTRINSIC_ROUND, fround>; |
||
| 135 | def : GINodeEquiv<G_INTRINSIC_LRINT, lrint>; |
||
| 136 | def : GINodeEquiv<G_FCOPYSIGN, fcopysign>; |
||
| 137 | def : GINodeEquiv<G_SMIN, smin>; |
||
| 138 | def : GINodeEquiv<G_SMAX, smax>; |
||
| 139 | def : GINodeEquiv<G_UMIN, umin>; |
||
| 140 | def : GINodeEquiv<G_UMAX, umax>; |
||
| 141 | def : GINodeEquiv<G_ABS, abs>; |
||
| 142 | def : GINodeEquiv<G_FMINNUM, fminnum>; |
||
| 143 | def : GINodeEquiv<G_FMAXNUM, fmaxnum>; |
||
| 144 | def : GINodeEquiv<G_FMINNUM_IEEE, fminnum_ieee>; |
||
| 145 | def : GINodeEquiv<G_FMAXNUM_IEEE, fmaxnum_ieee>; |
||
| 146 | def : GINodeEquiv<G_FMAXIMUM, fmaximum>; |
||
| 147 | def : GINodeEquiv<G_FMINIMUM, fminimum>; |
||
| 148 | def : GINodeEquiv<G_READCYCLECOUNTER, readcyclecounter>; |
||
| 149 | def : GINodeEquiv<G_ROTR, rotr>; |
||
| 150 | def : GINodeEquiv<G_ROTL, rotl>; |
||
| 151 | def : GINodeEquiv<G_LROUND, lround>; |
||
| 152 | def : GINodeEquiv<G_LLROUND, llround>; |
||
| 153 | |||
| 154 | def : GINodeEquiv<G_STRICT_FADD, strict_fadd>; |
||
| 155 | def : GINodeEquiv<G_STRICT_FSUB, strict_fsub>; |
||
| 156 | def : GINodeEquiv<G_STRICT_FMUL, strict_fmul>; |
||
| 157 | def : GINodeEquiv<G_STRICT_FDIV, strict_fdiv>; |
||
| 158 | def : GINodeEquiv<G_STRICT_FREM, strict_frem>; |
||
| 159 | def : GINodeEquiv<G_STRICT_FMA, strict_fma>; |
||
| 160 | def : GINodeEquiv<G_STRICT_FSQRT, strict_fsqrt>; |
||
| 161 | |||
| 162 | // Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some |
||
| 163 | // complications that tablegen must take care of. For example, Predicates such |
||
| 164 | // as isSignExtLoad require that this is not a perfect 1:1 mapping since a |
||
| 165 | // sign-extending load is (G_SEXTLOAD x) in GlobalISel. Additionally, |
||
| 166 | // G_LOAD handles both atomic and non-atomic loads where as SelectionDAG had |
||
| 167 | // separate nodes for them. This GINodeEquiv maps the non-atomic loads to |
||
| 168 | // G_LOAD with a non-atomic MachineMemOperand. |
||
| 169 | def : GINodeEquiv<G_LOAD, ld> { |
||
| 170 | let CheckMMOIsNonAtomic = true; |
||
| 171 | let IfSignExtend = G_SEXTLOAD; |
||
| 172 | let IfZeroExtend = G_ZEXTLOAD; |
||
| 173 | } |
||
| 174 | |||
| 175 | def : GINodeEquiv<G_ICMP, setcc> { |
||
| 176 | let IfFloatingPoint = G_FCMP; |
||
| 177 | } |
||
| 178 | |||
| 179 | // Broadly speaking G_STORE is equivalent to ISD::STORE but there are some |
||
| 180 | // complications that tablegen must take care of. For example, predicates such |
||
| 181 | // as isTruncStore require that this is not a perfect 1:1 mapping since a |
||
| 182 | // truncating store is (G_STORE (G_TRUNCATE x)) in GlobalISel. Additionally, |
||
| 183 | // G_STORE handles both atomic and non-atomic stores where as SelectionDAG had |
||
| 184 | // separate nodes for them. This GINodeEquiv maps the non-atomic stores to |
||
| 185 | // G_STORE with a non-atomic MachineMemOperand. |
||
| 186 | def : GINodeEquiv<G_STORE, st> { let CheckMMOIsNonAtomic = true; } |
||
| 187 | |||
| 188 | def : GINodeEquiv<G_LOAD, atomic_load> { |
||
| 189 | let CheckMMOIsNonAtomic = false; |
||
| 190 | let CheckMMOIsAtomic = true; |
||
| 191 | let IfSignExtend = G_SEXTLOAD; |
||
| 192 | let IfZeroExtend = G_ZEXTLOAD; |
||
| 193 | } |
||
| 194 | |||
| 195 | // Operands are swapped for atomic_store vs. regular store |
||
| 196 | def : GINodeEquiv<G_STORE, atomic_store> { |
||
| 197 | let CheckMMOIsNonAtomic = false; |
||
| 198 | let CheckMMOIsAtomic = true; |
||
| 199 | } |
||
| 200 | |||
| 201 | def : GINodeEquiv<G_ATOMIC_CMPXCHG, atomic_cmp_swap>; |
||
| 202 | def : GINodeEquiv<G_ATOMICRMW_XCHG, atomic_swap>; |
||
| 203 | def : GINodeEquiv<G_ATOMICRMW_ADD, atomic_load_add>; |
||
| 204 | def : GINodeEquiv<G_ATOMICRMW_SUB, atomic_load_sub>; |
||
| 205 | def : GINodeEquiv<G_ATOMICRMW_AND, atomic_load_and>; |
||
| 206 | def : GINodeEquiv<G_ATOMICRMW_NAND, atomic_load_nand>; |
||
| 207 | def : GINodeEquiv<G_ATOMICRMW_OR, atomic_load_or>; |
||
| 208 | def : GINodeEquiv<G_ATOMICRMW_XOR, atomic_load_xor>; |
||
| 209 | def : GINodeEquiv<G_ATOMICRMW_MIN, atomic_load_min>; |
||
| 210 | def : GINodeEquiv<G_ATOMICRMW_MAX, atomic_load_max>; |
||
| 211 | def : GINodeEquiv<G_ATOMICRMW_UMIN, atomic_load_umin>; |
||
| 212 | def : GINodeEquiv<G_ATOMICRMW_UMAX, atomic_load_umax>; |
||
| 213 | def : GINodeEquiv<G_ATOMICRMW_FADD, atomic_load_fadd>; |
||
| 214 | def : GINodeEquiv<G_ATOMICRMW_FSUB, atomic_load_fsub>; |
||
| 215 | def : GINodeEquiv<G_ATOMICRMW_FMAX, atomic_load_fmax>; |
||
| 216 | def : GINodeEquiv<G_ATOMICRMW_FMIN, atomic_load_fmin>; |
||
| 217 | def : GINodeEquiv<G_ATOMICRMW_UINC_WRAP, atomic_load_uinc_wrap>; |
||
| 218 | def : GINodeEquiv<G_ATOMICRMW_UDEC_WRAP, atomic_load_udec_wrap>; |
||
| 219 | def : GINodeEquiv<G_FENCE, atomic_fence>; |
||
| 220 | |||
| 221 | // Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern. |
||
| 222 | // Should be used on defs that subclass GIComplexOperandMatcher<>. |
||
| 223 | class GIComplexPatternEquiv<ComplexPattern seldag> { |
||
| 224 | ComplexPattern SelDAGEquivalent = seldag; |
||
| 225 | } |
||
| 226 | |||
| 227 | // Specifies the GlobalISel equivalents for SelectionDAG's SDNodeXForm. |
||
| 228 | // Should be used on defs that subclass GICustomOperandRenderer<>. |
||
| 229 | class GISDNodeXFormEquiv<SDNodeXForm seldag> { |
||
| 230 | SDNodeXForm SelDAGEquivalent = seldag; |
||
| 231 | } |