LLVM 23.0.0git
WebAssemblyCallLowering.cpp
Go to the documentation of this file.
1//===-- WebAssemblyCallLowering.cpp - Call lowering for GlobalISel -*- 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
10/// This file implements the lowering of LLVM calls to machine code calls for
11/// GlobalISel.
12///
13//===----------------------------------------------------------------------===//
14
29#include "llvm/IR/DataLayout.h"
30#include "llvm/IR/DebugLoc.h"
31#include "llvm/IR/Value.h"
33
34#define DEBUG_TYPE "wasm-call-lowering"
35
36using namespace llvm;
37
38// Test whether the given calling convention is supported.
40 // We currently support the language-independent target-independent
41 // conventions. We don't yet have a way to annotate calls with properties like
42 // "cold", and we don't have any call-clobbered registers, so these are mostly
43 // all handled the same.
44 return CallConv == CallingConv::C || CallConv == CallingConv::Fast ||
45 CallConv == CallingConv::Cold ||
46 CallConv == CallingConv::PreserveMost ||
47 CallConv == CallingConv::PreserveAll ||
48 CallConv == CallingConv::CXX_FAST_TLS ||
50 CallConv == CallingConv::Swift;
51}
52
53static unsigned extendOpFromFlags(ISD::ArgFlagsTy Flags) {
54 if (Flags.isSExt())
55 return TargetOpcode::G_SEXT;
56 if (Flags.isZExt())
57 return TargetOpcode::G_ZEXT;
58 return TargetOpcode::G_ANYEXT;
59}
60
61static LLT getLLTForWasmMVT(MVT Ty, const DataLayout &DL) {
62 if (Ty == MVT::externref) {
63 return LLT::pointer(
65 DL.getPointerSizeInBits(
67 }
68
69 if (Ty == MVT::funcref) {
70 return LLT::pointer(
72 DL.getPointerSizeInBits(
74 }
75
76 return llvm::getLLTForMVT(Ty);
77}
78
82
90
92 const Value *Val,
95 Register SwiftErrorVReg) const {
96 MachineFunction &MF = MIRBuilder.getMF();
97 const Function &F = MF.getFunction();
100 const DataLayout &DL = F.getDataLayout();
101
102 MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert(WebAssembly::RETURN);
103
104 assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
105 "Return value without a vreg or vice versa");
106
107 if (Val) {
108 LLVMContext &Ctx = Val->getType()->getContext();
109
110 if (!FLI.CanLowerReturn) {
111 insertSRetStores(MIRBuilder, Val->getType(), VRegs, FLI.DemoteRegister);
112 } else {
113 SmallVector<EVT, 4> SplitEVTs;
114 ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
115 assert(VRegs.size() == SplitEVTs.size() &&
116 "For each split Type there should be exactly one VReg.");
117
118 SmallVector<ArgInfo, 8> SplitRets;
119 CallingConv::ID CallConv = F.getCallingConv();
120
121 unsigned RetIdx = 0;
122 for (EVT SplitEVT : SplitEVTs) {
123 Register CurVReg = VRegs[RetIdx];
124 ArgInfo CurRetInfo = ArgInfo{CurVReg, SplitEVT.getTypeForEVT(Ctx), 0};
125 setArgFlags(CurRetInfo, AttributeList::ReturnIndex, DL, F);
126
127 splitToValueTypes(CurRetInfo, SplitRets, DL, CallConv);
128 ++RetIdx;
129 }
130
131 for (ArgInfo &Ret : SplitRets) {
132 const EVT OrigVT = TLI.getValueType(DL, Ret.Ty);
133 const MVT NewVT =
134 TLI.getRegisterTypeForCallingConv(Ctx, CallConv, OrigVT);
135 const LLT OrigLLT =
136 getLLTForType(*OrigVT.getTypeForEVT(F.getContext()), DL);
137 const LLT NewLLT = getLLTForWasmMVT(NewVT, DL);
138
139 const TargetRegisterClass &NewRegClass = *TLI.getRegClassFor(NewVT);
140
141 // If we need to split the type over multiple regs, check it's a
142 // scenario we currently support.
143 const unsigned NumParts =
144 TLI.getNumRegistersForCallingConv(Ctx, CallConv, OrigVT);
145
146 const ISD::ArgFlagsTy OrigFlags = Ret.Flags[0];
147 Ret.Flags.clear();
148
149 for (unsigned Part = 0; Part < NumParts; ++Part) {
150 ISD::ArgFlagsTy Flags = OrigFlags;
151
152 if (Part == 0) {
153 Flags.setSplit();
154 } else {
155 Flags.setOrigAlign(Align(1));
156 if (Part == NumParts - 1)
157 Flags.setSplitEnd();
158 }
159
160 Ret.Flags.push_back(Flags);
161 }
162
163 Ret.OrigRegs.assign(Ret.Regs.begin(), Ret.Regs.end());
164 if (NumParts != 1 || OrigLLT != NewLLT) {
165 // If we can't directly assign the register, we need one or more
166 // intermediate values.
167 Ret.Regs.resize(NumParts);
168
169 // For each split register, create and assign a vreg that will store
170 // the incoming component of the larger value. These will later be
171 // merged to form the final vreg.
172 for (unsigned Part = 0; Part < NumParts; ++Part) {
173 Register NewReg = MRI.createVirtualRegister(&NewRegClass);
174 MRI.setType(NewReg, NewLLT);
175 MIB.addUse(NewReg);
176 Ret.Regs[Part] = NewReg;
177 }
178
179 buildCopyToRegs(MIRBuilder, Ret.Regs, Ret.OrigRegs[0], OrigLLT,
180 NewLLT, extendOpFromFlags(Ret.Flags[0]));
181 } else {
182 MIB.addUse(Ret.Regs[0]);
183 }
184 }
185 }
186 }
187
188 if (SwiftErrorVReg) {
190 "Wasm does not `supportSwiftError`, yet SwiftErrorVReg is "
191 "improperly valid.");
192 }
193
194 MIRBuilder.insertInstr(MIB);
195 return true;
196}
197
198static unsigned getWasmArgumentOpcode(MVT ArgType) {
199 switch (ArgType.SimpleTy) {
200 case MVT::i32:
201 return WebAssembly::ARGUMENT_i32;
202 case MVT::i64:
203 return WebAssembly::ARGUMENT_i64;
204 case MVT::f32:
205 return WebAssembly::ARGUMENT_f32;
206 case MVT::f64:
207 return WebAssembly::ARGUMENT_f64;
208
209 case MVT::funcref:
210 return WebAssembly::ARGUMENT_funcref;
211 case MVT::externref:
212 return WebAssembly::ARGUMENT_externref;
213 case MVT::exnref:
214 return WebAssembly::ARGUMENT_exnref;
215
216 case MVT::v16i8:
217 return WebAssembly::ARGUMENT_v16i8;
218 case MVT::v8i16:
219 return WebAssembly::ARGUMENT_v8i16;
220 case MVT::v4i32:
221 return WebAssembly::ARGUMENT_v4i32;
222 case MVT::v2i64:
223 return WebAssembly::ARGUMENT_v2i64;
224 case MVT::v8f16:
225 return WebAssembly::ARGUMENT_v8f16;
226 case MVT::v4f32:
227 return WebAssembly::ARGUMENT_v4f32;
228 case MVT::v2f64:
229 return WebAssembly::ARGUMENT_v2f64;
230 default:
231 break;
232 }
233 llvm_unreachable("Found unexpected type for Wasm argument");
234}
235
236static Register buildWasmArgument(unsigned Idx, MVT ArgVT, LLT ArgLLT,
237 MachineIRBuilder &MIRBuilder,
238 Register Def = Register()) {
239 unsigned Op = getWasmArgumentOpcode(ArgVT);
240
241 const TargetInstrInfo &TII = MIRBuilder.getTII();
242 MachineFunction &MF = MIRBuilder.getMF();
244 const TargetRegisterClass &RegClass = *TII.getRegClass(TII.get(Op), 0);
245
246 Register NewReg;
247
248 if (Def.isValid()) {
250 "Def already has reg bank or reg class?");
251 MRI.setRegClass(Def, &RegClass);
252
253 NewReg = Def;
254 } else {
255 NewReg = MRI.createVirtualRegister(&RegClass);
256 MRI.setType(NewReg, ArgLLT);
257 }
258
259 MIRBuilder.buildInstr(Op).addDef(NewReg).addImm(Idx);
260
261 return NewReg;
262}
263
265 MachineIRBuilder &MIRBuilder, const Function &F,
267 MachineFunction &MF = MIRBuilder.getMF();
270 const DataLayout &DL = F.getDataLayout();
272
273 LLVMContext &Ctx = MIRBuilder.getContext();
274 const CallingConv::ID CallConv = F.getCallingConv();
275
276 if (!callingConvSupported(CallConv))
277 return false;
278
279 MF.getRegInfo().addLiveIn(WebAssembly::ARGUMENTS);
280 MF.front().addLiveIn(WebAssembly::ARGUMENTS);
281
282 SmallVector<ArgInfo, 8> SplitArgs;
283
284 if (!FLI.CanLowerReturn)
285 insertSRetIncomingArgument(F, SplitArgs, FLI.DemoteRegister, MRI, DL);
286
287 unsigned ArgIdx = 0;
288 bool HasSwiftErrorArg = false;
289 bool HasSwiftSelfArg = false;
290 for (const Argument &Arg : F.args()) {
291 ArgInfo OrigArg{VRegs[ArgIdx], Arg.getType(), ArgIdx};
292 setArgFlags(OrigArg, ArgIdx + AttributeList::FirstArgIndex, DL, F);
293
294 HasSwiftSelfArg |= Arg.hasSwiftSelfAttr();
295 HasSwiftErrorArg |= Arg.hasSwiftErrorAttr();
296 if (Arg.hasInAllocaAttr())
297 return false;
298 if (Arg.hasNestAttr())
299 return false;
300
301 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
302 ++ArgIdx;
303 }
304
305 unsigned FinalArgIdx = 0;
306 for (ArgInfo &Arg : SplitArgs) {
307 const EVT OrigVT = TLI.getValueType(DL, Arg.Ty);
308 const MVT NewVT = TLI.getRegisterTypeForCallingConv(Ctx, CallConv, OrigVT);
309 const LLT OrigLLT =
310 getLLTForType(*OrigVT.getTypeForEVT(F.getContext()), DL);
311 const LLT NewLLT = getLLTForWasmMVT(NewVT, DL);
312
313 // If we need to split the type over multiple regs, check it's a scenario
314 // we currently support.
315 const unsigned NumParts =
316 TLI.getNumRegistersForCallingConv(Ctx, CallConv, OrigVT);
317
318 const ISD::ArgFlagsTy OrigFlags = Arg.Flags[0];
319 Arg.Flags.clear();
320
321 for (unsigned Part = 0; Part < NumParts; ++Part) {
322 ISD::ArgFlagsTy Flags = OrigFlags;
323 if (Part == 0) {
324 Flags.setSplit();
325 } else {
326 Flags.setOrigAlign(Align(1));
327 if (Part == NumParts - 1)
328 Flags.setSplitEnd();
329 }
330
331 Arg.Flags.push_back(Flags);
332 }
333
334 Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end());
335 if (NumParts != 1 || OrigLLT != NewLLT) {
336 // If we can't directly assign the register, we need one or more
337 // intermediate values.
338 Arg.Regs.resize(NumParts);
339
340 // For each split register, create and assign a vreg that will store
341 // the incoming component of the larger value. These will later be
342 // merged to form the final vreg.
343 for (unsigned Part = 0; Part < NumParts; ++Part) {
344 Arg.Regs[Part] =
345 buildWasmArgument(FinalArgIdx++, NewVT, NewLLT, MIRBuilder);
346 MFI->addParam(NewVT);
347 }
348
349 buildCopyFromRegs(MIRBuilder, Arg.OrigRegs, Arg.Regs, OrigLLT, NewLLT,
350 Arg.Flags[0]);
351 } else {
352 buildWasmArgument(FinalArgIdx++, NewVT, NewLLT, MIRBuilder, Arg.Regs[0]);
353 MFI->addParam(NewVT);
354 }
355 }
356
357 // For swiftcc, emit additional swiftself and swifterror arguments
358 // if there aren't. These additional arguments are also added for callee
359 // signature They are necessary to match callee and caller signature for
360 // indirect call.
361 if (CallConv == CallingConv::Swift) {
362 const MVT PtrVT = TLI.getPointerTy(DL);
363
364 if (!HasSwiftSelfArg)
365 MFI->addParam(PtrVT);
366 if (!HasSwiftErrorArg)
367 MFI->addParam(PtrVT);
368 }
369
370 // Varargs are copied into a buffer allocated by the caller, and a pointer to
371 // the buffer is passed as an argument.
372 if (F.isVarArg()) {
373 const MVT PtrVT = TLI.getPointerTy(DL, 0);
374 const LLT PtrLLT = LLT::pointer(0, DL.getPointerSizeInBits(0));
375
376 Register VarargVreg =
377 buildWasmArgument(FinalArgIdx++, PtrVT, PtrLLT, MIRBuilder);
378 MFI->setVarargBufferVreg(VarargVreg);
379
380 MFI->addParam(PtrVT);
381 ++FinalArgIdx;
382 }
383
384 // Record the number and types of arguments and results.
385 SmallVector<MVT, 4> Params;
388 MF.getFunction(), MF.getTarget(), Params, Results);
389 for (MVT VT : Results)
390 MFI->addResult(VT);
391
392 // TODO: Use signatures in WebAssemblyMachineFunctionInfo too and unify
393 // the param logic here with ComputeSignatureVTs
394 assert(MFI->getParams().size() == Params.size() &&
395 std::equal(MFI->getParams().begin(), MFI->getParams().end(),
396 Params.begin()));
397 return true;
398}
399
401 CallLoweringInfo &Info) const {
402 MachineFunction &MF = MIRBuilder.getMF();
403 const DataLayout &DL = MIRBuilder.getDataLayout();
404 LLVMContext &Ctx = MIRBuilder.getContext();
406 MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
407 const Function &F = MF.getFunction();
408
409 CallingConv::ID CallConv = Info.CallConv;
410 if (!callingConvSupported(CallConv))
411 return false;
412
413 // TODO: tail calls
414 if (Info.IsMustTailCall)
415 return false;
416
417 // TODO: varargs
418 if (Info.IsVarArg)
419 return false;
420
421 // TODO: swiftcc
422 if (CallConv == CallingConv::Swift)
423 return false;
424
426
427 // TODO: indirect calls
428 if (Info.Callee.isReg())
429 return false;
430
431 CallInst = MIRBuilder.buildInstrNoInsert(WebAssembly::CALL);
432
433 SmallVector<ArgInfo, 8> SplitArgs;
434
435 for (const ArgInfo &Arg : Info.OrigArgs) {
436 if (Arg.Flags[0].isNest())
437 return false;
438 if (Arg.Flags[0].isInAlloca())
439 return false;
440 if (Arg.Flags[0].isInConsecutiveRegs())
441 return false;
442 if (Arg.Flags[0].isInConsecutiveRegsLast())
443 return false;
444
445 // TODO: bulk memory, then byval
446 if (Arg.Flags[0].isByVal() && Arg.Flags[0].getByValSize() != 0)
447 return false;
448
449 splitToValueTypes(Arg, SplitArgs, DL, CallConv);
450 }
451
452 SmallVector<Register> CallUseRegs;
453
454 for (ArgInfo &Arg : SplitArgs) {
455 const EVT OrigVT = TLI.getValueType(DL, Arg.Ty);
456 const MVT NewVT = TLI.getRegisterTypeForCallingConv(Ctx, CallConv, OrigVT);
457 const LLT OrigLLT =
458 getLLTForType(*OrigVT.getTypeForEVT(F.getContext()), DL);
459 const LLT NewLLT = getLLTForWasmMVT(NewVT, DL);
460
461 const TargetRegisterClass &NewRegClass = *TLI.getRegClassFor(NewVT);
462
463 // If we need to split the type over multiple regs, check it's a scenario
464 // we currently support.
465 const unsigned NumParts =
466 TLI.getNumRegistersForCallingConv(Ctx, CallConv, OrigVT);
467
468 const ISD::ArgFlagsTy OrigFlags = Arg.Flags[0];
469 Arg.Flags.clear();
470
471 for (unsigned Part = 0; Part < NumParts; ++Part) {
472 ISD::ArgFlagsTy Flags = OrigFlags;
473 if (Part == 0) {
474 Flags.setSplit();
475 } else {
476 Flags.setOrigAlign(Align(1));
477 if (Part == NumParts - 1)
478 Flags.setSplitEnd();
479 }
480
481 Arg.Flags.push_back(Flags);
482 }
483
484 Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end());
485 if (NumParts != 1 || OrigLLT != NewLLT) {
486 // If we can't directly assign the register, we need one or more
487 // intermediate values.
488 Arg.Regs.resize(NumParts);
489
490 // For each split register, create and assign a vreg that will store
491 // the incoming component of the larger value. These will later be
492 // merged to form the final vreg.
493 for (unsigned Part = 0; Part < NumParts; ++Part) {
494 Register NewReg = MRI.createVirtualRegister(&NewRegClass);
495 MRI.setType(NewReg, NewLLT);
496 CallUseRegs.push_back(NewReg);
497 Arg.Regs[Part] = NewReg;
498 }
499
500 buildCopyToRegs(MIRBuilder, Arg.Regs, Arg.OrigRegs[0], OrigLLT, NewLLT,
501 extendOpFromFlags(Arg.Flags[0]));
502 } else {
503 CallUseRegs.push_back(Arg.Regs[0]);
504 }
505 }
506
507 // Analyze operands of the call, assigning locations to each operand.
509 CCState CCInfo(CallConv, Info.IsVarArg, MF, ArgLocs, Ctx);
510
511 MIRBuilder.insertInstr(CallInst);
512
513 if (Info.CanLowerReturn && !Info.OrigRet.Ty->isVoidTy()) {
514 SmallVector<EVT, 4> SplitEVTs;
515 ComputeValueVTs(TLI, DL, Info.OrigRet.Ty, SplitEVTs);
516 assert(Info.OrigRet.Regs.size() == SplitEVTs.size() &&
517 "For each split Type there should be exactly one VReg.");
518
519 SmallVector<ArgInfo, 8> SplitRets;
520
521 unsigned RetIdx = 0;
522 for (EVT SplitEVT : SplitEVTs) {
523 Register CurVReg = Info.OrigRet.Regs[RetIdx];
524 ArgInfo CurArgInfo = ArgInfo{CurVReg, SplitEVT.getTypeForEVT(Ctx), 0};
525
526 if (Info.CB) {
527 setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, *Info.CB);
528 } else {
529 // We don't have a call base, so chances are we're looking at a
530 // libcall (external symbol).
531
532 // TODO: figure out how to get ALL the correct attributes
533 ISD::ArgFlagsTy &Flags = CurArgInfo.Flags[0];
534 PointerType *PtrTy =
536 if (PtrTy) {
537 Flags.setPointer();
538 Flags.setPointerAddrSpace(PtrTy->getPointerAddressSpace());
539 }
540 Align MemAlign = DL.getABITypeAlign(CurArgInfo.Ty);
541 Flags.setMemAlign(MemAlign);
542 Flags.setOrigAlign(MemAlign);
543 }
544
545 splitToValueTypes(CurArgInfo, SplitRets, DL, CallConv);
546 ++RetIdx;
547 }
548
549 for (ArgInfo &Ret : SplitRets) {
550 const EVT OrigVT = TLI.getValueType(DL, Ret.Ty);
551 const MVT NewVT =
552 TLI.getRegisterTypeForCallingConv(Ctx, CallConv, OrigVT);
553 const LLT OrigLLT =
554 getLLTForType(*OrigVT.getTypeForEVT(F.getContext()), DL);
555 const LLT NewLLT = getLLTForWasmMVT(NewVT, DL);
556
557 const TargetRegisterClass &NewRegClass = *TLI.getRegClassFor(NewVT);
558
559 // If we need to split the type over multiple regs, check it's a scenario
560 // we currently support.
561 const unsigned NumParts =
562 TLI.getNumRegistersForCallingConv(Ctx, CallConv, OrigVT);
563
564 const ISD::ArgFlagsTy OrigFlags = Ret.Flags[0];
565 Ret.Flags.clear();
566
567 for (unsigned Part = 0; Part < NumParts; ++Part) {
568 ISD::ArgFlagsTy Flags = OrigFlags;
569 if (Part == 0) {
570 Flags.setSplit();
571 } else {
572 Flags.setOrigAlign(Align(1));
573 if (Part == NumParts - 1)
574 Flags.setSplitEnd();
575 }
576
577 Ret.Flags.push_back(Flags);
578 }
579
580 Ret.OrigRegs.assign(Ret.Regs.begin(), Ret.Regs.end());
581
582 if (NumParts != 1 || OrigLLT != NewLLT) {
583 // If we can't directly assign the register, we need one or more
584 // intermediate values.
585 Ret.Regs.resize(NumParts);
586
587 // For each split register, create and assign a vreg that will store
588 // the incoming component of the larger value. These will later be
589 // merged to form the final vreg.
590 for (unsigned Part = 0; Part < NumParts; ++Part) {
591 Register NewReg = MRI.createVirtualRegister(&NewRegClass);
592 MRI.setType(NewReg, NewLLT);
593 CallInst.addDef(NewReg);
594 Ret.Regs[Part] = NewReg;
595 }
596
597 buildCopyFromRegs(MIRBuilder, Ret.OrigRegs, Ret.Regs, OrigLLT, NewLLT,
598 Ret.Flags[0]);
599 } else {
600 MRI.setRegClass(Ret.Regs[0], &NewRegClass);
601 CallInst.addDef(Ret.Regs[0]);
602 }
603 }
604 }
605
606 if (Info.Callee.isGlobal()) {
607 CallInst.addGlobalAddress(Info.Callee.getGlobal());
608 } else if (Info.Callee.isSymbol()) {
609 CallInst.addExternalSymbol(Info.Callee.getSymbolName());
610 } else {
611 return false;
612 }
613
614 for (Register Reg : CallUseRegs) {
615 CallInst.addUse(Reg);
616 }
617
618 if (!Info.CanLowerReturn)
619 insertSRetLoads(MIRBuilder, Info.OrigRet.Ty, Info.OrigRet.Regs,
620 Info.DemoteRegister, Info.DemoteStackIndex);
621
622 return true;
623}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static unsigned extendOpFromFlags(llvm::ISD::ArgFlagsTy Flags)
const HexagonInstrInfo * TII
Implement a low-level type suitable for MachineInstr level instruction selection.
#define F(x, y, z)
Definition MD5.cpp:54
This file declares the MachineIRBuilder class.
Promote Memory to Register
Definition Mem2Reg.cpp:110
static bool callingConvSupported(CallingConv::ID CallConv)
static unsigned getWasmArgumentOpcode(MVT ArgType)
static Register buildWasmArgument(unsigned Idx, MVT ArgVT, LLT ArgLLT, MachineIRBuilder &MIRBuilder, Register Def=Register())
static LLT getLLTForWasmMVT(MVT Ty, const DataLayout &DL)
static unsigned extendOpFromFlags(ISD::ArgFlagsTy Flags)
This file describes how to lower LLVM calls to machine code calls.
This file defines the interfaces that WebAssembly uses to lower LLVM code into a selection DAG.
This file provides WebAssembly-specific target descriptions.
This file declares WebAssembly-specific per-machine-function information.
This file contains the WebAssembly implementation of the WebAssemblyRegisterInfo class.
This file declares the WebAssembly-specific subclass of TargetSubtarget.
This file contains the declaration of the WebAssembly-specific utility functions.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
CCState - This class holds information needed while lowering arguments and return values.
This class represents a function call, abstracting a target machine's calling convention.
void insertSRetLoads(MachineIRBuilder &MIRBuilder, Type *RetTy, ArrayRef< Register > VRegs, Register DemoteReg, int FI) const
Load the returned value from the stack into virtual registers in VRegs.
void insertSRetIncomingArgument(const Function &F, SmallVectorImpl< ArgInfo > &SplitArgs, Register &DemoteReg, MachineRegisterInfo &MRI, const DataLayout &DL) const
Insert the hidden sret ArgInfo to the beginning of SplitArgs.
void splitToValueTypes(const ArgInfo &OrigArgInfo, SmallVectorImpl< ArgInfo > &SplitArgs, const DataLayout &DL, CallingConv::ID CallConv, SmallVectorImpl< TypeSize > *Offsets=nullptr) const
Break OrigArgInfo into one or more pieces the calling convention can process, returned in SplitArgs.
static void buildCopyToRegs(MachineIRBuilder &B, ArrayRef< Register > DstRegs, Register SrcReg, LLT SrcTy, LLT PartTy, unsigned ExtendOp=TargetOpcode::G_ANYEXT)
Create a sequence of instructions to expand the value in SrcReg (of type SrcTy) to the types in DstRe...
void insertSRetStores(MachineIRBuilder &MIRBuilder, Type *RetTy, ArrayRef< Register > VRegs, Register DemoteReg) const
Store the return value given by VRegs into stack starting at the offset specified in DemoteReg.
static void buildCopyFromRegs(MachineIRBuilder &B, ArrayRef< Register > OrigRegs, ArrayRef< Register > Regs, LLT LLTy, LLT PartLLT, const ISD::ArgFlagsTy Flags)
Create a sequence of instructions to combine pieces split into register typed values to the original ...
CallLowering(const TargetLowering *TLI)
const TargetLowering * getTLI() const
Getter for generic TargetLowering class.
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
Register DemoteRegister
DemoteRegister - if CanLowerReturn is false, DemoteRegister is a vreg allocated to hold a pointer to ...
bool CanLowerReturn
CanLowerReturn - true iff the function's return value can be lowered to registers.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition Function.h:211
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Machine Value Type.
SimpleValueType SimpleTy
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Helper class to build MachineInstr.
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
LLVMContext & getContext() const
const TargetInstrInfo & getTII()
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineFunction & getMF()
Getter for the function we currently build.
MachineRegisterInfo * getMRI()
Getter for MRI.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
const DataLayout & getDataLayout() const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const RegClassOrRegBank & getRegClassOrRegBank(Register Reg) const
Return the register bank or register class of Reg.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI void setType(Register VReg, LLT Ty)
Set the low-level type of VReg to Ty.
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Class to represent pointers.
bool isNull() const
Test if the pointer held in the union is null, regardless of which type it is.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:370
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
void addUse(Use &U)
This method should only be used by the Use class.
Definition Value.h:513
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef< Register > VRegs, FunctionLoweringInfo &FLI, Register SwiftErrorVReg) const override
This hook must be implemented to lower outgoing return values, described by Val, into the specified v...
WebAssemblyCallLowering(const WebAssemblyTargetLowering &TLI)
bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const override
This hook must be implemented to lower the given call instruction, including argument and return valu...
bool canLowerReturn(MachineFunction &MF, CallingConv::ID CallConv, SmallVectorImpl< BaseArgInfo > &Outs, bool IsVarArg) const override
This hook must be implemented to check whether the return values described by Outs can fit into the r...
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef< ArrayRef< Register > > VRegs, FunctionLoweringInfo &FLI) const override
This hook must be implemented to lower the incoming (formal) arguments, described by VRegs,...
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
const std::vector< MVT > & getParams() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ Swift
Calling convention for Swift.
Definition CallingConv.h:69
@ PreserveMost
Used for runtime calls that preserves most registers.
Definition CallingConv.h:63
@ CXX_FAST_TLS
Used for access functions.
Definition CallingConv.h:72
@ WASM_EmscriptenInvoke
For emscripten __invoke_* functions.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
Definition CallingConv.h:47
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition CallingConv.h:66
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
bool canLowerReturn(size_t ResultSize, const WebAssemblySubtarget *Subtarget)
Returns true if the function's return value(s) can be lowered directly, i.e., not indirectly via a po...
This is an optimization pass for GlobalISel generic memory operations.
void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc, const Function &ContextFunc, const TargetMachine &TM, SmallVectorImpl< MVT > &Params, SmallVectorImpl< MVT > &Results)
void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs=nullptr, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
Definition Analysis.cpp:119
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI LLT getLLTForMVT(MVT Ty)
Get a rough equivalent of an LLT for a given MVT.
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
Definition Error.cpp:173
DWARFExpression::Operation Op
LLVM_ABI LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
SmallVector< Register, 4 > Regs
SmallVector< Register, 2 > OrigRegs
SmallVector< ISD::ArgFlagsTy, 4 > Flags
Extended Value Type.
Definition ValueTypes.h:35
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.