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 /// 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->hasSignExt()) {
121  for (auto T : {MVT::i8, MVT::i16, MVT::i32})
123  }
124 
125  // Dynamic stack allocation: use the default expansion.
129 
132 
133  // Expand these forms; we pattern-match the forms that we can handle in isel.
134  for (auto T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64})
135  for (auto Op : {ISD::BR_CC, ISD::SELECT_CC})
137 
138  // We have custom switch handling.
140 
141  // WebAssembly doesn't have:
142  // - Floating-point extending loads.
143  // - Floating-point truncating stores.
144  // - i1 extending loads.
147  for (auto T : MVT::integer_valuetypes())
150 
151  // Trap lowers to wasm unreachable
153 
154  // Exception handling intrinsics
156 
158 }
159 
160 FastISel *WebAssemblyTargetLowering::createFastISel(
161  FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const {
162  return WebAssembly::createFastISel(FuncInfo, LibInfo);
163 }
164 
165 bool WebAssemblyTargetLowering::isOffsetFoldingLegal(
166  const GlobalAddressSDNode * /*GA*/) const {
167  // All offsets can be folded.
168  return true;
169 }
170 
171 MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout & /*DL*/,
172  EVT VT) const {
173  unsigned BitWidth = NextPowerOf2(VT.getSizeInBits() - 1);
174  if (BitWidth > 1 && BitWidth < 8) BitWidth = 8;
175 
176  if (BitWidth > 64) {
177  // The shift will be lowered to a libcall, and compiler-rt libcalls expect
178  // the count to be an i32.
179  BitWidth = 32;
180  assert(BitWidth >= Log2_32_Ceil(VT.getSizeInBits()) &&
181  "32-bit shift counts ought to be enough for anyone");
182  }
183 
184  MVT Result = MVT::getIntegerVT(BitWidth);
186  "Unable to represent scalar shift amount type");
187  return Result;
188 }
189 
190 // Lower an fp-to-int conversion operator from the LLVM opcode, which has an
191 // undefined result on invalid/overflow, to the WebAssembly opcode, which
192 // traps on invalid/overflow.
193 static MachineBasicBlock *
195  MachineInstr &MI,
196  DebugLoc DL,
197  MachineBasicBlock *BB,
198  const TargetInstrInfo &TII,
199  bool IsUnsigned,
200  bool Int64,
201  bool Float64,
202  unsigned LoweredOpcode
203 ) {
205 
206  unsigned OutReg = MI.getOperand(0).getReg();
207  unsigned InReg = MI.getOperand(1).getReg();
208 
209  unsigned Abs = Float64 ? WebAssembly::ABS_F64 : WebAssembly::ABS_F32;
210  unsigned FConst = Float64 ? WebAssembly::CONST_F64 : WebAssembly::CONST_F32;
211  unsigned LT = Float64 ? WebAssembly::LT_F64 : WebAssembly::LT_F32;
212  unsigned GE = Float64 ? WebAssembly::GE_F64 : WebAssembly::GE_F32;
213  unsigned IConst = Int64 ? WebAssembly::CONST_I64 : WebAssembly::CONST_I32;
214  unsigned Eqz = WebAssembly::EQZ_I32;
215  unsigned And = WebAssembly::AND_I32;
216  int64_t Limit = Int64 ? INT64_MIN : INT32_MIN;
217  int64_t Substitute = IsUnsigned ? 0 : Limit;
218  double CmpVal = IsUnsigned ? -(double)Limit * 2.0 : -(double)Limit;
219  auto &Context = BB->getParent()->getFunction().getContext();
221 
222  const BasicBlock *LLVM_BB = BB->getBasicBlock();
223  MachineFunction *F = BB->getParent();
224  MachineBasicBlock *TrueMBB = F->CreateMachineBasicBlock(LLVM_BB);
225  MachineBasicBlock *FalseMBB = F->CreateMachineBasicBlock(LLVM_BB);
226  MachineBasicBlock *DoneMBB = F->CreateMachineBasicBlock(LLVM_BB);
227 
229  F->insert(It, FalseMBB);
230  F->insert(It, TrueMBB);
231  F->insert(It, DoneMBB);
232 
233  // Transfer the remainder of BB and its successor edges to DoneMBB.
234  DoneMBB->splice(DoneMBB->begin(), BB,
235  std::next(MachineBasicBlock::iterator(MI)),
236  BB->end());
237  DoneMBB->transferSuccessorsAndUpdatePHIs(BB);
238 
239  BB->addSuccessor(TrueMBB);
240  BB->addSuccessor(FalseMBB);
241  TrueMBB->addSuccessor(DoneMBB);
242  FalseMBB->addSuccessor(DoneMBB);
243 
244  unsigned Tmp0, Tmp1, CmpReg, EqzReg, FalseReg, TrueReg;
245  Tmp0 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
246  Tmp1 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
247  CmpReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
248  EqzReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
249  FalseReg = MRI.createVirtualRegister(MRI.getRegClass(OutReg));
250  TrueReg = MRI.createVirtualRegister(MRI.getRegClass(OutReg));
251 
252  MI.eraseFromParent();
253  // For signed numbers, we can do a single comparison to determine whether
254  // fabs(x) is within range.
255  if (IsUnsigned) {
256  Tmp0 = InReg;
257  } else {
258  BuildMI(BB, DL, TII.get(Abs), Tmp0)
259  .addReg(InReg);
260  }
261  BuildMI(BB, DL, TII.get(FConst), Tmp1)
262  .addFPImm(cast<ConstantFP>(ConstantFP::get(Ty, CmpVal)));
263  BuildMI(BB, DL, TII.get(LT), CmpReg)
264  .addReg(Tmp0)
265  .addReg(Tmp1);
266 
267  // For unsigned numbers, we have to do a separate comparison with zero.
268  if (IsUnsigned) {
269  Tmp1 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
270  unsigned SecondCmpReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
271  unsigned AndReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
272  BuildMI(BB, DL, TII.get(FConst), Tmp1)
273  .addFPImm(cast<ConstantFP>(ConstantFP::get(Ty, 0.0)));
274  BuildMI(BB, DL, TII.get(GE), SecondCmpReg)
275  .addReg(Tmp0)
276  .addReg(Tmp1);
277  BuildMI(BB, DL, TII.get(And), AndReg)
278  .addReg(CmpReg)
279  .addReg(SecondCmpReg);
280  CmpReg = AndReg;
281  }
282 
283  BuildMI(BB, DL, TII.get(Eqz), EqzReg)
284  .addReg(CmpReg);
285 
286  // Create the CFG diamond to select between doing the conversion or using
287  // the substitute value.
288  BuildMI(BB, DL, TII.get(WebAssembly::BR_IF))
289  .addMBB(TrueMBB)
290  .addReg(EqzReg);
291  BuildMI(FalseMBB, DL, TII.get(LoweredOpcode), FalseReg)
292  .addReg(InReg);
293  BuildMI(FalseMBB, DL, TII.get(WebAssembly::BR))
294  .addMBB(DoneMBB);
295  BuildMI(TrueMBB, DL, TII.get(IConst), TrueReg)
296  .addImm(Substitute);
297  BuildMI(*DoneMBB, DoneMBB->begin(), DL, TII.get(TargetOpcode::PHI), OutReg)
298  .addReg(FalseReg)
299  .addMBB(FalseMBB)
300  .addReg(TrueReg)
301  .addMBB(TrueMBB);
302 
303  return DoneMBB;
304 }
305 
307 WebAssemblyTargetLowering::EmitInstrWithCustomInserter(
308  MachineInstr &MI,
310 ) const {
311  const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
312  DebugLoc DL = MI.getDebugLoc();
313 
314  switch (MI.getOpcode()) {
315  default: llvm_unreachable("Unexpected instr type to insert");
316  case WebAssembly::FP_TO_SINT_I32_F32:
317  return LowerFPToInt(MI, DL, BB, TII, false, false, false,
318  WebAssembly::I32_TRUNC_S_F32);
319  case WebAssembly::FP_TO_UINT_I32_F32:
320  return LowerFPToInt(MI, DL, BB, TII, true, false, false,
321  WebAssembly::I32_TRUNC_U_F32);
322  case WebAssembly::FP_TO_SINT_I64_F32:
323  return LowerFPToInt(MI, DL, BB, TII, false, true, false,
324  WebAssembly::I64_TRUNC_S_F32);
325  case WebAssembly::FP_TO_UINT_I64_F32:
326  return LowerFPToInt(MI, DL, BB, TII, true, true, false,
327  WebAssembly::I64_TRUNC_U_F32);
328  case WebAssembly::FP_TO_SINT_I32_F64:
329  return LowerFPToInt(MI, DL, BB, TII, false, false, true,
330  WebAssembly::I32_TRUNC_S_F64);
331  case WebAssembly::FP_TO_UINT_I32_F64:
332  return LowerFPToInt(MI, DL, BB, TII, true, false, true,
333  WebAssembly::I32_TRUNC_U_F64);
334  case WebAssembly::FP_TO_SINT_I64_F64:
335  return LowerFPToInt(MI, DL, BB, TII, false, true, true,
336  WebAssembly::I64_TRUNC_S_F64);
337  case WebAssembly::FP_TO_UINT_I64_F64:
338  return LowerFPToInt(MI, DL, BB, TII, true, true, true,
339  WebAssembly::I64_TRUNC_U_F64);
340  llvm_unreachable("Unexpected instruction to emit with custom inserter");
341  }
342 }
343 
344 const char *WebAssemblyTargetLowering::getTargetNodeName(
345  unsigned Opcode) const {
346  switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
348  break;
349 #define HANDLE_NODETYPE(NODE) \
350  case WebAssemblyISD::NODE: \
351  return "WebAssemblyISD::" #NODE;
352 #include "WebAssemblyISD.def"
353 #undef HANDLE_NODETYPE
354  }
355  return nullptr;
356 }
357 
358 std::pair<unsigned, const TargetRegisterClass *>
359 WebAssemblyTargetLowering::getRegForInlineAsmConstraint(
360  const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
361  // First, see if this is a constraint that directly corresponds to a
362  // WebAssembly register class.
363  if (Constraint.size() == 1) {
364  switch (Constraint[0]) {
365  case 'r':
366  assert(VT != MVT::iPTR && "Pointer MVT not expected here");
367  if (Subtarget->hasSIMD128() && VT.isVector()) {
368  if (VT.getSizeInBits() == 128)
369  return std::make_pair(0U, &WebAssembly::V128RegClass);
370  }
371  if (VT.isInteger() && !VT.isVector()) {
372  if (VT.getSizeInBits() <= 32)
373  return std::make_pair(0U, &WebAssembly::I32RegClass);
374  if (VT.getSizeInBits() <= 64)
375  return std::make_pair(0U, &WebAssembly::I64RegClass);
376  }
377  break;
378  default:
379  break;
380  }
381  }
382 
383  return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
384 }
385 
386 bool WebAssemblyTargetLowering::isCheapToSpeculateCttz() const {
387  // Assume ctz is a relatively cheap operation.
388  return true;
389 }
390 
391 bool WebAssemblyTargetLowering::isCheapToSpeculateCtlz() const {
392  // Assume clz is a relatively cheap operation.
393  return true;
394 }
395 
396 bool WebAssemblyTargetLowering::isLegalAddressingMode(const DataLayout &DL,
397  const AddrMode &AM,
398  Type *Ty,
399  unsigned AS,
400  Instruction *I) const {
401  // WebAssembly offsets are added as unsigned without wrapping. The
402  // isLegalAddressingMode gives us no way to determine if wrapping could be
403  // happening, so we approximate this by accepting only non-negative offsets.
404  if (AM.BaseOffs < 0) return false;
405 
406  // WebAssembly has no scale register operands.
407  if (AM.Scale != 0) return false;
408 
409  // Everything else is legal.
410  return true;
411 }
412 
413 bool WebAssemblyTargetLowering::allowsMisalignedMemoryAccesses(
414  EVT /*VT*/, unsigned /*AddrSpace*/, unsigned /*Align*/, bool *Fast) const {
415  // WebAssembly supports unaligned accesses, though it should be declared
416  // with the p2align attribute on loads and stores which do so, and there
417  // may be a performance impact. We tell LLVM they're "fast" because
418  // for the kinds of things that LLVM uses this for (merging adjacent stores
419  // of constants, etc.), WebAssembly implementations will either want the
420  // unaligned access or they'll split anyway.
421  if (Fast) *Fast = true;
422  return true;
423 }
424 
425 bool WebAssemblyTargetLowering::isIntDivCheap(EVT VT,
426  AttributeList Attr) const {
427  // The current thinking is that wasm engines will perform this optimization,
428  // so we can save on code size.
429  return true;
430 }
431 
432 EVT WebAssemblyTargetLowering::getSetCCResultType(const DataLayout &DL,
433  LLVMContext &C,
434  EVT VT) const {
435  if (VT.isVector())
437 
438  return TargetLowering::getSetCCResultType(DL, C, VT);
439 }
440 
441 //===----------------------------------------------------------------------===//
442 // WebAssembly Lowering private implementation.
443 //===----------------------------------------------------------------------===//
444 
445 //===----------------------------------------------------------------------===//
446 // Lowering Code
447 //===----------------------------------------------------------------------===//
448 
449 static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *msg) {
451  DAG.getContext()->diagnose(
453 }
454 
455 // Test whether the given calling convention is supported.
456 static bool CallingConvSupported(CallingConv::ID CallConv) {
457  // We currently support the language-independent target-independent
458  // conventions. We don't yet have a way to annotate calls with properties like
459  // "cold", and we don't have any call-clobbered registers, so these are mostly
460  // all handled the same.
461  return CallConv == CallingConv::C || CallConv == CallingConv::Fast ||
462  CallConv == CallingConv::Cold ||
463  CallConv == CallingConv::PreserveMost ||
464  CallConv == CallingConv::PreserveAll ||
465  CallConv == CallingConv::CXX_FAST_TLS;
466 }
467 
468 SDValue WebAssemblyTargetLowering::LowerCall(
469  CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const {
470  SelectionDAG &DAG = CLI.DAG;
471  SDLoc DL = CLI.DL;
472  SDValue Chain = CLI.Chain;
473  SDValue Callee = CLI.Callee;
475  auto Layout = MF.getDataLayout();
476 
477  CallingConv::ID CallConv = CLI.CallConv;
478  if (!CallingConvSupported(CallConv))
479  fail(DL, DAG,
480  "WebAssembly doesn't support language-specific or target-specific "
481  "calling conventions yet");
482  if (CLI.IsPatchPoint)
483  fail(DL, DAG, "WebAssembly doesn't support patch point yet");
484 
485  // WebAssembly doesn't currently support explicit tail calls. If they are
486  // required, fail. Otherwise, just disable them.
487  if ((CallConv == CallingConv::Fast && CLI.IsTailCall &&
489  (CLI.CS && CLI.CS.isMustTailCall()))
490  fail(DL, DAG, "WebAssembly doesn't support tail call yet");
491  CLI.IsTailCall = false;
492 
494  if (Ins.size() > 1)
495  fail(DL, DAG, "WebAssembly doesn't support more than 1 returned value yet");
496 
497  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
498  SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
499  unsigned NumFixedArgs = 0;
500  for (unsigned i = 0; i < Outs.size(); ++i) {
501  const ISD::OutputArg &Out = Outs[i];
502  SDValue &OutVal = OutVals[i];
503  if (Out.Flags.isNest())
504  fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
505  if (Out.Flags.isInAlloca())
506  fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments");
507  if (Out.Flags.isInConsecutiveRegs())
508  fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments");
509  if (Out.Flags.isInConsecutiveRegsLast())
510  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
511  if (Out.Flags.isByVal() && Out.Flags.getByValSize() != 0) {
512  auto &MFI = MF.getFrameInfo();
513  int FI = MFI.CreateStackObject(Out.Flags.getByValSize(),
514  Out.Flags.getByValAlign(),
515  /*isSS=*/false);
516  SDValue SizeNode =
517  DAG.getConstant(Out.Flags.getByValSize(), DL, MVT::i32);
518  SDValue FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
519  Chain = DAG.getMemcpy(
520  Chain, DL, FINode, OutVal, SizeNode, Out.Flags.getByValAlign(),
521  /*isVolatile*/ false, /*AlwaysInline=*/false,
522  /*isTailCall*/ false, MachinePointerInfo(), MachinePointerInfo());
523  OutVal = FINode;
524  }
525  // Count the number of fixed args *after* legalization.
526  NumFixedArgs += Out.IsFixed;
527  }
528 
529  bool IsVarArg = CLI.IsVarArg;
530  auto PtrVT = getPointerTy(Layout);
531 
532  // Analyze operands of the call, assigning locations to each operand.
534  CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
535 
536  if (IsVarArg) {
537  // Outgoing non-fixed arguments are placed in a buffer. First
538  // compute their offsets and the total amount of buffer space needed.
539  for (SDValue Arg :
540  make_range(OutVals.begin() + NumFixedArgs, OutVals.end())) {
541  EVT VT = Arg.getValueType();
542  assert(VT != MVT::iPTR && "Legalized args should be concrete");
543  Type *Ty = VT.getTypeForEVT(*DAG.getContext());
544  unsigned Offset = CCInfo.AllocateStack(Layout.getTypeAllocSize(Ty),
545  Layout.getABITypeAlignment(Ty));
546  CCInfo.addLoc(CCValAssign::getMem(ArgLocs.size(), VT.getSimpleVT(),
547  Offset, VT.getSimpleVT(),
549  }
550  }
551 
552  unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
553 
554  SDValue FINode;
555  if (IsVarArg && NumBytes) {
556  // For non-fixed arguments, next emit stores to store the argument values
557  // to the stack buffer at the offsets computed above.
558  int FI = MF.getFrameInfo().CreateStackObject(NumBytes,
559  Layout.getStackAlignment(),
560  /*isSS=*/false);
561  unsigned ValNo = 0;
563  for (SDValue Arg :
564  make_range(OutVals.begin() + NumFixedArgs, OutVals.end())) {
565  assert(ArgLocs[ValNo].getValNo() == ValNo &&
566  "ArgLocs should remain in order and only hold varargs args");
567  unsigned Offset = ArgLocs[ValNo++].getLocMemOffset();
568  FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
569  SDValue Add = DAG.getNode(ISD::ADD, DL, PtrVT, FINode,
570  DAG.getConstant(Offset, DL, PtrVT));
571  Chains.push_back(DAG.getStore(
572  Chain, DL, Arg, Add,
573  MachinePointerInfo::getFixedStack(MF, FI, Offset), 0));
574  }
575  if (!Chains.empty())
576  Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
577  } else if (IsVarArg) {
578  FINode = DAG.getIntPtrConstant(0, DL);
579  }
580 
581  // Compute the operands for the CALLn node.
583  Ops.push_back(Chain);
584  Ops.push_back(Callee);
585 
586  // Add all fixed arguments. Note that for non-varargs calls, NumFixedArgs
587  // isn't reliable.
588  Ops.append(OutVals.begin(),
589  IsVarArg ? OutVals.begin() + NumFixedArgs : OutVals.end());
590  // Add a pointer to the vararg buffer.
591  if (IsVarArg) Ops.push_back(FINode);
592 
593  SmallVector<EVT, 8> InTys;
594  for (const auto &In : Ins) {
595  assert(!In.Flags.isByVal() && "byval is not valid for return values");
596  assert(!In.Flags.isNest() && "nest is not valid for return values");
597  if (In.Flags.isInAlloca())
598  fail(DL, DAG, "WebAssembly hasn't implemented inalloca return values");
599  if (In.Flags.isInConsecutiveRegs())
600  fail(DL, DAG, "WebAssembly hasn't implemented cons regs return values");
601  if (In.Flags.isInConsecutiveRegsLast())
602  fail(DL, DAG,
603  "WebAssembly hasn't implemented cons regs last return values");
604  // Ignore In.getOrigAlign() because all our arguments are passed in
605  // registers.
606  InTys.push_back(In.VT);
607  }
608  InTys.push_back(MVT::Other);
609  SDVTList InTyList = DAG.getVTList(InTys);
610  SDValue Res =
611  DAG.getNode(Ins.empty() ? WebAssemblyISD::CALL0 : WebAssemblyISD::CALL1,
612  DL, InTyList, Ops);
613  if (Ins.empty()) {
614  Chain = Res;
615  } else {
616  InVals.push_back(Res);
617  Chain = Res.getValue(1);
618  }
619 
620  return Chain;
621 }
622 
623 bool WebAssemblyTargetLowering::CanLowerReturn(
624  CallingConv::ID /*CallConv*/, MachineFunction & /*MF*/, bool /*IsVarArg*/,
626  LLVMContext & /*Context*/) const {
627  // WebAssembly can't currently handle returning tuples.
628  return Outs.size() <= 1;
629 }
630 
631 SDValue WebAssemblyTargetLowering::LowerReturn(
632  SDValue Chain, CallingConv::ID CallConv, bool /*IsVarArg*/,
634  const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
635  SelectionDAG &DAG) const {
636  assert(Outs.size() <= 1 && "WebAssembly can only return up to one value");
637  if (!CallingConvSupported(CallConv))
638  fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
639 
640  SmallVector<SDValue, 4> RetOps(1, Chain);
641  RetOps.append(OutVals.begin(), OutVals.end());
642  Chain = DAG.getNode(WebAssemblyISD::RETURN, DL, MVT::Other, RetOps);
643 
644  // Record the number and types of the return values.
645  for (const ISD::OutputArg &Out : Outs) {
646  assert(!Out.Flags.isByVal() && "byval is not valid for return values");
647  assert(!Out.Flags.isNest() && "nest is not valid for return values");
648  assert(Out.IsFixed && "non-fixed return value is not valid");
649  if (Out.Flags.isInAlloca())
650  fail(DL, DAG, "WebAssembly hasn't implemented inalloca results");
651  if (Out.Flags.isInConsecutiveRegs())
652  fail(DL, DAG, "WebAssembly hasn't implemented cons regs results");
653  if (Out.Flags.isInConsecutiveRegsLast())
654  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last results");
655  }
656 
657  return Chain;
658 }
659 
660 SDValue WebAssemblyTargetLowering::LowerFormalArguments(
661  SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
662  const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
663  SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
664  if (!CallingConvSupported(CallConv))
665  fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
666 
668  auto *MFI = MF.getInfo<WebAssemblyFunctionInfo>();
669 
670  // Set up the incoming ARGUMENTS value, which serves to represent the liveness
671  // of the incoming values before they're represented by virtual registers.
672  MF.getRegInfo().addLiveIn(WebAssembly::ARGUMENTS);
673 
674  for (const ISD::InputArg &In : Ins) {
675  if (In.Flags.isInAlloca())
676  fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments");
677  if (In.Flags.isNest())
678  fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
679  if (In.Flags.isInConsecutiveRegs())
680  fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments");
681  if (In.Flags.isInConsecutiveRegsLast())
682  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
683  // Ignore In.getOrigAlign() because all our arguments are passed in
684  // registers.
685  InVals.push_back(
686  In.Used
687  ? DAG.getNode(WebAssemblyISD::ARGUMENT, DL, In.VT,
688  DAG.getTargetConstant(InVals.size(), DL, MVT::i32))
689  : DAG.getUNDEF(In.VT));
690 
691  // Record the number and types of arguments.
692  MFI->addParam(In.VT);
693  }
694 
695  // Varargs are copied into a buffer allocated by the caller, and a pointer to
696  // the buffer is passed as an argument.
697  if (IsVarArg) {
698  MVT PtrVT = getPointerTy(MF.getDataLayout());
699  unsigned VarargVreg =
701  MFI->setVarargBufferVreg(VarargVreg);
702  Chain = DAG.getCopyToReg(
703  Chain, DL, VarargVreg,
704  DAG.getNode(WebAssemblyISD::ARGUMENT, DL, PtrVT,
705  DAG.getTargetConstant(Ins.size(), DL, MVT::i32)));
706  MFI->addParam(PtrVT);
707  }
708 
709  // Record the number and types of results.
710  SmallVector<MVT, 4> Params;
712  ComputeSignatureVTs(MF.getFunction(), DAG.getTarget(), Params, Results);
713  for (MVT VT : Results)
714  MFI->addResult(VT);
715 
716  return Chain;
717 }
718 
719 //===----------------------------------------------------------------------===//
720 // Custom lowering hooks.
721 //===----------------------------------------------------------------------===//
722 
723 SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
724  SelectionDAG &DAG) const {
725  SDLoc DL(Op);
726  switch (Op.getOpcode()) {
727  default:
728  llvm_unreachable("unimplemented operation lowering");
729  return SDValue();
730  case ISD::FrameIndex:
731  return LowerFrameIndex(Op, DAG);
732  case ISD::GlobalAddress:
733  return LowerGlobalAddress(Op, DAG);
734  case ISD::ExternalSymbol:
735  return LowerExternalSymbol(Op, DAG);
736  case ISD::JumpTable:
737  return LowerJumpTable(Op, DAG);
738  case ISD::BR_JT:
739  return LowerBR_JT(Op, DAG);
740  case ISD::VASTART:
741  return LowerVASTART(Op, DAG);
742  case ISD::BlockAddress:
743  case ISD::BRIND:
744  fail(DL, DAG, "WebAssembly hasn't implemented computed gotos");
745  return SDValue();
746  case ISD::RETURNADDR: // Probably nothing meaningful can be returned here.
747  fail(DL, DAG, "WebAssembly hasn't implemented __builtin_return_address");
748  return SDValue();
749  case ISD::FRAMEADDR:
750  return LowerFRAMEADDR(Op, DAG);
751  case ISD::CopyToReg:
752  return LowerCopyToReg(Op, DAG);
754  return LowerINTRINSIC_WO_CHAIN(Op, DAG);
755  }
756 }
757 
758 SDValue WebAssemblyTargetLowering::LowerCopyToReg(SDValue Op,
759  SelectionDAG &DAG) const {
760  SDValue Src = Op.getOperand(2);
761  if (isa<FrameIndexSDNode>(Src.getNode())) {
762  // CopyToReg nodes don't support FrameIndex operands. Other targets select
763  // the FI to some LEA-like instruction, but since we don't have that, we
764  // need to insert some kind of instruction that can take an FI operand and
765  // produces a value usable by CopyToReg (i.e. in a vreg). So insert a dummy
766  // copy_local between Op and its FI operand.
767  SDValue Chain = Op.getOperand(0);
768  SDLoc DL(Op);
769  unsigned Reg = cast<RegisterSDNode>(Op.getOperand(1))->getReg();
770  EVT VT = Src.getValueType();
771  SDValue Copy(
772  DAG.getMachineNode(VT == MVT::i32 ? WebAssembly::COPY_I32
773  : WebAssembly::COPY_I64,
774  DL, VT, Src),
775  0);
776  return Op.getNode()->getNumValues() == 1
777  ? DAG.getCopyToReg(Chain, DL, Reg, Copy)
778  : DAG.getCopyToReg(Chain, DL, Reg, Copy, Op.getNumOperands() == 4
779  ? Op.getOperand(3)
780  : SDValue());
781  }
782  return SDValue();
783 }
784 
785 SDValue WebAssemblyTargetLowering::LowerFrameIndex(SDValue Op,
786  SelectionDAG &DAG) const {
787  int FI = cast<FrameIndexSDNode>(Op)->getIndex();
788  return DAG.getTargetFrameIndex(FI, Op.getValueType());
789 }
790 
791 SDValue WebAssemblyTargetLowering::LowerFRAMEADDR(SDValue Op,
792  SelectionDAG &DAG) const {
793  // Non-zero depths are not supported by WebAssembly currently. Use the
794  // legalizer's default expansion, which is to return 0 (what this function is
795  // documented to do).
796  if (Op.getConstantOperandVal(0) > 0)
797  return SDValue();
798 
800  EVT VT = Op.getValueType();
801  unsigned FP =
803  return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), FP, VT);
804 }
805 
806 SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
807  SelectionDAG &DAG) const {
808  SDLoc DL(Op);
809  const auto *GA = cast<GlobalAddressSDNode>(Op);
810  EVT VT = Op.getValueType();
811  assert(GA->getTargetFlags() == 0 &&
812  "Unexpected target flags on generic GlobalAddressSDNode");
813  if (GA->getAddressSpace() != 0)
814  fail(DL, DAG, "WebAssembly only expects the 0 address space");
815  return DAG.getNode(
816  WebAssemblyISD::Wrapper, DL, VT,
817  DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset()));
818 }
819 
820 SDValue WebAssemblyTargetLowering::LowerExternalSymbol(
821  SDValue Op, SelectionDAG &DAG) const {
822  SDLoc DL(Op);
823  const auto *ES = cast<ExternalSymbolSDNode>(Op);
824  EVT VT = Op.getValueType();
825  assert(ES->getTargetFlags() == 0 &&
826  "Unexpected target flags on generic ExternalSymbolSDNode");
827  // Set the TargetFlags to 0x1 which indicates that this is a "function"
828  // symbol rather than a data symbol. We do this unconditionally even though
829  // we don't know anything about the symbol other than its name, because all
830  // external symbols used in target-independent SelectionDAG code are for
831  // functions.
832  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
833  DAG.getTargetExternalSymbol(ES->getSymbol(), VT,
834  /*TargetFlags=*/0x1));
835 }
836 
837 SDValue WebAssemblyTargetLowering::LowerJumpTable(SDValue Op,
838  SelectionDAG &DAG) const {
839  // There's no need for a Wrapper node because we always incorporate a jump
840  // table operand into a BR_TABLE instruction, rather than ever
841  // materializing it in a register.
842  const JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
843  return DAG.getTargetJumpTable(JT->getIndex(), Op.getValueType(),
844  JT->getTargetFlags());
845 }
846 
847 SDValue WebAssemblyTargetLowering::LowerBR_JT(SDValue Op,
848  SelectionDAG &DAG) const {
849  SDLoc DL(Op);
850  SDValue Chain = Op.getOperand(0);
851  const auto *JT = cast<JumpTableSDNode>(Op.getOperand(1));
852  SDValue Index = Op.getOperand(2);
853  assert(JT->getTargetFlags() == 0 && "WebAssembly doesn't set target flags");
854 
856  Ops.push_back(Chain);
857  Ops.push_back(Index);
858 
860  const auto &MBBs = MJTI->getJumpTables()[JT->getIndex()].MBBs;
861 
862  // Add an operand for each case.
863  for (auto MBB : MBBs) Ops.push_back(DAG.getBasicBlock(MBB));
864 
865  // TODO: For now, we just pick something arbitrary for a default case for now.
866  // We really want to sniff out the guard and put in the real default case (and
867  // delete the guard).
868  Ops.push_back(DAG.getBasicBlock(MBBs[0]));
869 
870  return DAG.getNode(WebAssemblyISD::BR_TABLE, DL, MVT::Other, Ops);
871 }
872 
873 SDValue WebAssemblyTargetLowering::LowerVASTART(SDValue Op,
874  SelectionDAG &DAG) const {
875  SDLoc DL(Op);
877 
879  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
880 
881  SDValue ArgN = DAG.getCopyFromReg(DAG.getEntryNode(), DL,
882  MFI->getVarargBufferVreg(), PtrVT);
883  return DAG.getStore(Op.getOperand(0), DL, ArgN, Op.getOperand(1),
884  MachinePointerInfo(SV), 0);
885 }
886 
887 SDValue
888 WebAssemblyTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
889  SelectionDAG &DAG) const {
890  unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
891  SDLoc DL(Op);
892  switch (IntNo) {
893  default:
894  return {}; // Don't custom lower most intrinsics.
895 
896  case Intrinsic::wasm_lsda:
897  // TODO For now, just return 0 not to crash
898  return DAG.getConstant(0, DL, Op.getValueType());
899  }
900 }
901 
902 //===----------------------------------------------------------------------===//
903 // WebAssembly Optimization Hooks
904 //===----------------------------------------------------------------------===//
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)
uint64_t CallInst * C
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:552
This file defines the interfaces that WebAssembly uses to lower LLVM code into a selection DAG...
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:111
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:611
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:137
bool isVector() const
Return true if this is a vector value type.
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:285
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:660
unsigned Reg
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.
unsigned const TargetRegisterInfo * TRI
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:426
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
#define INT64_MIN
Definition: DataTypes.h:80
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Definition: ValueTypes.cpp:202
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
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:311
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:457
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:656
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:395
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:623
const TargetMachine & getTarget() const
Definition: SelectionDAG.h:399
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:865
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:571
C - The default llvm calling convention, compatible with C.
Definition: CallingConv.h:35
amdgpu Simplify well known AMD library false Value * Callee
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition: ISDOpcodes.h:151
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
bool IsFixed
IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
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:590
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:689
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:117
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:728
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:680
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:194
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:640
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:628
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:222
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
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)
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition: ValueTypes.h:96
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:549
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:684
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:674
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:186
FMINNAN/FMAXNAN - Behave identically to FMINNUM/FMAXNUM, except that when a single input is NaN...
Definition: ISDOpcodes.h:566
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:395
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:43
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:599
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:685
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:121
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:151
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:700
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:62
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:456
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
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
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:569
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:316
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
LLVMContext * getContext() const
Definition: SelectionDAG.h:404
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned char TargetFlags=0)
Definition: SelectionDAG.h:617
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:595
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary...
Definition: ISDOpcodes.h:584