1 //== llvm/CodeGen/GlobalISel/LegalizerHelper.h ---------------- -*- 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-exception 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_LEGALIZERHELPER_H 21 #define LLVM_CODEGEN_GLOBALISEL_LEGALIZERHELPER_H 22 23 #include "llvm/CodeGen/GlobalISel/CallLowering.h" 24 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 25 #include "llvm/CodeGen/RuntimeLibcallUtil.h" 26 #include "llvm/CodeGen/TargetOpcodes.h" 27 28 namespace llvm { 29 // Forward declarations. 30 class APInt; 31 class GAnyLoad; 32 class GLoadStore; 33 class GStore; 34 class GenericMachineInstr; 35 class MachineFunction; 36 class MachineIRBuilder; 37 class MachineInstr; 38 class MachineInstrBuilder; 39 struct MachinePointerInfo; 40 template <typename T> class SmallVectorImpl; 41 class LegalizerInfo; 42 class MachineRegisterInfo; 43 class GISelChangeObserver; 44 class LostDebugLocObserver; 45 class TargetLowering; 46 47 class LegalizerHelper { 48 public: 49 /// Expose MIRBuilder so clients can set their own RecordInsertInstruction 50 /// functions 51 MachineIRBuilder &MIRBuilder; 52 53 /// To keep track of changes made by the LegalizerHelper. 54 GISelChangeObserver &Observer; 55 56 private: 57 MachineRegisterInfo &MRI; 58 const LegalizerInfo &LI; 59 const TargetLowering &TLI; 60 GISelKnownBits *KB; 61 62 public: 63 enum LegalizeResult { 64 /// Instruction was already legal and no change was made to the 65 /// MachineFunction. 66 AlreadyLegal, 67 68 /// Instruction has been legalized and the MachineFunction changed. 69 Legalized, 70 71 /// Some kind of error has occurred and we could not legalize this 72 /// instruction. 73 UnableToLegalize, 74 }; 75 76 /// Expose LegalizerInfo so the clients can re-use. getLegalizerInfo()77 const LegalizerInfo &getLegalizerInfo() const { return LI; } getTargetLowering()78 const TargetLowering &getTargetLowering() const { return TLI; } getKnownBits()79 GISelKnownBits *getKnownBits() const { return KB; } 80 81 LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer, 82 MachineIRBuilder &B); 83 LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI, 84 GISelChangeObserver &Observer, MachineIRBuilder &B, 85 GISelKnownBits *KB = nullptr); 86 87 /// Replace \p MI by a sequence of legal instructions that can implement the 88 /// same operation. Note that this means \p MI may be deleted, so any iterator 89 /// steps should be performed before calling this function. \p Helper should 90 /// be initialized to the MachineFunction containing \p MI. 91 /// 92 /// Considered as an opaque blob, the legal code will use and define the same 93 /// registers as \p MI. 94 LegalizeResult legalizeInstrStep(MachineInstr &MI, 95 LostDebugLocObserver &LocObserver); 96 97 /// Legalize an instruction by emiting a runtime library call instead. 98 LegalizeResult libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver); 99 100 /// Legalize an instruction by reducing the width of the underlying scalar 101 /// type. 102 LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy); 103 104 /// Legalize an instruction by performing the operation on a wider scalar type 105 /// (for example a 16-bit addition can be safely performed at 32-bits 106 /// precision, ignoring the unused bits). 107 LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); 108 109 /// Legalize an instruction by replacing the value type 110 LegalizeResult bitcast(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 111 112 /// Legalize an instruction by splitting it into simpler parts, hopefully 113 /// understood by the target. 114 LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 115 116 /// Legalize a vector instruction by splitting into multiple components, each 117 /// acting on the same scalar type as the original but with fewer elements. 118 LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, 119 LLT NarrowTy); 120 121 /// Legalize a vector instruction by increasing the number of vector elements 122 /// involved and ignoring the added elements later. 123 LegalizeResult moreElementsVector(MachineInstr &MI, unsigned TypeIdx, 124 LLT MoreTy); 125 126 /// Cast the given value to an LLT::scalar with an equivalent size. Returns 127 /// the register to use if an instruction was inserted. Returns the original 128 /// register if no coercion was necessary. 129 // 130 // This may also fail and return Register() if there is no legal way to cast. 131 Register coerceToScalar(Register Val); 132 133 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 134 /// Use by extending the operand's type to \p WideTy using the specified \p 135 /// ExtOpcode for the extension instruction, and replacing the vreg of the 136 /// operand in place. 137 void widenScalarSrc(MachineInstr &MI, LLT WideTy, unsigned OpIdx, 138 unsigned ExtOpcode); 139 140 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 141 /// Use by truncating the operand's type to \p NarrowTy using G_TRUNC, and 142 /// replacing the vreg of the operand in place. 143 void narrowScalarSrc(MachineInstr &MI, LLT NarrowTy, unsigned OpIdx); 144 145 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 146 /// Def by extending the operand's type to \p WideTy and truncating it back 147 /// with the \p TruncOpcode, and replacing the vreg of the operand in place. 148 void widenScalarDst(MachineInstr &MI, LLT WideTy, unsigned OpIdx = 0, 149 unsigned TruncOpcode = TargetOpcode::G_TRUNC); 150 151 // Legalize a single operand \p OpIdx of the machine instruction \p MI as a 152 // Def by truncating the operand's type to \p NarrowTy, replacing in place and 153 // extending back with \p ExtOpcode. 154 void narrowScalarDst(MachineInstr &MI, LLT NarrowTy, unsigned OpIdx, 155 unsigned ExtOpcode); 156 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 157 /// Def by performing it with additional vector elements and extracting the 158 /// result elements, and replacing the vreg of the operand in place. 159 void moreElementsVectorDst(MachineInstr &MI, LLT MoreTy, unsigned OpIdx); 160 161 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 162 /// Use by producing a vector with undefined high elements, extracting the 163 /// original vector type, and replacing the vreg of the operand in place. 164 void moreElementsVectorSrc(MachineInstr &MI, LLT MoreTy, unsigned OpIdx); 165 166 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 167 /// use by inserting a G_BITCAST to \p CastTy 168 void bitcastSrc(MachineInstr &MI, LLT CastTy, unsigned OpIdx); 169 170 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 171 /// def by inserting a G_BITCAST from \p CastTy 172 void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx); 173 174 private: 175 LegalizeResult 176 widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); 177 LegalizeResult 178 widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); 179 LegalizeResult 180 widenScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); 181 LegalizeResult 182 widenScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); 183 LegalizeResult widenScalarAddSubOverflow(MachineInstr &MI, unsigned TypeIdx, 184 LLT WideTy); 185 LegalizeResult widenScalarAddSubShlSat(MachineInstr &MI, unsigned TypeIdx, 186 LLT WideTy); 187 LegalizeResult widenScalarMulo(MachineInstr &MI, unsigned TypeIdx, 188 LLT WideTy); 189 190 /// Helper function to build a wide generic register \p DstReg of type \p 191 /// RegTy from smaller parts. This will produce a G_MERGE_VALUES, 192 /// G_BUILD_VECTOR, G_CONCAT_VECTORS, or sequence of G_INSERT as appropriate 193 /// for the types. 194 /// 195 /// \p PartRegs must be registers of type \p PartTy. 196 /// 197 /// If \p ResultTy does not evenly break into \p PartTy sized pieces, the 198 /// remainder must be specified with \p LeftoverRegs of type \p LeftoverTy. 199 void insertParts(Register DstReg, LLT ResultTy, 200 LLT PartTy, ArrayRef<Register> PartRegs, 201 LLT LeftoverTy = LLT(), ArrayRef<Register> LeftoverRegs = {}); 202 203 /// Merge \p PartRegs with different types into \p DstReg. 204 void mergeMixedSubvectors(Register DstReg, ArrayRef<Register> PartRegs); 205 206 void appendVectorElts(SmallVectorImpl<Register> &Elts, Register Reg); 207 208 /// Unmerge \p SrcReg into smaller sized values, and append them to \p 209 /// Parts. The elements of \p Parts will be the greatest common divisor type 210 /// of \p DstTy, \p NarrowTy and the type of \p SrcReg. This will compute and 211 /// return the GCD type. 212 LLT extractGCDType(SmallVectorImpl<Register> &Parts, LLT DstTy, 213 LLT NarrowTy, Register SrcReg); 214 215 /// Unmerge \p SrcReg into \p GCDTy typed registers. This will append all of 216 /// the unpacked registers to \p Parts. This version is if the common unmerge 217 /// type is already known. 218 void extractGCDType(SmallVectorImpl<Register> &Parts, LLT GCDTy, 219 Register SrcReg); 220 221 /// Produce a merge of values in \p VRegs to define \p DstReg. Perform a merge 222 /// from the least common multiple type, and convert as appropriate to \p 223 /// DstReg. 224 /// 225 /// \p VRegs should each have type \p GCDTy. This type should be greatest 226 /// common divisor type of \p DstReg, \p NarrowTy, and an undetermined source 227 /// type. 228 /// 229 /// \p NarrowTy is the desired result merge source type. If the source value 230 /// needs to be widened to evenly cover \p DstReg, inserts high bits 231 /// corresponding to the extension opcode \p PadStrategy. 232 /// 233 /// \p VRegs will be cleared, and the result \p NarrowTy register pieces 234 /// will replace it. Returns The complete LCMTy that \p VRegs will cover when 235 /// merged. 236 LLT buildLCMMergePieces(LLT DstTy, LLT NarrowTy, LLT GCDTy, 237 SmallVectorImpl<Register> &VRegs, 238 unsigned PadStrategy = TargetOpcode::G_ANYEXT); 239 240 /// Merge the values in \p RemergeRegs to an \p LCMTy typed value. Extract the 241 /// low bits into \p DstReg. This is intended to use the outputs from 242 /// buildLCMMergePieces after processing. 243 void buildWidenedRemergeToDst(Register DstReg, LLT LCMTy, 244 ArrayRef<Register> RemergeRegs); 245 246 /// Perform generic multiplication of values held in multiple registers. 247 /// Generated instructions use only types NarrowTy and i1. 248 /// Destination can be same or two times size of the source. 249 void multiplyRegisters(SmallVectorImpl<Register> &DstRegs, 250 ArrayRef<Register> Src1Regs, 251 ArrayRef<Register> Src2Regs, LLT NarrowTy); 252 253 void changeOpcode(MachineInstr &MI, unsigned NewOpcode); 254 255 LegalizeResult tryNarrowPow2Reduction(MachineInstr &MI, Register SrcReg, 256 LLT SrcTy, LLT NarrowTy, 257 unsigned ScalarOpc); 258 259 // Memcpy family legalization helpers. 260 LegalizeResult lowerMemset(MachineInstr &MI, Register Dst, Register Val, 261 uint64_t KnownLen, Align Alignment, 262 bool IsVolatile); 263 LegalizeResult lowerMemcpyInline(MachineInstr &MI, Register Dst, Register Src, 264 uint64_t KnownLen, Align DstAlign, 265 Align SrcAlign, bool IsVolatile); 266 LegalizeResult lowerMemcpy(MachineInstr &MI, Register Dst, Register Src, 267 uint64_t KnownLen, uint64_t Limit, Align DstAlign, 268 Align SrcAlign, bool IsVolatile); 269 LegalizeResult lowerMemmove(MachineInstr &MI, Register Dst, Register Src, 270 uint64_t KnownLen, Align DstAlign, Align SrcAlign, 271 bool IsVolatile); 272 273 // Implements floating-point environment read/write via library function call. 274 LegalizeResult createGetStateLibcall(MachineIRBuilder &MIRBuilder, 275 MachineInstr &MI, 276 LostDebugLocObserver &LocObserver); 277 LegalizeResult createSetStateLibcall(MachineIRBuilder &MIRBuilder, 278 MachineInstr &MI, 279 LostDebugLocObserver &LocObserver); 280 LegalizeResult createResetStateLibcall(MachineIRBuilder &MIRBuilder, 281 MachineInstr &MI, 282 LostDebugLocObserver &LocObserver); 283 284 MachineInstrBuilder 285 getNeutralElementForVecReduce(unsigned Opcode, MachineIRBuilder &MIRBuilder, 286 LLT Ty); 287 288 public: 289 /// Return the alignment to use for a stack temporary object with the given 290 /// type. 291 Align getStackTemporaryAlignment(LLT Type, Align MinAlign = Align()) const; 292 293 /// Create a stack temporary based on the size in bytes and the alignment 294 MachineInstrBuilder createStackTemporary(TypeSize Bytes, Align Alignment, 295 MachinePointerInfo &PtrInfo); 296 297 /// Get a pointer to vector element \p Index located in memory for a vector of 298 /// type \p VecTy starting at a base address of \p VecPtr. If \p Index is out 299 /// of bounds the returned pointer is unspecified, but will be within the 300 /// vector bounds. 301 Register getVectorElementPointer(Register VecPtr, LLT VecTy, Register Index); 302 303 /// Handles most opcodes. Split \p MI into same instruction on sub-vectors or 304 /// scalars with \p NumElts elements (1 for scalar). Supports uneven splits: 305 /// there can be leftover sub-vector with fewer then \p NumElts or a leftover 306 /// scalar. To avoid this use moreElements first and set MI number of elements 307 /// to multiple of \p NumElts. Non-vector operands that should be used on all 308 /// sub-instructions without split are listed in \p NonVecOpIndices. 309 LegalizeResult fewerElementsVectorMultiEltType( 310 GenericMachineInstr &MI, unsigned NumElts, 311 std::initializer_list<unsigned> NonVecOpIndices = {}); 312 313 LegalizeResult fewerElementsVectorPhi(GenericMachineInstr &MI, 314 unsigned NumElts); 315 316 LegalizeResult moreElementsVectorPhi(MachineInstr &MI, unsigned TypeIdx, 317 LLT MoreTy); 318 LegalizeResult moreElementsVectorShuffle(MachineInstr &MI, unsigned TypeIdx, 319 LLT MoreTy); 320 321 LegalizeResult fewerElementsVectorUnmergeValues(MachineInstr &MI, 322 unsigned TypeIdx, 323 LLT NarrowTy); 324 LegalizeResult fewerElementsVectorMerge(MachineInstr &MI, unsigned TypeIdx, 325 LLT NarrowTy); 326 LegalizeResult fewerElementsVectorExtractInsertVectorElt(MachineInstr &MI, 327 unsigned TypeIdx, 328 LLT NarrowTy); 329 330 /// Equalize source and destination vector sizes of G_SHUFFLE_VECTOR. 331 LegalizeResult equalizeVectorShuffleLengths(MachineInstr &MI); 332 333 LegalizeResult reduceLoadStoreWidth(GLoadStore &MI, unsigned TypeIdx, 334 LLT NarrowTy); 335 336 LegalizeResult narrowScalarShiftByConstant(MachineInstr &MI, const APInt &Amt, 337 LLT HalfTy, LLT ShiftAmtTy); 338 339 LegalizeResult fewerElementsVectorReductions(MachineInstr &MI, 340 unsigned TypeIdx, LLT NarrowTy); 341 LegalizeResult fewerElementsVectorSeqReductions(MachineInstr &MI, 342 unsigned TypeIdx, 343 LLT NarrowTy); 344 345 // Fewer Elements for bitcast, ensuring that the size of the Src and Dst 346 // registers will be the same 347 LegalizeResult fewerElementsBitcast(MachineInstr &MI, unsigned TypeIdx, 348 LLT NarrowTy); 349 350 LegalizeResult fewerElementsVectorShuffle(MachineInstr &MI, unsigned TypeIdx, 351 LLT NarrowTy); 352 353 LegalizeResult narrowScalarShift(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 354 LegalizeResult narrowScalarAddSub(MachineInstr &MI, unsigned TypeIdx, 355 LLT NarrowTy); 356 LegalizeResult narrowScalarMul(MachineInstr &MI, LLT Ty); 357 LegalizeResult narrowScalarFPTOI(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 358 LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 359 LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 360 361 LegalizeResult narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 362 LegalizeResult narrowScalarExt(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 363 LegalizeResult narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 364 LegalizeResult narrowScalarCTLZ(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 365 LegalizeResult narrowScalarCTTZ(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 366 LegalizeResult narrowScalarCTPOP(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 367 LegalizeResult narrowScalarFLDEXP(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 368 369 /// Perform Bitcast legalize action on G_EXTRACT_VECTOR_ELT. 370 LegalizeResult bitcastExtractVectorElt(MachineInstr &MI, unsigned TypeIdx, 371 LLT CastTy); 372 373 /// Perform Bitcast legalize action on G_INSERT_VECTOR_ELT. 374 LegalizeResult bitcastInsertVectorElt(MachineInstr &MI, unsigned TypeIdx, 375 LLT CastTy); 376 LegalizeResult bitcastConcatVector(MachineInstr &MI, unsigned TypeIdx, 377 LLT CastTy); 378 379 LegalizeResult lowerConstant(MachineInstr &MI); 380 LegalizeResult lowerFConstant(MachineInstr &MI); 381 LegalizeResult lowerBitcast(MachineInstr &MI); 382 LegalizeResult lowerLoad(GAnyLoad &MI); 383 LegalizeResult lowerStore(GStore &MI); 384 LegalizeResult lowerBitCount(MachineInstr &MI); 385 LegalizeResult lowerFunnelShiftWithInverse(MachineInstr &MI); 386 LegalizeResult lowerFunnelShiftAsShifts(MachineInstr &MI); 387 LegalizeResult lowerFunnelShift(MachineInstr &MI); 388 LegalizeResult lowerEXT(MachineInstr &MI); 389 LegalizeResult lowerTRUNC(MachineInstr &MI); 390 LegalizeResult lowerRotateWithReverseRotate(MachineInstr &MI); 391 LegalizeResult lowerRotate(MachineInstr &MI); 392 393 LegalizeResult lowerU64ToF32BitOps(MachineInstr &MI); 394 LegalizeResult lowerUITOFP(MachineInstr &MI); 395 LegalizeResult lowerSITOFP(MachineInstr &MI); 396 LegalizeResult lowerFPTOUI(MachineInstr &MI); 397 LegalizeResult lowerFPTOSI(MachineInstr &MI); 398 399 LegalizeResult lowerFPTRUNC_F64_TO_F16(MachineInstr &MI); 400 LegalizeResult lowerFPTRUNC(MachineInstr &MI); 401 LegalizeResult lowerFPOWI(MachineInstr &MI); 402 403 LegalizeResult lowerISFPCLASS(MachineInstr &MI); 404 405 LegalizeResult lowerThreewayCompare(MachineInstr &MI); 406 LegalizeResult lowerMinMax(MachineInstr &MI); 407 LegalizeResult lowerFCopySign(MachineInstr &MI); 408 LegalizeResult lowerFMinNumMaxNum(MachineInstr &MI); 409 LegalizeResult lowerFMad(MachineInstr &MI); 410 LegalizeResult lowerIntrinsicRound(MachineInstr &MI); 411 LegalizeResult lowerFFloor(MachineInstr &MI); 412 LegalizeResult lowerMergeValues(MachineInstr &MI); 413 LegalizeResult lowerUnmergeValues(MachineInstr &MI); 414 LegalizeResult lowerExtractInsertVectorElt(MachineInstr &MI); 415 LegalizeResult lowerShuffleVector(MachineInstr &MI); 416 LegalizeResult lowerVECTOR_COMPRESS(MachineInstr &MI); 417 Register getDynStackAllocTargetPtr(Register SPReg, Register AllocSize, 418 Align Alignment, LLT PtrTy); 419 LegalizeResult lowerDynStackAlloc(MachineInstr &MI); 420 LegalizeResult lowerStackSave(MachineInstr &MI); 421 LegalizeResult lowerStackRestore(MachineInstr &MI); 422 LegalizeResult lowerExtract(MachineInstr &MI); 423 LegalizeResult lowerInsert(MachineInstr &MI); 424 LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI); 425 LegalizeResult lowerAddSubSatToMinMax(MachineInstr &MI); 426 LegalizeResult lowerAddSubSatToAddoSubo(MachineInstr &MI); 427 LegalizeResult lowerShlSat(MachineInstr &MI); 428 LegalizeResult lowerBswap(MachineInstr &MI); 429 LegalizeResult lowerBitreverse(MachineInstr &MI); 430 LegalizeResult lowerReadWriteRegister(MachineInstr &MI); 431 LegalizeResult lowerSMULH_UMULH(MachineInstr &MI); 432 LegalizeResult lowerSelect(MachineInstr &MI); 433 LegalizeResult lowerDIVREM(MachineInstr &MI); 434 LegalizeResult lowerAbsToAddXor(MachineInstr &MI); 435 LegalizeResult lowerAbsToMaxNeg(MachineInstr &MI); 436 LegalizeResult lowerAbsToCNeg(MachineInstr &MI); 437 LegalizeResult lowerVectorReduction(MachineInstr &MI); 438 LegalizeResult lowerMemcpyInline(MachineInstr &MI); 439 LegalizeResult lowerMemCpyFamily(MachineInstr &MI, unsigned MaxLen = 0); 440 LegalizeResult lowerVAArg(MachineInstr &MI); 441 }; 442 443 /// Helper function that creates a libcall to the given \p Name using the given 444 /// calling convention \p CC. 445 LegalizerHelper::LegalizeResult 446 createLibcall(MachineIRBuilder &MIRBuilder, const char *Name, 447 const CallLowering::ArgInfo &Result, 448 ArrayRef<CallLowering::ArgInfo> Args, CallingConv::ID CC, 449 LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr); 450 451 /// Helper function that creates the given libcall. 452 LegalizerHelper::LegalizeResult 453 createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, 454 const CallLowering::ArgInfo &Result, 455 ArrayRef<CallLowering::ArgInfo> Args, 456 LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr); 457 458 /// Create a libcall to memcpy et al. 459 LegalizerHelper::LegalizeResult 460 createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 461 MachineInstr &MI, LostDebugLocObserver &LocObserver); 462 463 464 } // End namespace llvm. 465 466 #endif 467