LLVM  7.0.0svn
WebAssemblyISelLowering.cpp
Go to the documentation of this file.
1 //=- WebAssemblyISelLowering.cpp - WebAssembly DAG Lowering Implementation -==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief This file implements the WebAssemblyTargetLowering class.
12 ///
13 //===----------------------------------------------------------------------===//
14 
18 #include "WebAssemblySubtarget.h"
20 #include "llvm/CodeGen/Analysis.h"
26 #include "llvm/IR/DiagnosticInfo.h"
28 #include "llvm/IR/Function.h"
29 #include "llvm/IR/Intrinsics.h"
30 #include "llvm/Support/Debug.h"
34 using namespace llvm;
35 
36 #define DEBUG_TYPE "wasm-lower"
37 
39  const TargetMachine &TM, const WebAssemblySubtarget &STI)
40  : TargetLowering(TM), Subtarget(&STI) {
41  auto MVTPtr = Subtarget->hasAddr64() ? MVT::i64 : MVT::i32;
42 
43  // Booleans always contain 0 or 1.
45  // WebAssembly does not produce floating-point exceptions on normal floating
46  // point operations.
48  // We don't know the microarchitecture here, so just reduce register pressure.
50  // Tell ISel that we have a stack pointer.
52  Subtarget->hasAddr64() ? WebAssembly::SP64 : WebAssembly::SP32);
53  // Set up the register classes.
54  addRegisterClass(MVT::i32, &WebAssembly::I32RegClass);
55  addRegisterClass(MVT::i64, &WebAssembly::I64RegClass);
56  addRegisterClass(MVT::f32, &WebAssembly::F32RegClass);
57  addRegisterClass(MVT::f64, &WebAssembly::F64RegClass);
58  if (Subtarget->hasSIMD128()) {
59  addRegisterClass(MVT::v16i8, &WebAssembly::V128RegClass);
60  addRegisterClass(MVT::v8i16, &WebAssembly::V128RegClass);
61  addRegisterClass(MVT::v4i32, &WebAssembly::V128RegClass);
62  addRegisterClass(MVT::v4f32, &WebAssembly::V128RegClass);
63  }
64  // Compute derived properties from the register classes.
66 
72 
73  // Take the default expansion for va_arg, va_copy, and va_end. There is no
74  // default action for va_start, so we do that custom.
79 
80  for (auto T : {MVT::f32, MVT::f64}) {
81  // Don't expand the floating-point types to constant pools.
83  // Expand floating-point comparisons.
84  for (auto CC : {ISD::SETO, ISD::SETUO, ISD::SETUEQ, ISD::SETONE,
87  // Expand floating-point library function operators.
89  ISD::FMA})
91  // Note supported floating-point library function operators that otherwise
92  // default to expand.
93  for (auto Op :
96  // Support minnan and maxnan, which otherwise default to expand.
99  // WebAssembly currently has no builtin f16 support.
104  }
105 
106  for (auto T : {MVT::i32, MVT::i64}) {
107  // Expand unavailable integer operations.
108  for (auto Op :
112  ISD::SUBE}) {
114  }
115  }
116 
117  // As a special case, these operators use the type to mean the type to
118  // sign-extend from.
120  if (!Subtarget->hasAtomics()) {
121  // The Atomics feature includes signext intructions.
122  for (auto T : {MVT::i8, MVT::i16, MVT::i32})
124  }
125 
126  // Dynamic stack allocation: use the default expansion.
130 
133 
134  // Expand these forms; we pattern-match the forms that we can handle in isel.
135  for (auto T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64})
136  for (auto Op : {ISD::BR_CC, ISD::SELECT_CC})
138 
139  // We have custom switch handling.
141 
142  // WebAssembly doesn't have:
143  // - Floating-point extending loads.
144  // - Floating-point truncating stores.
145  // - i1 extending loads.
148  for (auto T : MVT::integer_valuetypes())
151 
152  // Trap lowers to wasm unreachable
154 
156 }
157 
158 FastISel *WebAssemblyTargetLowering::createFastISel(
159  FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const {
160  return WebAssembly::createFastISel(FuncInfo, LibInfo);
161 }
162 
163 bool WebAssemblyTargetLowering::isOffsetFoldingLegal(
164  const GlobalAddressSDNode * /*GA*/) const {
165  // All offsets can be folded.
166  return true;
167 }
168 
169 MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout & /*DL*/,
170  EVT VT) const {
171  unsigned BitWidth = NextPowerOf2(VT.getSizeInBits() - 1);
172  if (BitWidth > 1 && BitWidth < 8) BitWidth = 8;
173 
174  if (BitWidth > 64) {
175  // The shift will be lowered to a libcall, and compiler-rt libcalls expect
176  // the count to be an i32.
177  BitWidth = 32;
178  assert(BitWidth >= Log2_32_Ceil(VT.getSizeInBits()) &&
179  "32-bit shift counts ought to be enough for anyone");
180  }
181 
182  MVT Result = MVT::getIntegerVT(BitWidth);
184  "Unable to represent scalar shift amount type");
185  return Result;
186 }
187 
188 // Lower an fp-to-int conversion operator from the LLVM opcode, which has an
189 // undefined result on invalid/overflow, to the WebAssembly opcode, which
190 // traps on invalid/overflow.
191 static MachineBasicBlock *
193  MachineInstr &MI,
194  DebugLoc DL,
195  MachineBasicBlock *BB,
196  const TargetInstrInfo &TII,
197  bool IsUnsigned,
198  bool Int64,
199  bool Float64,
200  unsigned LoweredOpcode
201 ) {
203 
204  unsigned OutReg = MI.getOperand(0).getReg();
205  unsigned InReg = MI.getOperand(1).getReg();
206 
207  unsigned Abs = Float64 ? WebAssembly::ABS_F64 : WebAssembly::ABS_F32;
208  unsigned FConst = Float64 ? WebAssembly::CONST_F64 : WebAssembly::CONST_F32;
209  unsigned LT = Float64 ? WebAssembly::LT_F64 : WebAssembly::LT_F32;
210  unsigned GE = Float64 ? WebAssembly::GE_F64 : WebAssembly::GE_F32;
211  unsigned IConst = Int64 ? WebAssembly::CONST_I64 : WebAssembly::CONST_I32;
212  unsigned Eqz = WebAssembly::EQZ_I32;
213  unsigned And = WebAssembly::AND_I32;
214  int64_t Limit = Int64 ? INT64_MIN : INT32_MIN;
215  int64_t Substitute = IsUnsigned ? 0 : Limit;
216  double CmpVal = IsUnsigned ? -(double)Limit * 2.0 : -(double)Limit;
217  auto &Context = BB->getParent()->getFunction().getContext();
219 
220  const BasicBlock *LLVM_BB = BB->getBasicBlock();
221  MachineFunction *F = BB->getParent();
222  MachineBasicBlock *TrueMBB = F->CreateMachineBasicBlock(LLVM_BB);
223  MachineBasicBlock *FalseMBB = F->CreateMachineBasicBlock(LLVM_BB);
224  MachineBasicBlock *DoneMBB = F->CreateMachineBasicBlock(LLVM_BB);
225 
227  F->insert(It, FalseMBB);
228  F->insert(It, TrueMBB);
229  F->insert(It, DoneMBB);
230 
231  // Transfer the remainder of BB and its successor edges to DoneMBB.
232  DoneMBB->splice(DoneMBB->begin(), BB,
233  std::next(MachineBasicBlock::iterator(MI)),
234  BB->end());
235  DoneMBB->transferSuccessorsAndUpdatePHIs(BB);
236 
237  BB->addSuccessor(TrueMBB);
238  BB->addSuccessor(FalseMBB);
239  TrueMBB->addSuccessor(DoneMBB);
240  FalseMBB->addSuccessor(DoneMBB);
241 
242  unsigned Tmp0, Tmp1, CmpReg, EqzReg, FalseReg, TrueReg;
243  Tmp0 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
244  Tmp1 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
245  CmpReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
246  EqzReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
247  FalseReg = MRI.createVirtualRegister(MRI.getRegClass(OutReg));
248  TrueReg = MRI.createVirtualRegister(MRI.getRegClass(OutReg));
249 
250  MI.eraseFromParent();
251  // For signed numbers, we can do a single comparison to determine whether
252  // fabs(x) is within range.
253  if (IsUnsigned) {
254  Tmp0 = InReg;
255  } else {
256  BuildMI(BB, DL, TII.get(Abs), Tmp0)
257  .addReg(InReg);
258  }
259  BuildMI(BB, DL, TII.get(FConst), Tmp1)
260  .addFPImm(cast<ConstantFP>(ConstantFP::get(Ty, CmpVal)));
261  BuildMI(BB, DL, TII.get(LT), CmpReg)
262  .addReg(Tmp0)
263  .addReg(Tmp1);
264 
265  // For unsigned numbers, we have to do a separate comparison with zero.
266  if (IsUnsigned) {
267  Tmp1 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
268  unsigned SecondCmpReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
269  unsigned AndReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
270  BuildMI(BB, DL, TII.get(FConst), Tmp1)
271  .addFPImm(cast<ConstantFP>(ConstantFP::get(Ty, 0.0)));
272  BuildMI(BB, DL, TII.get(GE), SecondCmpReg)
273  .addReg(Tmp0)
274  .addReg(Tmp1);
275  BuildMI(BB, DL, TII.get(And), AndReg)
276  .addReg(CmpReg)
277  .addReg(SecondCmpReg);
278  CmpReg = AndReg;
279  }
280 
281  BuildMI(BB, DL, TII.get(Eqz), EqzReg)
282  .addReg(CmpReg);
283 
284  // Create the CFG diamond to select between doing the conversion or using
285  // the substitute value.
286  BuildMI(BB, DL, TII.get(WebAssembly::BR_IF))
287  .addMBB(TrueMBB)
288  .addReg(EqzReg);
289  BuildMI(FalseMBB, DL, TII.get(LoweredOpcode), FalseReg)
290  .addReg(InReg);
291  BuildMI(FalseMBB, DL, TII.get(WebAssembly::BR))
292  .addMBB(DoneMBB);
293  BuildMI(TrueMBB, DL, TII.get(IConst), TrueReg)
294  .addImm(Substitute);
295  BuildMI(*DoneMBB, DoneMBB->begin(), DL, TII.get(TargetOpcode::PHI), OutReg)
296  .addReg(FalseReg)
297  .addMBB(FalseMBB)
298  .addReg(TrueReg)
299  .addMBB(TrueMBB);
300 
301  return DoneMBB;
302 }
303 
305 WebAssemblyTargetLowering::EmitInstrWithCustomInserter(
306  MachineInstr &MI,
308 ) const {
309  const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
310  DebugLoc DL = MI.getDebugLoc();
311 
312  switch (MI.getOpcode()) {
313  default: llvm_unreachable("Unexpected instr type to insert");
314  case WebAssembly::FP_TO_SINT_I32_F32:
315  return LowerFPToInt(MI, DL, BB, TII, false, false, false,
316  WebAssembly::I32_TRUNC_S_F32);
317  case WebAssembly::FP_TO_UINT_I32_F32:
318  return LowerFPToInt(MI, DL, BB, TII, true, false, false,
319  WebAssembly::I32_TRUNC_U_F32);
320  case WebAssembly::FP_TO_SINT_I64_F32:
321  return LowerFPToInt(MI, DL, BB, TII, false, true, false,
322  WebAssembly::I64_TRUNC_S_F32);
323  case WebAssembly::FP_TO_UINT_I64_F32:
324  return LowerFPToInt(MI, DL, BB, TII, true, true, false,
325  WebAssembly::I64_TRUNC_U_F32);
326  case WebAssembly::FP_TO_SINT_I32_F64:
327  return LowerFPToInt(MI, DL, BB, TII, false, false, true,
328  WebAssembly::I32_TRUNC_S_F64);
329  case WebAssembly::FP_TO_UINT_I32_F64:
330  return LowerFPToInt(MI, DL, BB, TII, true, false, true,
331  WebAssembly::I32_TRUNC_U_F64);
332  case WebAssembly::FP_TO_SINT_I64_F64:
333  return LowerFPToInt(MI, DL, BB, TII, false, true, true,
334  WebAssembly::I64_TRUNC_S_F64);
335  case WebAssembly::FP_TO_UINT_I64_F64:
336  return LowerFPToInt(MI, DL, BB, TII, true, true, true,
337  WebAssembly::I64_TRUNC_U_F64);
338  llvm_unreachable("Unexpected instruction to emit with custom inserter");
339  }
340 }
341 
342 const char *WebAssemblyTargetLowering::getTargetNodeName(
343  unsigned Opcode) const {
344  switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
346  break;
347 #define HANDLE_NODETYPE(NODE) \
348  case WebAssemblyISD::NODE: \
349  return "WebAssemblyISD::" #NODE;
350 #include "WebAssemblyISD.def"
351 #undef HANDLE_NODETYPE
352  }
353  return nullptr;
354 }
355 
356 std::pair<unsigned, const TargetRegisterClass *>
357 WebAssemblyTargetLowering::getRegForInlineAsmConstraint(
358  const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
359  // First, see if this is a constraint that directly corresponds to a
360  // WebAssembly register class.
361  if (Constraint.size() == 1) {
362  switch (Constraint[0]) {
363  case 'r':
364  assert(VT != MVT::iPTR && "Pointer MVT not expected here");
365  if (Subtarget->hasSIMD128() && VT.isVector()) {
366  if (VT.getSizeInBits() == 128)
367  return std::make_pair(0U, &WebAssembly::V128RegClass);
368  }
369  if (VT.isInteger() && !VT.isVector()) {
370  if (VT.getSizeInBits() <= 32)
371  return std::make_pair(0U, &WebAssembly::I32RegClass);
372  if (VT.getSizeInBits() <= 64)
373  return std::make_pair(0U, &WebAssembly::I64RegClass);
374  }
375  break;
376  default:
377  break;
378  }
379  }
380 
381  return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
382 }
383 
384 bool WebAssemblyTargetLowering::isCheapToSpeculateCttz() const {
385  // Assume ctz is a relatively cheap operation.
386  return true;
387 }
388 
389 bool WebAssemblyTargetLowering::isCheapToSpeculateCtlz() const {
390  // Assume clz is a relatively cheap operation.
391  return true;
392 }
393 
394 bool WebAssemblyTargetLowering::isLegalAddressingMode(const DataLayout &DL,
395  const AddrMode &AM,
396  Type *Ty,
397  unsigned AS,
398  Instruction *I) const {
399  // WebAssembly offsets are added as unsigned without wrapping. The
400  // isLegalAddressingMode gives us no way to determine if wrapping could be
401  // happening, so we approximate this by accepting only non-negative offsets.
402  if (AM.BaseOffs < 0) return false;
403 
404  // WebAssembly has no scale register operands.
405  if (AM.Scale != 0) return false;
406 
407  // Everything else is legal.
408  return true;
409 }
410 
411 bool WebAssemblyTargetLowering::allowsMisalignedMemoryAccesses(
412  EVT /*VT*/, unsigned /*AddrSpace*/, unsigned /*Align*/, bool *Fast) const {
413  // WebAssembly supports unaligned accesses, though it should be declared
414  // with the p2align attribute on loads and stores which do so, and there
415  // may be a performance impact. We tell LLVM they're "fast" because
416  // for the kinds of things that LLVM uses this for (merging adjacent stores
417  // of constants, etc.), WebAssembly implementations will either want the
418  // unaligned access or they'll split anyway.
419  if (Fast) *Fast = true;
420  return true;
421 }
422 
423 bool WebAssemblyTargetLowering::isIntDivCheap(EVT VT,
424  AttributeList Attr) const {
425  // The current thinking is that wasm engines will perform this optimization,
426  // so we can save on code size.
427  return true;
428 }
429 
430 //===----------------------------------------------------------------------===//
431 // WebAssembly Lowering private implementation.
432 //===----------------------------------------------------------------------===//
433 
434 //===----------------------------------------------------------------------===//
435 // Lowering Code
436 //===----------------------------------------------------------------------===//
437 
438 static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *msg) {
440  DAG.getContext()->diagnose(
442 }
443 
444 // Test whether the given calling convention is supported.
445 static bool CallingConvSupported(CallingConv::ID CallConv) {
446  // We currently support the language-independent target-independent
447  // conventions. We don't yet have a way to annotate calls with properties like
448  // "cold", and we don't have any call-clobbered registers, so these are mostly
449  // all handled the same.
450  return CallConv == CallingConv::C || CallConv == CallingConv::Fast ||
451  CallConv == CallingConv::Cold ||
452  CallConv == CallingConv::PreserveMost ||
453  CallConv == CallingConv::PreserveAll ||
454  CallConv == CallingConv::CXX_FAST_TLS;
455 }
456 
457 SDValue WebAssemblyTargetLowering::LowerCall(
458  CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const {
459  SelectionDAG &DAG = CLI.DAG;
460  SDLoc DL = CLI.DL;
461  SDValue Chain = CLI.Chain;
462  SDValue Callee = CLI.Callee;
464  auto Layout = MF.getDataLayout();
465 
466  CallingConv::ID CallConv = CLI.CallConv;
467  if (!CallingConvSupported(CallConv))
468  fail(DL, DAG,
469  "WebAssembly doesn't support language-specific or target-specific "
470  "calling conventions yet");
471  if (CLI.IsPatchPoint)
472  fail(DL, DAG, "WebAssembly doesn't support patch point yet");
473 
474  // WebAssembly doesn't currently support explicit tail calls. If they are
475  // required, fail. Otherwise, just disable them.
476  if ((CallConv == CallingConv::Fast && CLI.IsTailCall &&
478  (CLI.CS && CLI.CS.isMustTailCall()))
479  fail(DL, DAG, "WebAssembly doesn't support tail call yet");
480  CLI.IsTailCall = false;
481 
483  if (Ins.size() > 1)
484  fail(DL, DAG, "WebAssembly doesn't support more than 1 returned value yet");
485 
486  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
487  SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
488  for (unsigned i = 0; i < Outs.size(); ++i) {
489  const ISD::OutputArg &Out = Outs[i];
490  SDValue &OutVal = OutVals[i];
491  if (Out.Flags.isNest())
492  fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
493  if (Out.Flags.isInAlloca())
494  fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments");
495  if (Out.Flags.isInConsecutiveRegs())
496  fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments");
497  if (Out.Flags.isInConsecutiveRegsLast())
498  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
499  if (Out.Flags.isByVal() && Out.Flags.getByValSize() != 0) {
500  auto &MFI = MF.getFrameInfo();
501  int FI = MFI.CreateStackObject(Out.Flags.getByValSize(),
502  Out.Flags.getByValAlign(),
503  /*isSS=*/false);
504  SDValue SizeNode =
505  DAG.getConstant(Out.Flags.getByValSize(), DL, MVT::i32);
506  SDValue FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
507  Chain = DAG.getMemcpy(
508  Chain, DL, FINode, OutVal, SizeNode, Out.Flags.getByValAlign(),
509  /*isVolatile*/ false, /*AlwaysInline=*/false,
510  /*isTailCall*/ false, MachinePointerInfo(), MachinePointerInfo());
511  OutVal = FINode;
512  }
513  }
514 
515  bool IsVarArg = CLI.IsVarArg;
516  unsigned NumFixedArgs = CLI.NumFixedArgs;
517 
518  auto PtrVT = getPointerTy(Layout);
519 
520  // Analyze operands of the call, assigning locations to each operand.
522  CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
523 
524  if (IsVarArg) {
525  // Outgoing non-fixed arguments are placed in a buffer. First
526  // compute their offsets and the total amount of buffer space needed.
527  for (SDValue Arg :
528  make_range(OutVals.begin() + NumFixedArgs, OutVals.end())) {
529  EVT VT = Arg.getValueType();
530  assert(VT != MVT::iPTR && "Legalized args should be concrete");
531  Type *Ty = VT.getTypeForEVT(*DAG.getContext());
532  unsigned Offset = CCInfo.AllocateStack(Layout.getTypeAllocSize(Ty),
533  Layout.getABITypeAlignment(Ty));
534  CCInfo.addLoc(CCValAssign::getMem(ArgLocs.size(), VT.getSimpleVT(),
535  Offset, VT.getSimpleVT(),
537  }
538  }
539 
540  unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
541 
542  SDValue FINode;
543  if (IsVarArg && NumBytes) {
544  // For non-fixed arguments, next emit stores to store the argument values
545  // to the stack buffer at the offsets computed above.
546  int FI = MF.getFrameInfo().CreateStackObject(NumBytes,
547  Layout.getStackAlignment(),
548  /*isSS=*/false);
549  unsigned ValNo = 0;
551  for (SDValue Arg :
552  make_range(OutVals.begin() + NumFixedArgs, OutVals.end())) {
553  assert(ArgLocs[ValNo].getValNo() == ValNo &&
554  "ArgLocs should remain in order and only hold varargs args");
555  unsigned Offset = ArgLocs[ValNo++].getLocMemOffset();
556  FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
557  SDValue Add = DAG.getNode(ISD::ADD, DL, PtrVT, FINode,
558  DAG.getConstant(Offset, DL, PtrVT));
559  Chains.push_back(DAG.getStore(
560  Chain, DL, Arg, Add,
561  MachinePointerInfo::getFixedStack(MF, FI, Offset), 0));
562  }
563  if (!Chains.empty())
564  Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
565  } else if (IsVarArg) {
566  FINode = DAG.getIntPtrConstant(0, DL);
567  }
568 
569  // Compute the operands for the CALLn node.
571  Ops.push_back(Chain);
572  Ops.push_back(Callee);
573 
574  // Add all fixed arguments. Note that for non-varargs calls, NumFixedArgs
575  // isn't reliable.
576  Ops.append(OutVals.begin(),
577  IsVarArg ? OutVals.begin() + NumFixedArgs : OutVals.end());
578  // Add a pointer to the vararg buffer.
579  if (IsVarArg) Ops.push_back(FINode);
580 
581  SmallVector<EVT, 8> InTys;
582  for (const auto &In : Ins) {
583  assert(!In.Flags.isByVal() && "byval is not valid for return values");
584  assert(!In.Flags.isNest() && "nest is not valid for return values");
585  if (In.Flags.isInAlloca())
586  fail(DL, DAG, "WebAssembly hasn't implemented inalloca return values");
587  if (In.Flags.isInConsecutiveRegs())
588  fail(DL, DAG, "WebAssembly hasn't implemented cons regs return values");
589  if (In.Flags.isInConsecutiveRegsLast())
590  fail(DL, DAG,
591  "WebAssembly hasn't implemented cons regs last return values");
592  // Ignore In.getOrigAlign() because all our arguments are passed in
593  // registers.
594  InTys.push_back(In.VT);
595  }
596  InTys.push_back(MVT::Other);
597  SDVTList InTyList = DAG.getVTList(InTys);
598  SDValue Res =
599  DAG.getNode(Ins.empty() ? WebAssemblyISD::CALL0 : WebAssemblyISD::CALL1,
600  DL, InTyList, Ops);
601  if (Ins.empty()) {
602  Chain = Res;
603  } else {
604  InVals.push_back(Res);
605  Chain = Res.getValue(1);
606  }
607 
608  return Chain;
609 }
610 
611 bool WebAssemblyTargetLowering::CanLowerReturn(
612  CallingConv::ID /*CallConv*/, MachineFunction & /*MF*/, bool /*IsVarArg*/,
614  LLVMContext & /*Context*/) const {
615  // WebAssembly can't currently handle returning tuples.
616  return Outs.size() <= 1;
617 }
618 
619 SDValue WebAssemblyTargetLowering::LowerReturn(
620  SDValue Chain, CallingConv::ID CallConv, bool /*IsVarArg*/,
622  const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
623  SelectionDAG &DAG) const {
624  assert(Outs.size() <= 1 && "WebAssembly can only return up to one value");
625  if (!CallingConvSupported(CallConv))
626  fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
627 
628  SmallVector<SDValue, 4> RetOps(1, Chain);
629  RetOps.append(OutVals.begin(), OutVals.end());
630  Chain = DAG.getNode(WebAssemblyISD::RETURN, DL, MVT::Other, RetOps);
631 
632  // Record the number and types of the return values.
633  for (const ISD::OutputArg &Out : Outs) {
634  assert(!Out.Flags.isByVal() && "byval is not valid for return values");
635  assert(!Out.Flags.isNest() && "nest is not valid for return values");
636  assert(Out.IsFixed && "non-fixed return value is not valid");
637  if (Out.Flags.isInAlloca())
638  fail(DL, DAG, "WebAssembly hasn't implemented inalloca results");
639  if (Out.Flags.isInConsecutiveRegs())
640  fail(DL, DAG, "WebAssembly hasn't implemented cons regs results");
641  if (Out.Flags.isInConsecutiveRegsLast())
642  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last results");
643  }
644 
645  return Chain;
646 }
647 
648 SDValue WebAssemblyTargetLowering::LowerFormalArguments(
649  SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
650  const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
651  SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
652  if (!CallingConvSupported(CallConv))
653  fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
654 
656  auto *MFI = MF.getInfo<WebAssemblyFunctionInfo>();
657 
658  // Set up the incoming ARGUMENTS value, which serves to represent the liveness
659  // of the incoming values before they're represented by virtual registers.
660  MF.getRegInfo().addLiveIn(WebAssembly::ARGUMENTS);
661 
662  for (const ISD::InputArg &In : Ins) {
663  if (In.Flags.isInAlloca())
664  fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments");
665  if (In.Flags.isNest())
666  fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
667  if (In.Flags.isInConsecutiveRegs())
668  fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments");
669  if (In.Flags.isInConsecutiveRegsLast())
670  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
671  // Ignore In.getOrigAlign() because all our arguments are passed in
672  // registers.
673  InVals.push_back(
674  In.Used
675  ? DAG.getNode(WebAssemblyISD::ARGUMENT, DL, In.VT,
676  DAG.getTargetConstant(InVals.size(), DL, MVT::i32))
677  : DAG.getUNDEF(In.VT));
678 
679  // Record the number and types of arguments.
680  MFI->addParam(In.VT);
681  }
682 
683  // Varargs are copied into a buffer allocated by the caller, and a pointer to
684  // the buffer is passed as an argument.
685  if (IsVarArg) {
686  MVT PtrVT = getPointerTy(MF.getDataLayout());
687  unsigned VarargVreg =
689  MFI->setVarargBufferVreg(VarargVreg);
690  Chain = DAG.getCopyToReg(
691  Chain, DL, VarargVreg,
692  DAG.getNode(WebAssemblyISD::ARGUMENT, DL, PtrVT,
693  DAG.getTargetConstant(Ins.size(), DL, MVT::i32)));
694  MFI->addParam(PtrVT);
695  }
696 
697  // Record the number and types of results.
698  SmallVector<MVT, 4> Params;
700  ComputeSignatureVTs(MF.getFunction(), DAG.getTarget(), Params, Results);
701  for (MVT VT : Results)
702  MFI->addResult(VT);
703 
704  return Chain;
705 }
706 
707 //===----------------------------------------------------------------------===//
708 // Custom lowering hooks.
709 //===----------------------------------------------------------------------===//
710 
711 SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
712  SelectionDAG &DAG) const {
713  SDLoc DL(Op);
714  switch (Op.getOpcode()) {
715  default:
716  llvm_unreachable("unimplemented operation lowering");
717  return SDValue();
718  case ISD::FrameIndex:
719  return LowerFrameIndex(Op, DAG);
720  case ISD::GlobalAddress:
721  return LowerGlobalAddress(Op, DAG);
722  case ISD::ExternalSymbol:
723  return LowerExternalSymbol(Op, DAG);
724  case ISD::JumpTable:
725  return LowerJumpTable(Op, DAG);
726  case ISD::BR_JT:
727  return LowerBR_JT(Op, DAG);
728  case ISD::VASTART:
729  return LowerVASTART(Op, DAG);
730  case ISD::BlockAddress:
731  case ISD::BRIND:
732  fail(DL, DAG, "WebAssembly hasn't implemented computed gotos");
733  return SDValue();
734  case ISD::RETURNADDR: // Probably nothing meaningful can be returned here.
735  fail(DL, DAG, "WebAssembly hasn't implemented __builtin_return_address");
736  return SDValue();
737  case ISD::FRAMEADDR:
738  return LowerFRAMEADDR(Op, DAG);
739  case ISD::CopyToReg:
740  return LowerCopyToReg(Op, DAG);
741  }
742 }
743 
744 SDValue WebAssemblyTargetLowering::LowerCopyToReg(SDValue Op,
745  SelectionDAG &DAG) const {
746  SDValue Src = Op.getOperand(2);
747  if (isa<FrameIndexSDNode>(Src.getNode())) {
748  // CopyToReg nodes don't support FrameIndex operands. Other targets select
749  // the FI to some LEA-like instruction, but since we don't have that, we
750  // need to insert some kind of instruction that can take an FI operand and
751  // produces a value usable by CopyToReg (i.e. in a vreg). So insert a dummy
752  // copy_local between Op and its FI operand.
753  SDValue Chain = Op.getOperand(0);
754  SDLoc DL(Op);
755  unsigned Reg = cast<RegisterSDNode>(Op.getOperand(1))->getReg();
756  EVT VT = Src.getValueType();
757  SDValue Copy(
758  DAG.getMachineNode(VT == MVT::i32 ? WebAssembly::COPY_I32
759  : WebAssembly::COPY_I64,
760  DL, VT, Src),
761  0);
762  return Op.getNode()->getNumValues() == 1
763  ? DAG.getCopyToReg(Chain, DL, Reg, Copy)
764  : DAG.getCopyToReg(Chain, DL, Reg, Copy, Op.getNumOperands() == 4
765  ? Op.getOperand(3)
766  : SDValue());
767  }
768  return SDValue();
769 }
770 
771 SDValue WebAssemblyTargetLowering::LowerFrameIndex(SDValue Op,
772  SelectionDAG &DAG) const {
773  int FI = cast<FrameIndexSDNode>(Op)->getIndex();
774  return DAG.getTargetFrameIndex(FI, Op.getValueType());
775 }
776 
777 SDValue WebAssemblyTargetLowering::LowerFRAMEADDR(SDValue Op,
778  SelectionDAG &DAG) const {
779  // Non-zero depths are not supported by WebAssembly currently. Use the
780  // legalizer's default expansion, which is to return 0 (what this function is
781  // documented to do).
782  if (Op.getConstantOperandVal(0) > 0)
783  return SDValue();
784 
786  EVT VT = Op.getValueType();
787  unsigned FP =
789  return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), FP, VT);
790 }
791 
792 SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
793  SelectionDAG &DAG) const {
794  SDLoc DL(Op);
795  const auto *GA = cast<GlobalAddressSDNode>(Op);
796  EVT VT = Op.getValueType();
797  assert(GA->getTargetFlags() == 0 &&
798  "Unexpected target flags on generic GlobalAddressSDNode");
799  if (GA->getAddressSpace() != 0)
800  fail(DL, DAG, "WebAssembly only expects the 0 address space");
801  return DAG.getNode(
802  WebAssemblyISD::Wrapper, DL, VT,
803  DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset()));
804 }
805 
806 SDValue WebAssemblyTargetLowering::LowerExternalSymbol(
807  SDValue Op, SelectionDAG &DAG) const {
808  SDLoc DL(Op);
809  const auto *ES = cast<ExternalSymbolSDNode>(Op);
810  EVT VT = Op.getValueType();
811  assert(ES->getTargetFlags() == 0 &&
812  "Unexpected target flags on generic ExternalSymbolSDNode");
813  // Set the TargetFlags to 0x1 which indicates that this is a "function"
814  // symbol rather than a data symbol. We do this unconditionally even though
815  // we don't know anything about the symbol other than its name, because all
816  // external symbols used in target-independent SelectionDAG code are for
817  // functions.
818  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
819  DAG.getTargetExternalSymbol(ES->getSymbol(), VT,
820  /*TargetFlags=*/0x1));
821 }
822 
823 SDValue WebAssemblyTargetLowering::LowerJumpTable(SDValue Op,
824  SelectionDAG &DAG) const {
825  // There's no need for a Wrapper node because we always incorporate a jump
826  // table operand into a BR_TABLE instruction, rather than ever
827  // materializing it in a register.
828  const JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
829  return DAG.getTargetJumpTable(JT->getIndex(), Op.getValueType(),
830  JT->getTargetFlags());
831 }
832 
833 SDValue WebAssemblyTargetLowering::LowerBR_JT(SDValue Op,
834  SelectionDAG &DAG) const {
835  SDLoc DL(Op);
836  SDValue Chain = Op.getOperand(0);
837  const auto *JT = cast<JumpTableSDNode>(Op.getOperand(1));
838  SDValue Index = Op.getOperand(2);
839  assert(JT->getTargetFlags() == 0 && "WebAssembly doesn't set target flags");
840 
842  Ops.push_back(Chain);
843  Ops.push_back(Index);
844 
846  const auto &MBBs = MJTI->getJumpTables()[JT->getIndex()].MBBs;
847 
848  // Add an operand for each case.
849  for (auto MBB : MBBs) Ops.push_back(DAG.getBasicBlock(MBB));
850 
851  // TODO: For now, we just pick something arbitrary for a default case for now.
852  // We really want to sniff out the guard and put in the real default case (and
853  // delete the guard).
854  Ops.push_back(DAG.getBasicBlock(MBBs[0]));
855 
856  return DAG.getNode(WebAssemblyISD::BR_TABLE, DL, MVT::Other, Ops);
857 }
858 
859 SDValue WebAssemblyTargetLowering::LowerVASTART(SDValue Op,
860  SelectionDAG &DAG) const {
861  SDLoc DL(Op);
863 
865  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
866 
867  SDValue ArgN = DAG.getCopyFromReg(DAG.getEntryNode(), DL,
868  MFI->getVarargBufferVreg(), PtrVT);
869  return DAG.getStore(Op.getOperand(0), DL, ArgN, Op.getOperand(1),
870  MachinePointerInfo(SV), 0);
871 }
872 
873 //===----------------------------------------------------------------------===//
874 // WebAssembly Optimization Hooks
875 //===----------------------------------------------------------------------===//
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
void setFrameAddressIsTaken(bool T)
static MVT getIntegerVT(unsigned BitWidth)
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
Definition: MathExtras.h:544
This file defines the interfaces that WebAssembly uses to lower LLVM code into a selection DAG...
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:43
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:109
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isInteger() const
Return true if this is an integer or a vector integer type.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
static Type * getDoubleTy(LLVMContext &C)
Definition: Type.cpp:165
const std::vector< MachineJumpTableEntry > & getJumpTables() const
LLVMContext & Context
Diagnostic information for unsupported feature in backend.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:618
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
InputArg - This struct carries flags and type information about a single incoming (formal) argument o...
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:136
bool isVector() const
Return true if this is a vector value type.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(unsigned Reg, unsigned vreg=0)
addLiveIn - Add the specified register as a live-in.
Carry-setting nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:223
static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *msg)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:271
unsigned getReg() const
getReg - Returns the register number.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:138
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain...
Definition: ISDOpcodes.h:667
void setHasFloatingPointExceptions(bool FPExceptions=true)
Tells the code generator that this target supports floating point exceptions and cares about preservi...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:253
SDValue getBasicBlock(MachineBasicBlock *MBB)
Function Alias Analysis Results
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
virtual const TargetRegisterClass * getRegClassFor(MVT VT) const
Return the register class that should be used for the specified value type.
A debug info location.
Definition: DebugLoc.h:34
F(f)
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned char TargetFlags=0)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it...
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:405
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:210
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations...
Definition: ISDOpcodes.h:434
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
const HexagonInstrInfo * TII
static Type * getFloatTy(LLVMContext &C)
Definition: Type.cpp:164
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Definition: ValueTypes.cpp:205
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s), MachineInstr opcode, and operands.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
CopyToReg - This node has three operands: a chain, a register number to set to this value...
Definition: ISDOpcodes.h:170
uint64_t getConstantOperandVal(unsigned i) const
Reg
All possible values of the reg field in the ModR/M byte.
void setCondCodeAction(ISD::CondCode CC, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn&#39;t supported on the target and indicate what to d...
bool isInConsecutiveRegs() const
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:293
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:449
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG...
Definition: ISDOpcodes.h:73
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
This represents a list of ValueType&#39;s that has been intern&#39;d by a SelectionDAG.
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:663
unsigned getSizeInBits() const
This is a fast-path instruction selection class that generates poor code and doesn&#39;t support illegal ...
Definition: FastISel.h:67
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:292
This file declares the WebAssembly-specific subclass of TargetMachine.
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:387
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose...
SDValue getTargetFrameIndex(int FI, EVT VT)
Definition: SelectionDAG.h:609
const TargetMachine & getTarget() const
Definition: SelectionDAG.h:391
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:201
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
Definition: SelectionDAG.h:851
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:561
amdgpu Simplify well known AMD library false Value * Callee
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
unsigned getByValSize() const
TargetInstrInfo - Interface to description of machine instruction set.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:597
static bool CallingConvSupported(CallingConv::ID CallConv)
unsigned const MachineRegisterInfo * MRI
MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
Machine Value Type.
LLVM Basic Block Representation.
Definition: BasicBlock.h:59
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:69
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type...
void ComputeSignatureVTs(const Function &F, const TargetMachine &TM, SmallVectorImpl< MVT > &Params, SmallVectorImpl< MVT > &Results)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE...
Definition: ISDOpcodes.h:696
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:116
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:232
This file provides WebAssembly-specific target descriptions.
unsigned char getTargetFlags() const
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
TRAP - Trapping instruction.
Definition: ISDOpcodes.h:735
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline...
self_iterator getIterator()
Definition: ilist_node.h:82
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:687
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:193
static unsigned NumFixedArgs
Extended Value Type.
Definition: ValueTypes.h:34
uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
Definition: MathExtras.h:632
const AMDGPUAS & AS
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This class contains a discriminated union of information about pointers in memory operands...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
WebAssemblyTargetLowering(const TargetMachine &TM, const WebAssemblySubtarget &STI)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned char TargetFlags=0)
Definition: SelectionDAG.h:614
TokenFactor - This node takes multiple tokens as input and produces a single token result...
Definition: ISDOpcodes.h:50
static MachineBasicBlock * LowerFPToInt(MachineInstr &MI, DebugLoc DL, MachineBasicBlock *BB, const TargetInstrInfo &TII, bool IsUnsigned, bool Int64, bool Float64, unsigned LoweredOpcode)
This file declares the WebAssembly-specific subclass of TargetSubtarget.
Iterator for intrusive lists based on ilist_node.
CCState - This class holds information needed while lowering arguments and return values...
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:210
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:862
Provides information about what library functions are available for the current target.
const DebugLoc & getDebugLoc() const
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo)
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:383
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
Definition: ISDOpcodes.h:556
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
Definition: Constants.cpp:622
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:660
const Function & getFunction() const
Return the LLVM function that this machine code represents.
static mvt_range integer_valuetypes()
unsigned getFrameRegister(const MachineFunction &MF) const override
unsigned getByValAlign() const
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
AddrMode
ARM Addressing Modes.
Definition: ARMBaseInfo.h:172
FMINNAN/FMAXNAN - Behave identically to FMINNUM/FMAXNUM, except that when a single input is NaN...
Definition: ISDOpcodes.h:573
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:396
const WebAssemblyRegisterInfo * getRegisterInfo() const override
amdgpu Simplify well known AMD library false Value Value * Arg
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:606
Representation of each machine instruction.
Definition: MachineInstr.h:60
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the source.
Definition: ISDOpcodes.h:692
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
C - The default llvm calling convention, compatible with C.
Definition: CallingConv.h:35
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:120
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB &#39;Other&#39; at the position From, and insert it into this MBB right before &#39;...
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:686
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:206
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:61
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:464
bool isInConsecutiveRegsLast() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
TargetOptions Options
Definition: TargetMachine.h:98
#define I(x, y, z)
Definition: MD5.cpp:58
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
This file declares WebAssembly-specific per-machine-function information.
void setStackPointerRegisterToSaveRestore(unsigned R)
If set to a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save and restore.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
unsigned getOpcode() const
FSINCOS - Compute both fsin and fcos as a single operation.
Definition: ISDOpcodes.h:576
SDValue getValue(unsigned R) const
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LLVM Value Representation.
Definition: Value.h:73
FMA - Perform a * b + c with no intermediate rounding step.
Definition: ISDOpcodes.h:278
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:59
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
const WebAssemblyInstrInfo * getInstrInfo() const override
unsigned getNumOperands() const
const SDValue & getOperand(unsigned i) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:298
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
LLVMContext * getContext() const
Definition: SelectionDAG.h:396
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned char TargetFlags=0)
Definition: SelectionDAG.h:603
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:356
BRIND - Indirect branch.
Definition: ISDOpcodes.h:602
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary...
Definition: ISDOpcodes.h:591