Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 1 | //== llvm/CodeGen/GlobalISel/LegalizerHelper.h ---------------- -*- C++ -*-==// |
| 2 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 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 |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | /// \file A pass to convert the target-illegal operations created by IR -> MIR |
| 10 | /// translation into ones the target expects to be able to select. This may |
| 11 | /// occur in multiple phases, for example G_ADD <2 x i8> -> G_ADD <2 x i16> -> |
| 12 | /// G_ADD <4 x i16>. |
| 13 | /// |
| 14 | /// The LegalizerHelper class is where most of the work happens, and is |
| 15 | /// designed to be callable from other passes that find themselves with an |
| 16 | /// illegal instruction. |
| 17 | // |
| 18 | //===----------------------------------------------------------------------===// |
| 19 | |
| 20 | #ifndef LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H |
| 21 | #define LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H |
| 22 | |
| 23 | #include "llvm/CodeGen/GlobalISel/CallLowering.h" |
| 24 | #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" |
| 25 | #include "llvm/CodeGen/LowLevelType.h" |
| 26 | #include "llvm/CodeGen/MachineFunctionPass.h" |
| 27 | #include "llvm/CodeGen/RuntimeLibcalls.h" |
| 28 | |
| 29 | namespace llvm { |
| 30 | // Forward declarations. |
| 31 | class LegalizerInfo; |
| 32 | class Legalizer; |
| 33 | class MachineRegisterInfo; |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 34 | class GISelChangeObserver; |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 35 | class TargetLowering; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 36 | |
| 37 | class LegalizerHelper { |
| 38 | public: |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 39 | /// Expose MIRBuilder so clients can set their own RecordInsertInstruction |
| 40 | /// functions |
| 41 | MachineIRBuilder &MIRBuilder; |
| 42 | |
| 43 | /// To keep track of changes made by the LegalizerHelper. |
| 44 | GISelChangeObserver &Observer; |
| 45 | |
| 46 | private: |
| 47 | MachineRegisterInfo &MRI; |
| 48 | const LegalizerInfo &LI; |
| 49 | const TargetLowering &TLI; |
| 50 | |
| 51 | public: |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 52 | enum LegalizeResult { |
| 53 | /// Instruction was already legal and no change was made to the |
| 54 | /// MachineFunction. |
| 55 | AlreadyLegal, |
| 56 | |
| 57 | /// Instruction has been legalized and the MachineFunction changed. |
| 58 | Legalized, |
| 59 | |
| 60 | /// Some kind of error has occurred and we could not legalize this |
| 61 | /// instruction. |
| 62 | UnableToLegalize, |
| 63 | }; |
| 64 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 65 | /// Expose LegalizerInfo so the clients can re-use. |
| 66 | const LegalizerInfo &getLegalizerInfo() const { return LI; } |
| 67 | const TargetLowering &getTargetLowering() const { return TLI; } |
| 68 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 69 | LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer, |
| 70 | MachineIRBuilder &B); |
| 71 | LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI, |
| 72 | GISelChangeObserver &Observer, MachineIRBuilder &B); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 73 | |
| 74 | /// Replace \p MI by a sequence of legal instructions that can implement the |
| 75 | /// same operation. Note that this means \p MI may be deleted, so any iterator |
| 76 | /// steps should be performed before calling this function. \p Helper should |
| 77 | /// be initialized to the MachineFunction containing \p MI. |
| 78 | /// |
| 79 | /// Considered as an opaque blob, the legal code will use and define the same |
| 80 | /// registers as \p MI. |
| 81 | LegalizeResult legalizeInstrStep(MachineInstr &MI); |
| 82 | |
| 83 | /// Legalize an instruction by emiting a runtime library call instead. |
| 84 | LegalizeResult libcall(MachineInstr &MI); |
| 85 | |
| 86 | /// Legalize an instruction by reducing the width of the underlying scalar |
| 87 | /// type. |
| 88 | LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy); |
| 89 | |
| 90 | /// Legalize an instruction by performing the operation on a wider scalar type |
| 91 | /// (for example a 16-bit addition can be safely performed at 32-bits |
| 92 | /// precision, ignoring the unused bits). |
| 93 | LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); |
| 94 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 95 | /// Legalize an instruction by replacing the value type |
| 96 | LegalizeResult bitcast(MachineInstr &MI, unsigned TypeIdx, LLT Ty); |
| 97 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 98 | /// Legalize an instruction by splitting it into simpler parts, hopefully |
| 99 | /// understood by the target. |
| 100 | LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty); |
| 101 | |
| 102 | /// Legalize a vector instruction by splitting into multiple components, each |
| 103 | /// acting on the same scalar type as the original but with fewer elements. |
| 104 | LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, |
| 105 | LLT NarrowTy); |
| 106 | |
| 107 | /// Legalize a vector instruction by increasing the number of vector elements |
| 108 | /// involved and ignoring the added elements later. |
| 109 | LegalizeResult moreElementsVector(MachineInstr &MI, unsigned TypeIdx, |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 110 | LLT MoreTy); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 111 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 112 | /// Cast the given value to an LLT::scalar with an equivalent size. Returns |
| 113 | /// the register to use if an instruction was inserted. Returns the original |
| 114 | /// register if no coercion was necessary. |
| 115 | // |
| 116 | // This may also fail and return Register() if there is no legal way to cast. |
| 117 | Register coerceToScalar(Register Val); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 118 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 119 | /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a |
| 120 | /// Use by extending the operand's type to \p WideTy using the specified \p |
| 121 | /// ExtOpcode for the extension instruction, and replacing the vreg of the |
| 122 | /// operand in place. |
| 123 | void widenScalarSrc(MachineInstr &MI, LLT WideTy, unsigned OpIdx, |
| 124 | unsigned ExtOpcode); |
| 125 | |
| 126 | /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 127 | /// Use by truncating the operand's type to \p NarrowTy using G_TRUNC, and |
| 128 | /// replacing the vreg of the operand in place. |
| 129 | void narrowScalarSrc(MachineInstr &MI, LLT NarrowTy, unsigned OpIdx); |
| 130 | |
| 131 | /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 132 | /// Def by extending the operand's type to \p WideTy and truncating it back |
| 133 | /// with the \p TruncOpcode, and replacing the vreg of the operand in place. |
| 134 | void widenScalarDst(MachineInstr &MI, LLT WideTy, unsigned OpIdx = 0, |
| 135 | unsigned TruncOpcode = TargetOpcode::G_TRUNC); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 136 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 137 | // Legalize a single operand \p OpIdx of the machine instruction \p MI as a |
| 138 | // Def by truncating the operand's type to \p NarrowTy, replacing in place and |
| 139 | // extending back with \p ExtOpcode. |
| 140 | void narrowScalarDst(MachineInstr &MI, LLT NarrowTy, unsigned OpIdx, |
| 141 | unsigned ExtOpcode); |
| 142 | /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a |
| 143 | /// Def by performing it with additional vector elements and extracting the |
| 144 | /// result elements, and replacing the vreg of the operand in place. |
| 145 | void moreElementsVectorDst(MachineInstr &MI, LLT MoreTy, unsigned OpIdx); |
| 146 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 147 | /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a |
| 148 | /// Use by producing a vector with undefined high elements, extracting the |
| 149 | /// original vector type, and replacing the vreg of the operand in place. |
| 150 | void moreElementsVectorSrc(MachineInstr &MI, LLT MoreTy, unsigned OpIdx); |
| 151 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 152 | /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a |
| 153 | /// use by inserting a G_BITCAST to \p CastTy |
| 154 | void bitcastSrc(MachineInstr &MI, LLT CastTy, unsigned OpIdx); |
| 155 | |
| 156 | /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a |
| 157 | /// def by inserting a G_BITCAST from \p CastTy |
| 158 | void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx); |
| 159 | |
| 160 | /// Widen \p OrigReg to \p WideTy by merging to a wider type, padding with |
| 161 | /// G_IMPLICIT_DEF, and producing dead results. |
| 162 | Register widenWithUnmerge(LLT WideTy, Register OrigReg); |
| 163 | |
| 164 | private: |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 165 | LegalizeResult |
| 166 | widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); |
| 167 | LegalizeResult |
| 168 | widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); |
| 169 | LegalizeResult |
| 170 | widenScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); |
| 171 | LegalizeResult |
| 172 | widenScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 173 | LegalizeResult |
| 174 | widenScalarAddSubShlSat(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 175 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 176 | /// Helper function to split a wide generic register into bitwise blocks with |
| 177 | /// the given Type (which implies the number of blocks needed). The generic |
| 178 | /// registers created are appended to Ops, starting at bit 0 of Reg. |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 179 | void extractParts(Register Reg, LLT Ty, int NumParts, |
| 180 | SmallVectorImpl<Register> &VRegs); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 181 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 182 | /// Version which handles irregular splits. |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 183 | bool extractParts(Register Reg, LLT RegTy, LLT MainTy, |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 184 | LLT &LeftoverTy, |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 185 | SmallVectorImpl<Register> &VRegs, |
| 186 | SmallVectorImpl<Register> &LeftoverVRegs); |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 187 | |
| 188 | /// Helper function to build a wide generic register \p DstReg of type \p |
| 189 | /// RegTy from smaller parts. This will produce a G_MERGE_VALUES, |
| 190 | /// G_BUILD_VECTOR, G_CONCAT_VECTORS, or sequence of G_INSERT as appropriate |
| 191 | /// for the types. |
| 192 | /// |
| 193 | /// \p PartRegs must be registers of type \p PartTy. |
| 194 | /// |
| 195 | /// If \p ResultTy does not evenly break into \p PartTy sized pieces, the |
| 196 | /// remainder must be specified with \p LeftoverRegs of type \p LeftoverTy. |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 197 | void insertParts(Register DstReg, LLT ResultTy, |
| 198 | LLT PartTy, ArrayRef<Register> PartRegs, |
| 199 | LLT LeftoverTy = LLT(), ArrayRef<Register> LeftoverRegs = {}); |
| 200 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 201 | /// Unmerge \p SrcReg into smaller sized values, and append them to \p |
| 202 | /// Parts. The elements of \p Parts will be the greatest common divisor type |
| 203 | /// of \p DstTy, \p NarrowTy and the type of \p SrcReg. This will compute and |
| 204 | /// return the GCD type. |
| 205 | LLT extractGCDType(SmallVectorImpl<Register> &Parts, LLT DstTy, |
| 206 | LLT NarrowTy, Register SrcReg); |
| 207 | |
| 208 | /// Unmerge \p SrcReg into \p GCDTy typed registers. This will append all of |
| 209 | /// the unpacked registers to \p Parts. This version is if the common unmerge |
| 210 | /// type is already known. |
| 211 | void extractGCDType(SmallVectorImpl<Register> &Parts, LLT GCDTy, |
| 212 | Register SrcReg); |
| 213 | |
| 214 | /// Produce a merge of values in \p VRegs to define \p DstReg. Perform a merge |
| 215 | /// from the least common multiple type, and convert as appropriate to \p |
| 216 | /// DstReg. |
| 217 | /// |
| 218 | /// \p VRegs should each have type \p GCDTy. This type should be greatest |
| 219 | /// common divisor type of \p DstReg, \p NarrowTy, and an undetermined source |
| 220 | /// type. |
| 221 | /// |
| 222 | /// \p NarrowTy is the desired result merge source type. If the source value |
| 223 | /// needs to be widened to evenly cover \p DstReg, inserts high bits |
| 224 | /// corresponding to the extension opcode \p PadStrategy. |
| 225 | /// |
| 226 | /// \p VRegs will be cleared, and the the result \p NarrowTy register pieces |
| 227 | /// will replace it. Returns The complete LCMTy that \p VRegs will cover when |
| 228 | /// merged. |
| 229 | LLT buildLCMMergePieces(LLT DstTy, LLT NarrowTy, LLT GCDTy, |
| 230 | SmallVectorImpl<Register> &VRegs, |
| 231 | unsigned PadStrategy = TargetOpcode::G_ANYEXT); |
| 232 | |
| 233 | /// Merge the values in \p RemergeRegs to an \p LCMTy typed value. Extract the |
| 234 | /// low bits into \p DstReg. This is intended to use the outputs from |
| 235 | /// buildLCMMergePieces after processing. |
| 236 | void buildWidenedRemergeToDst(Register DstReg, LLT LCMTy, |
| 237 | ArrayRef<Register> RemergeRegs); |
| 238 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 239 | /// Perform generic multiplication of values held in multiple registers. |
| 240 | /// Generated instructions use only types NarrowTy and i1. |
| 241 | /// Destination can be same or two times size of the source. |
| 242 | void multiplyRegisters(SmallVectorImpl<Register> &DstRegs, |
| 243 | ArrayRef<Register> Src1Regs, |
| 244 | ArrayRef<Register> Src2Regs, LLT NarrowTy); |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 245 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 246 | void changeOpcode(MachineInstr &MI, unsigned NewOpcode); |
| 247 | |
| 248 | public: |
| 249 | /// Return the alignment to use for a stack temporary object with the given |
| 250 | /// type. |
| 251 | Align getStackTemporaryAlignment(LLT Type, Align MinAlign = Align()) const; |
| 252 | |
| 253 | /// Create a stack temporary based on the size in bytes and the alignment |
| 254 | MachineInstrBuilder createStackTemporary(TypeSize Bytes, Align Alignment, |
| 255 | MachinePointerInfo &PtrInfo); |
| 256 | |
| 257 | /// Get a pointer to vector element \p Index located in memory for a vector of |
| 258 | /// type \p VecTy starting at a base address of \p VecPtr. If \p Index is out |
| 259 | /// of bounds the returned pointer is unspecified, but will be within the |
| 260 | /// vector bounds. |
| 261 | Register getVectorElementPointer(Register VecPtr, LLT VecTy, Register Index); |
| 262 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 263 | LegalizeResult fewerElementsVectorImplicitDef(MachineInstr &MI, |
| 264 | unsigned TypeIdx, LLT NarrowTy); |
| 265 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 266 | /// Legalize a instruction with a vector type where each operand may have a |
| 267 | /// different element type. All type indexes must have the same number of |
| 268 | /// elements. |
| 269 | LegalizeResult fewerElementsVectorMultiEltType(MachineInstr &MI, |
| 270 | unsigned TypeIdx, LLT NarrowTy); |
| 271 | |
| 272 | LegalizeResult fewerElementsVectorCasts(MachineInstr &MI, unsigned TypeIdx, |
| 273 | LLT NarrowTy); |
| 274 | |
| 275 | LegalizeResult |
| 276 | fewerElementsVectorCmp(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy); |
| 277 | |
| 278 | LegalizeResult |
| 279 | fewerElementsVectorSelect(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy); |
| 280 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 281 | LegalizeResult fewerElementsVectorPhi(MachineInstr &MI, |
| 282 | unsigned TypeIdx, LLT NarrowTy); |
| 283 | |
| 284 | LegalizeResult moreElementsVectorPhi(MachineInstr &MI, unsigned TypeIdx, |
| 285 | LLT MoreTy); |
| 286 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 287 | LegalizeResult fewerElementsVectorUnmergeValues(MachineInstr &MI, |
| 288 | unsigned TypeIdx, |
| 289 | LLT NarrowTy); |
| 290 | LegalizeResult fewerElementsVectorMerge(MachineInstr &MI, unsigned TypeIdx, |
| 291 | LLT NarrowTy); |
| 292 | LegalizeResult fewerElementsVectorExtractInsertVectorElt(MachineInstr &MI, |
| 293 | unsigned TypeIdx, |
| 294 | LLT NarrowTy); |
| 295 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 296 | LegalizeResult |
| 297 | reduceLoadStoreWidth(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy); |
| 298 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 299 | /// Legalize an instruction by reducing the operation width, either by |
| 300 | /// narrowing the type of the operation or by reducing the number of elements |
| 301 | /// of a vector. |
| 302 | /// The used strategy (narrow vs. fewerElements) is decided by \p NarrowTy. |
| 303 | /// Narrow is used if the scalar type of \p NarrowTy and \p DstTy differ, |
| 304 | /// fewerElements is used when the scalar type is the same but the number of |
| 305 | /// elements between \p NarrowTy and \p DstTy differ. |
| 306 | LegalizeResult reduceOperationWidth(MachineInstr &MI, unsigned TypeIdx, |
| 307 | LLT NarrowTy); |
| 308 | |
| 309 | LegalizeResult fewerElementsVectorSextInReg(MachineInstr &MI, unsigned TypeIdx, |
| 310 | LLT NarrowTy); |
| 311 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 312 | LegalizeResult narrowScalarShiftByConstant(MachineInstr &MI, const APInt &Amt, |
| 313 | LLT HalfTy, LLT ShiftAmtTy); |
| 314 | |
| 315 | LegalizeResult narrowScalarShift(MachineInstr &MI, unsigned TypeIdx, LLT Ty); |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 316 | LegalizeResult narrowScalarMul(MachineInstr &MI, LLT Ty); |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 317 | LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty); |
| 318 | LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty); |
| 319 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 320 | LegalizeResult narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx, LLT Ty); |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 321 | LegalizeResult narrowScalarExt(MachineInstr &MI, unsigned TypeIdx, LLT Ty); |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 322 | LegalizeResult narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT Ty); |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 323 | LegalizeResult narrowScalarCTLZ(MachineInstr &MI, unsigned TypeIdx, LLT Ty); |
| 324 | LegalizeResult narrowScalarCTTZ(MachineInstr &MI, unsigned TypeIdx, LLT Ty); |
| 325 | LegalizeResult narrowScalarCTPOP(MachineInstr &MI, unsigned TypeIdx, LLT Ty); |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 326 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 327 | /// Perform Bitcast legalize action on G_EXTRACT_VECTOR_ELT. |
| 328 | LegalizeResult bitcastExtractVectorElt(MachineInstr &MI, unsigned TypeIdx, |
| 329 | LLT CastTy); |
| 330 | |
| 331 | /// Perform Bitcast legalize action on G_INSERT_VECTOR_ELT. |
| 332 | LegalizeResult bitcastInsertVectorElt(MachineInstr &MI, unsigned TypeIdx, |
| 333 | LLT CastTy); |
| 334 | |
| 335 | LegalizeResult lowerBitcast(MachineInstr &MI); |
| 336 | LegalizeResult lowerLoad(MachineInstr &MI); |
| 337 | LegalizeResult lowerStore(MachineInstr &MI); |
| 338 | LegalizeResult lowerBitCount(MachineInstr &MI); |
Andrew Scull | 0372a57 | 2018-11-16 15:47:06 +0000 | [diff] [blame] | 339 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 340 | LegalizeResult lowerU64ToF32BitOps(MachineInstr &MI); |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 341 | LegalizeResult lowerUITOFP(MachineInstr &MI); |
| 342 | LegalizeResult lowerSITOFP(MachineInstr &MI); |
| 343 | LegalizeResult lowerFPTOUI(MachineInstr &MI); |
| 344 | LegalizeResult lowerFPTOSI(MachineInstr &MI); |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 345 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 346 | LegalizeResult lowerFPTRUNC_F64_TO_F16(MachineInstr &MI); |
| 347 | LegalizeResult lowerFPTRUNC(MachineInstr &MI); |
| 348 | LegalizeResult lowerFPOWI(MachineInstr &MI); |
| 349 | |
| 350 | LegalizeResult lowerMinMax(MachineInstr &MI); |
| 351 | LegalizeResult lowerFCopySign(MachineInstr &MI); |
| 352 | LegalizeResult lowerFMinNumMaxNum(MachineInstr &MI); |
| 353 | LegalizeResult lowerFMad(MachineInstr &MI); |
| 354 | LegalizeResult lowerIntrinsicRound(MachineInstr &MI); |
| 355 | LegalizeResult lowerFFloor(MachineInstr &MI); |
| 356 | LegalizeResult lowerMergeValues(MachineInstr &MI); |
| 357 | LegalizeResult lowerUnmergeValues(MachineInstr &MI); |
| 358 | LegalizeResult lowerExtractInsertVectorElt(MachineInstr &MI); |
| 359 | LegalizeResult lowerShuffleVector(MachineInstr &MI); |
| 360 | LegalizeResult lowerDynStackAlloc(MachineInstr &MI); |
| 361 | LegalizeResult lowerExtract(MachineInstr &MI); |
| 362 | LegalizeResult lowerInsert(MachineInstr &MI); |
| 363 | LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI); |
| 364 | LegalizeResult lowerAddSubSatToMinMax(MachineInstr &MI); |
| 365 | LegalizeResult lowerAddSubSatToAddoSubo(MachineInstr &MI); |
| 366 | LegalizeResult lowerShlSat(MachineInstr &MI); |
| 367 | LegalizeResult lowerBswap(MachineInstr &MI); |
| 368 | LegalizeResult lowerBitreverse(MachineInstr &MI); |
| 369 | LegalizeResult lowerReadWriteRegister(MachineInstr &MI); |
| 370 | LegalizeResult lowerSMULH_UMULH(MachineInstr &MI); |
| 371 | LegalizeResult lowerSelect(MachineInstr &MI); |
| 372 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 373 | }; |
| 374 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 375 | /// Helper function that creates a libcall to the given \p Name using the given |
| 376 | /// calling convention \p CC. |
| 377 | LegalizerHelper::LegalizeResult |
| 378 | createLibcall(MachineIRBuilder &MIRBuilder, const char *Name, |
| 379 | const CallLowering::ArgInfo &Result, |
| 380 | ArrayRef<CallLowering::ArgInfo> Args, CallingConv::ID CC); |
| 381 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 382 | /// Helper function that creates the given libcall. |
| 383 | LegalizerHelper::LegalizeResult |
| 384 | createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, |
| 385 | const CallLowering::ArgInfo &Result, |
| 386 | ArrayRef<CallLowering::ArgInfo> Args); |
| 387 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 388 | /// Create a libcall to memcpy et al. |
| 389 | LegalizerHelper::LegalizeResult createMemLibcall(MachineIRBuilder &MIRBuilder, |
| 390 | MachineRegisterInfo &MRI, |
| 391 | MachineInstr &MI); |
| 392 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 393 | } // End namespace llvm. |
| 394 | |
| 395 | #endif |