LLVM 24.0.0git
BPFISelLowering.cpp
Go to the documentation of this file.
1//===-- BPFISelLowering.cpp - BPF DAG Lowering Implementation ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interfaces that BPF uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#include "BPFISelLowering.h"
15#include "BPF.h"
16#include "BPFSubtarget.h"
25#include "llvm/IR/DIBuilder.h"
28#include "llvm/IR/Module.h"
29#include "llvm/Support/Debug.h"
33
34using namespace llvm;
35
36#define DEBUG_TYPE "bpf-lower"
37
38static cl::opt<bool> BPFExpandMemcpyInOrder("bpf-expand-memcpy-in-order",
39 cl::Hidden, cl::init(false),
40 cl::desc("Expand memcpy into load/store pairs in order"));
41
43 "bpf-min-jump-table-entries", cl::init(13), cl::Hidden,
44 cl::desc("Set minimum number of entries to use a jump table on BPF"));
45
47 "bpf-allows-libcalls", cl::Hidden, cl::init(false),
48 cl::desc("Allow libcalls instead of rejecting unsupported built-in "
49 "functions"));
50
51static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg,
52 SDValue Val = {}) {
53 std::string Str;
54 if (Val) {
55 raw_string_ostream OS(Str);
56 Val->print(OS);
57 OS << ' ';
58 }
61 MF.getFunction(), Twine(Str).concat(Msg), DL.getDebugLoc()));
62}
63
65 const BPFSubtarget &STI)
66 : TargetLowering(TM, STI) {
67
68 // Set up the register classes.
69 addRegisterClass(MVT::i64, &BPF::GPRRegClass);
70 if (STI.getHasAlu32())
71 addRegisterClass(MVT::i32, &BPF::GPR32RegClass);
72
73 // Compute derived properties from the register classes
75
77
79 setOperationAction(ISD::BR_JT, MVT::Other, STI.hasGotox() ? Custom : Expand);
81
82 if (!STI.hasGotox())
84
86
88 if (STI.hasGotox())
90
94
95 // Set unsupported atomic operations as Custom so
96 // we can emit better error messages than fatal error
97 // from selectiondag.
98 for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
99 if (VT == MVT::i32) {
100 if (STI.getHasAlu32())
101 continue;
102 } else {
104 }
105
111 }
112
113 for (auto VT : {MVT::i32, MVT::i64}) {
116 // No atomic sub insn. Expand it into atomic add of the negated value.
118 }
119
121
122 for (auto VT : { MVT::i32, MVT::i64 }) {
123 if (VT == MVT::i32 && !STI.getHasAlu32())
124 continue;
125
128 if (!STI.hasSdivSmod()) {
131 }
132 if (VT == MVT::i32 || !STI.hasHmul()) {
135 }
148
152 }
153
154 if (STI.getHasAlu32()) {
157 STI.getHasJmp32() ? Custom : Promote);
158 }
159
161 if (!STI.hasMovsx()) {
165 }
166
167 // Extended load operations for i1 types must be promoted
168 for (MVT VT : MVT::integer_valuetypes()) {
172
173 if (!STI.hasLdsx()) {
175 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i16, Expand);
176 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i32, Expand);
177 }
178 }
179
182 // AtomicExpand turns operations on 8 and 16 bits into cmpxchg of the word
183 // that they are in. Its loops start with a relaxed atomic load.
184 if (STI.hasLoadAcqStoreRel())
187
188 // Function alignments
191
193 // LLVM generic code will try to expand memcpy into load/store pairs at this
194 // stage which is before quite a few IR optimization passes, therefore the
195 // loads and stores could potentially be moved apart from each other which
196 // will cause trouble to memcpy pattern matcher inside kernel eBPF JIT
197 // compilers.
198 //
199 // When -bpf-expand-memcpy-in-order specified, we want to defer the expand
200 // of memcpy to later stage in IR optimization pipeline so those load/store
201 // pairs won't be touched and could be kept in order. Hence, we set
202 // MaxStoresPerMem* to zero to disable the generic getMemcpyLoadsAndStores
203 // code path, and ask LLVM to use target expander EmitTargetCodeForMemcpy.
208 } else {
209 // inline memcpy() for kernel to see explicit copy
210 unsigned CommonMaxStores =
212
217 }
218
219 // CPU/Feature control
220 HasAlu32 = STI.getHasAlu32();
221 HasJmp32 = STI.getHasJmp32();
222 HasJmpExt = STI.getHasJmpExt();
223 HasMovsx = STI.hasMovsx();
224 HasLoadAcqStoreRel = STI.hasLoadAcqStoreRel();
225
226 AllowsMisalignedMemAccess = STI.getAllowsMisalignedMemAccess();
227}
228
231 unsigned *Fast) const {
232 // allows-misaligned-mem-access is disabled
233 if (!AllowsMisalignedMemAccess)
234 return false;
235
236 // only allow misalignment for simple value types
237 if (!VT.isSimple())
238 return false;
239
240 // always assume fast mode when misalignment is allowed
241 if (Fast)
242 *Fast = true;
243
244 return true;
245}
246
248 return false;
249}
250
251bool BPFTargetLowering::isTruncateFree(Type *Ty1, Type *Ty2) const {
252 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
253 return false;
254 unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
255 unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
256 return NumBits1 > NumBits2;
257}
258
259bool BPFTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
260 if (!VT1.isInteger() || !VT2.isInteger())
261 return false;
262 unsigned NumBits1 = VT1.getSizeInBits();
263 unsigned NumBits2 = VT2.getSizeInBits();
264 return NumBits1 > NumBits2;
265}
266
267bool BPFTargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
268 if (!getHasAlu32() || !Ty1->isIntegerTy() || !Ty2->isIntegerTy())
269 return false;
270 unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
271 unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
272 return NumBits1 == 32 && NumBits2 == 64;
273}
274
275bool BPFTargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
276 if (!getHasAlu32() || !VT1.isInteger() || !VT2.isInteger())
277 return false;
278 unsigned NumBits1 = VT1.getSizeInBits();
279 unsigned NumBits2 = VT2.getSizeInBits();
280 return NumBits1 == 32 && NumBits2 == 64;
281}
282
283bool BPFTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
284 EVT VT1 = Val.getValueType();
285 if (Val.getOpcode() == ISD::LOAD && VT1.isSimple() && VT2.isSimple()) {
286 MVT MT1 = VT1.getSimpleVT().SimpleTy;
287 MVT MT2 = VT2.getSimpleVT().SimpleTy;
288 if ((MT1 == MVT::i8 || MT1 == MVT::i16 || MT1 == MVT::i32) &&
289 (MT2 == MVT::i32 || MT2 == MVT::i64))
290 return true;
291 }
292 return TargetLoweringBase::isZExtFree(Val, VT2);
293}
294
298
301 if (Constraint.size() == 1) {
302 switch (Constraint[0]) {
303 default:
304 break;
305 case 'w':
306 return C_RegisterClass;
307 }
308 }
309
310 return TargetLowering::getConstraintType(Constraint);
311}
312
313std::pair<unsigned, const TargetRegisterClass *>
315 StringRef Constraint,
316 MVT VT) const {
317 if (Constraint.size() == 1) {
318 // GCC Constraint Letters
319 switch (Constraint[0]) {
320 case 'r': // GENERAL_REGS
321 return std::make_pair(0U, &BPF::GPRRegClass);
322 case 'w':
323 if (HasAlu32)
324 return std::make_pair(0U, &BPF::GPR32RegClass);
325 break;
326 default:
327 break;
328 }
329 }
330
332}
333
334void BPFTargetLowering::ReplaceNodeResults(
336 const char *Msg;
337 uint32_t Opcode = N->getOpcode();
338 switch (Opcode) {
339 default:
340 report_fatal_error("unhandled custom legalization: " + Twine(Opcode));
345 case ISD::ATOMIC_SWAP:
347 if (HasAlu32 || Opcode == ISD::ATOMIC_LOAD_ADD)
348 Msg = "unsupported atomic operation, please use 32/64 bit version";
349 else
350 Msg = "unsupported atomic operation, please use 64 bit version";
351 break;
352 case ISD::ATOMIC_LOAD:
354 return;
355 }
356
357 SDLoc DL(N);
358 // We'll still produce a fatal error downstream, but this diagnostic is more
359 // user-friendly.
360 fail(DL, DAG, Msg);
361}
362
364 switch (Op.getOpcode()) {
365 default:
366 report_fatal_error("unimplemented opcode: " + Twine(Op.getOpcode()));
367 case ISD::BR_CC:
368 return LowerBR_CC(Op, DAG);
369 case ISD::JumpTable:
370 return LowerJumpTable(Op, DAG);
371 case ISD::BR_JT:
372 return LowerBR_JT(Op, DAG);
374 return LowerGlobalAddress(Op, DAG);
376 return LowerConstantPool(Op, DAG);
378 return LowerBlockAddress(Op, DAG);
379 case ISD::SELECT_CC:
380 return LowerSELECT_CC(Op, DAG);
381 case ISD::SDIV:
382 case ISD::SREM:
383 return LowerSDIVSREM(Op, DAG);
384 case ISD::SHL_PARTS:
385 case ISD::SRL_PARTS:
386 case ISD::SRA_PARTS:
387 return LowerShiftParts(Op, DAG);
389 return LowerDYNAMIC_STACKALLOC(Op, DAG);
390 case ISD::ATOMIC_LOAD:
392 return LowerATOMIC_LOAD_STORE(Op, DAG);
394 return LowerATOMIC_FENCE(Op, DAG);
395 case ISD::TRAP:
396 return LowerTRAP(Op, DAG);
397 }
398}
399
400// Calling Convention Implementation
401#define GET_CALLING_CONV_IMPL
402#include "BPFGenCallingConv.inc"
403
404// Apply AssertSext/AssertZext and truncate based on VA's LocInfo.
406 const CCValAssign &VA, EVT RegVT,
407 SDValue ArgValue) {
408 if (VA.getLocInfo() == CCValAssign::SExt)
409 ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
410 DAG.getValueType(VA.getValVT()));
411 else if (VA.getLocInfo() == CCValAssign::ZExt)
412 ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
413 DAG.getValueType(VA.getValVT()));
414 if (VA.getLocInfo() != CCValAssign::Full)
415 ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
416 return ArgValue;
417}
418
419SDValue BPFTargetLowering::LowerFormalArguments(
420 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
421 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
422 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
423 switch (CallConv) {
424 default:
425 report_fatal_error("unimplemented calling convention: " + Twine(CallConv));
426 case CallingConv::C:
428 break;
429 }
430
432 MachineRegisterInfo &RegInfo = MF.getRegInfo();
433
434 // Assign locations to all of the incoming arguments.
436 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
437 CCInfo.AnalyzeFormalArguments(Ins, getHasAlu32() ? CC_BPF32 : CC_BPF64);
438
439 for (size_t I = 0; I < ArgLocs.size(); ++I) {
440 auto &VA = ArgLocs[I];
441 EVT RegVT = VA.getLocVT();
442
443 if (VA.isRegLoc()) {
444 // Arguments passed in registers
445 MVT::SimpleValueType SimpleTy = RegVT.getSimpleVT().SimpleTy;
446 switch (SimpleTy) {
447 default: {
448 std::string Str;
449 {
450 raw_string_ostream OS(Str);
451 RegVT.print(OS);
452 }
453 report_fatal_error("unhandled argument type: " + Twine(Str));
454 }
455 case MVT::i32:
456 case MVT::i64:
457 Register VReg = RegInfo.createVirtualRegister(
458 SimpleTy == MVT::i64 ? &BPF::GPRRegClass : &BPF::GPR32RegClass);
459 RegInfo.addLiveIn(VA.getLocReg(), VReg);
460 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
461 InVals.push_back(convertLocValType(DAG, DL, VA, RegVT, ArgValue));
462 break;
463 }
464 continue;
465 }
466
467 if (VA.isMemLoc()) {
468 // For example, two stack arguments,
469 // arg1: Off = 8
470 // arg2: off = 16
471 int Off = VA.getLocMemOffset() + 8;
472 if (Off > INT16_MAX) {
473 fail(DL, DAG, "extra parameter stack depth exceeded limit");
474 break;
475 }
476
477 // Physical extra argument slot is always 64-bit.
478 SDValue StackVal = DAG.getNode(BPFISD::LOAD_STACK_ARG, DL,
479 DAG.getVTList(MVT::i64, MVT::Other), Chain,
480 DAG.getConstant(Off, DL, MVT::i64));
481 SDValue ArgValue = StackVal.getValue(0);
482 Chain = StackVal.getValue(1);
483 InVals.push_back(convertLocValType(DAG, DL, VA, MVT::i64, ArgValue));
484 continue;
485 }
486 }
487
488 if (IsVarArg)
489 fail(DL, DAG, "variadic functions are not supported");
490 return Chain;
491}
492
493static void resetRegMaskBit(const TargetRegisterInfo *TRI, uint32_t *RegMask,
494 MCRegister Reg) {
495 for (MCPhysReg SubReg : TRI->subregs_inclusive(Reg))
496 RegMask[SubReg / 32] &= ~(1u << (SubReg % 32));
497}
498
500 MachineFunction &MF,
501 const uint32_t *BaseRegMask) {
502 uint32_t *RegMask = MF.allocateRegMask();
503 unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs());
504 memcpy(RegMask, BaseRegMask, sizeof(RegMask[0]) * RegMaskSize);
505 return RegMask;
506}
507
508SDValue BPFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
509 SmallVectorImpl<SDValue> &InVals) const {
510 SelectionDAG &DAG = CLI.DAG;
511 auto &Outs = CLI.Outs;
512 auto &OutVals = CLI.OutVals;
513 auto &Ins = CLI.Ins;
514 SDValue Chain = CLI.Chain;
515 SDValue Callee = CLI.Callee;
516 bool &IsTailCall = CLI.IsTailCall;
517 CallingConv::ID CallConv = CLI.CallConv;
518 bool IsVarArg = CLI.IsVarArg;
520
521 // BPF target does not support tail call optimization.
522 IsTailCall = false;
523
524 switch (CallConv) {
525 default:
526 report_fatal_error("unsupported calling convention: " + Twine(CallConv));
528 case CallingConv::C:
529 break;
530 }
531
532 // Analyze operands of the call, assigning locations to each operand.
534 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
535
536 CCInfo.AnalyzeCallOperands(Outs, getHasAlu32() ? CC_BPF32 : CC_BPF64);
537
538 unsigned NumBytes = CCInfo.getStackSize();
539
540 for (auto &Arg : Outs) {
541 ISD::ArgFlagsTy Flags = Arg.Flags;
542 if (!Flags.isByVal())
543 continue;
544 fail(CLI.DL, DAG, "pass by value not supported", Callee);
545 break;
546 }
547
548 auto PtrVT = getPointerTy(MF.getDataLayout());
549 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
550
552
553 // Walk arg assignments
554 for (size_t i = 0; i < OutVals.size(); ++i) {
555 CCValAssign &VA = ArgLocs[i];
556 SDValue &Arg = OutVals[i];
557
558 // Promote the value if needed.
559 switch (VA.getLocInfo()) {
560 default:
561 report_fatal_error("unhandled location info: " + Twine(VA.getLocInfo()));
563 break;
565 Arg = DAG.getNode(ISD::SIGN_EXTEND, CLI.DL, VA.getLocVT(), Arg);
566 break;
568 Arg = DAG.getNode(ISD::ZERO_EXTEND, CLI.DL, VA.getLocVT(), Arg);
569 break;
571 Arg = DAG.getNode(ISD::ANY_EXTEND, CLI.DL, VA.getLocVT(), Arg);
572 break;
573 }
574
575 // Push arguments into RegsToPass vector
576 if (VA.isRegLoc()) {
577 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
578 continue;
579 }
580
581 if (VA.isMemLoc()) {
582 int Off = -8 - VA.getLocMemOffset();
583 if (Off < INT16_MIN) {
584 fail(CLI.DL, DAG, "extra parameter stack depth exceeded limit");
585 break;
586 }
587
588 assert(Arg.getValueType() == MVT::i64 && "stack args are i64");
589
590 SDValue OffVal = DAG.getConstant(Off, CLI.DL, MVT::i64);
591 Chain = DAG.getNode(BPFISD::STORE_STACK_ARG, CLI.DL, MVT::Other, Chain,
592 OffVal, Arg);
593 continue;
594 }
595
596 report_fatal_error("unhandled argument location");
597 }
598
599 SDValue InGlue;
600
601 // Build a sequence of copy-to-reg nodes chained together with token chain and
602 // flag operands which copy the outgoing args into registers. The InGlue in
603 // necessary since all emitted instructions must be stuck together.
604 for (auto &Reg : RegsToPass) {
605 Chain = DAG.getCopyToReg(Chain, CLI.DL, Reg.first, Reg.second, InGlue);
606 InGlue = Chain.getValue(1);
607 }
608
609 // If the callee is a GlobalAddress node (quite common, every direct call is)
610 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
611 // Likewise ExternalSymbol -> TargetExternalSymbol.
612 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
613 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), CLI.DL, PtrVT,
614 G->getOffset(), 0);
615 } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
616 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
617 StringRef Sym = E->getSymbol();
618 if (!BPFAllowsLibcalls && Sym != BPF_TRAP && Sym != "__multi3" &&
619 Sym != "__divti3" && Sym != "__modti3" && Sym != "__udivti3" &&
620 Sym != "__umodti3" && Sym != "memcpy" && Sym != "memset" &&
621 Sym != "memmove")
622 fail(
623 CLI.DL, DAG,
624 Twine("A call to built-in function '" + Sym + "' is not supported."));
625 }
626
627 // Returns a chain & a flag for retval copy to use.
628 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
630 Ops.push_back(Chain);
631 Ops.push_back(Callee);
632
633 // Add argument registers to the end of the list so that they are
634 // known live into the call.
635 for (auto &Reg : RegsToPass)
636 Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
637
638 bool HasFastCall =
639 (CLI.CB && isa<CallInst>(CLI.CB) && CLI.CB->hasFnAttr("bpf_fastcall"));
640 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
641 if (HasFastCall) {
642 uint32_t *RegMask = regMaskFromTemplate(
643 TRI, MF, TRI->getCallPreservedMask(MF, CallingConv::PreserveAll));
644 for (auto const &RegPair : RegsToPass)
645 resetRegMaskBit(TRI, RegMask, RegPair.first);
646 if (!CLI.CB->getType()->isVoidTy())
647 resetRegMaskBit(TRI, RegMask, BPF::R0);
648 Ops.push_back(DAG.getRegisterMask(RegMask));
649 } else {
650 Ops.push_back(
651 DAG.getRegisterMask(TRI->getCallPreservedMask(MF, CLI.CallConv)));
652 }
653
654 if (InGlue.getNode())
655 Ops.push_back(InGlue);
656
657 Chain = DAG.getNode(BPFISD::CALL, CLI.DL, NodeTys, Ops);
658 InGlue = Chain.getValue(1);
659
660 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
661
662 // Create the CALLSEQ_END node.
663 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, CLI.DL);
664 InGlue = Chain.getValue(1);
665
666 // Handle result values, copying them out of physregs into vregs that we
667 // return.
668 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, CLI.DL, DAG,
669 InVals);
670}
671
673BPFTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
674 bool IsVarArg,
676 const SmallVectorImpl<SDValue> &OutVals,
677 const SDLoc &DL, SelectionDAG &DAG) const {
678 unsigned Opc = BPFISD::RET_GLUE;
679
680 // CCValAssign - represent the assignment of the return value to a location
683
684 // CCState - Info about the registers and stack slot.
685 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
686
687 // Analize return values.
688 CCInfo.AnalyzeReturn(Outs, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
689
690 SDValue Glue;
691 SmallVector<SDValue, 4> RetOps(1, Chain);
692
693 // Copy the result values into the output registers.
694 for (size_t i = 0; i != RVLocs.size(); ++i) {
695 CCValAssign &VA = RVLocs[i];
696 if (!VA.isRegLoc())
697 report_fatal_error("stack return values are not supported");
698
699 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Glue);
700
701 // Guarantee that all emitted copies are stuck together,
702 // avoiding something bad.
703 Glue = Chain.getValue(1);
704 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
705 }
706
707 RetOps[0] = Chain; // Update chain.
708
709 // Add the glue if we have it.
710 if (Glue.getNode())
711 RetOps.push_back(Glue);
712
713 return DAG.getNode(Opc, DL, MVT::Other, RetOps);
714}
715
716SDValue BPFTargetLowering::LowerCallResult(
717 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
718 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
719 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
720
722 // Assign locations to each value returned by this call.
724 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
725
726 CCInfo.AnalyzeCallResult(Ins, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
727
728 // Copy all of the result registers out of their specified physreg.
729 for (auto &Val : RVLocs) {
730 Chain = DAG.getCopyFromReg(Chain, DL, Val.getLocReg(),
731 Val.getValVT(), InGlue).getValue(1);
732 InGlue = Chain.getValue(2);
733 InVals.push_back(Chain.getValue(0));
734 }
735
736 return Chain;
737}
738
740 switch (CC) {
741 default:
742 break;
743 case ISD::SETULT:
744 case ISD::SETULE:
745 case ISD::SETLT:
746 case ISD::SETLE:
748 std::swap(LHS, RHS);
749 break;
750 }
751}
752
753SDValue BPFTargetLowering::LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const {
754 SDLoc DL(Op);
755 fail(DL, DAG,
756 "unsupported signed division, please convert to unsigned div/mod.");
757 return DAG.getUNDEF(Op->getValueType(0));
758}
759
760SDValue BPFTargetLowering::LowerShiftParts(SDValue Op,
761 SelectionDAG &DAG) const {
762 SDValue Lo, Hi;
763 expandShiftParts(Op.getNode(), Lo, Hi, DAG);
764 return DAG.getMergeValues({Lo, Hi}, SDLoc(Op));
765}
766
767SDValue BPFTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
768 SelectionDAG &DAG) const {
769 SDLoc DL(Op);
770 fail(DL, DAG, "unsupported dynamic stack allocation");
771 auto Ops = {DAG.getConstant(0, SDLoc(), Op.getValueType()), Op.getOperand(0)};
772 return DAG.getMergeValues(Ops, SDLoc());
773}
774
775SDValue BPFTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
776 SDValue Chain = Op.getOperand(0);
777 ISD::CondCode CC = Op.getOperandCondCode(1);
778 SDValue LHS = Op.getOperand(2);
779 SDValue RHS = Op.getOperand(3);
780 SDValue Dest = Op.getOperand(4);
781 SDLoc DL(Op);
782
783 if (!getHasJmpExt())
784 NegateCC(LHS, RHS, CC);
785
786 return DAG.getNode(BPFISD::BR_CC, DL, Op.getValueType(), Chain, LHS, RHS,
787 DAG.getConstant(CC, DL, LHS.getValueType()), Dest);
788}
789
790SDValue BPFTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
791 SDValue LHS = Op.getOperand(0);
792 SDValue RHS = Op.getOperand(1);
793 SDValue TrueV = Op.getOperand(2);
794 SDValue FalseV = Op.getOperand(3);
795 ISD::CondCode CC = Op.getOperandCondCode(4);
796 SDLoc DL(Op);
797
798 if (!getHasJmpExt())
799 NegateCC(LHS, RHS, CC);
800
801 SDValue TargetCC = DAG.getConstant(CC, DL, LHS.getValueType());
802 SDValue Ops[] = {LHS, RHS, TargetCC, TrueV, FalseV};
803
804 return DAG.getNode(BPFISD::SELECT_CC, DL, Op.getValueType(), Ops);
805}
806
807SDValue BPFTargetLowering::LowerATOMIC_LOAD_STORE(SDValue Op,
808 SelectionDAG &DAG) const {
809 SDNode *N = Op.getNode();
810 SDLoc DL(N);
811
812 // A seq_cst store is xchg by now, see shouldExpandAtomicStoreInIR(), which
813 // makes load acquire enough for a seq_cst load.
814 if (cast<AtomicSDNode>(N)->getMergedOrdering() ==
816 (N->getOpcode() == ISD::ATOMIC_STORE || !HasLoadAcqStoreRel))
817 fail(DL, DAG,
818 "sequentially consistent (seq_cst) "
819 "atomic load/store is not supported");
820
821 return Op;
822}
823
826 if (!HasLoadAcqStoreRel)
828
829 switch (AI->getOperation()) {
836 // There are insns for 32 and 64 bits.
837 if (AI->getDataLayout().getTypeSizeInBits(AI->getType()) >= 32)
839 [[fallthrough]];
840 default:
842 }
843}
844
847 // Store release is not ordered with a later load. xchg is fully ordered.
848 if (HasLoadAcqStoreRel &&
852}
853
854SDValue BPFTargetLowering::LowerATOMIC_FENCE(SDValue Op,
855 SelectionDAG &DAG) const {
856 SDLoc DL(Op);
857 SyncScope::ID FenceSSID =
858 static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
859
860 if (FenceSSID == SyncScope::SingleThread)
861 // MEMBARRIER is a compiler barrier; it codegens to a no-op.
862 return DAG.getNode(ISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0));
863
864 // There is no insn for that. An atomic insn that returns the old value is
865 // fully ordered: add zero to a slot in the stack. Without alu32 that is
866 // 'lock *(u64 *)(r10 - 8) += r1', which is not ordered.
867 if (!HasAlu32)
868 report_fatal_error("Runtime fence is not supported at the moment");
869
871 SDValue Slot = DAG.CreateStackTemporary(MVT::i64);
873 MF, cast<FrameIndexSDNode>(Slot)->getIndex());
874 SDValue Zero = DAG.getConstant(0, DL, MVT::i64);
875 SDValue Chain = DAG.getStore(Op.getOperand(0), DL, Zero, Slot, PtrInfo);
880 return DAG
881 .getAtomic(ISD::ATOMIC_LOAD_ADD, DL, MVT::i64, Chain, Slot, Zero, MMO)
882 .getValue(1);
883}
884
886 if (auto *Fn = M->getFunction(BPF_TRAP))
887 return Fn;
888
889 FunctionType *FT = FunctionType::get(Type::getVoidTy(M->getContext()), false);
890 Function *NewF =
892 NewF->setDSOLocal(true);
894 NewF->setSection(".ksyms");
895
896 if (M->debug_compile_units().empty())
897 return NewF;
898
899 DIBuilder DBuilder(*M);
900 DITypeArray ParamTypes =
901 DBuilder.getOrCreateTypeArray({nullptr /*void return*/});
902 DISubroutineType *FuncType = DBuilder.createSubroutineType(ParamTypes);
903 DICompileUnit *CU = *M->debug_compile_units_begin();
904 DISubprogram *SP =
905 DBuilder.createFunction(CU, BPF_TRAP, BPF_TRAP, nullptr, 0, FuncType, 0,
906 DINode::FlagZero, DISubprogram::SPFlagZero);
907 NewF->setSubprogram(SP);
908 return NewF;
909}
910
911SDValue BPFTargetLowering::LowerTRAP(SDValue Op, SelectionDAG &DAG) const {
913 TargetLowering::CallLoweringInfo CLI(DAG);
915 SDNode *N = Op.getNode();
916 SDLoc DL(N);
917
919 auto PtrVT = getPointerTy(MF.getDataLayout());
920 CLI.Callee = DAG.getTargetGlobalAddress(Fn, DL, PtrVT);
921 CLI.Chain = N->getOperand(0);
922 CLI.IsTailCall = false;
924 CLI.IsVarArg = false;
925 CLI.DL = std::move(DL);
926 CLI.NoMerge = false;
927 CLI.DoesNotReturn = true;
928 return LowerCall(CLI, InVals);
929}
930
931/// The verifier wants to see that the load from the table is within it. The
932/// range check in front of it doesn't always show that: it can be done on
933/// another copy of the value, e.g. 'w1 = w7; w1 &= 255; if w1 > 24 goto' and
934/// then 'r1 = r7; r1 &= 255' for the index. Make the size of the table a power
935/// of two and mask the index.
936SDValue BPFTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
937 SDLoc DL(Op);
938 SDValue Chain = Op.getOperand(0);
939 unsigned JTI = cast<JumpTableSDNode>(Op.getOperand(1))->getIndex();
940 SDValue Index = Op.getOperand(2);
942 MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
943 std::vector<MachineBasicBlock *> MBBs = MJTI->getJumpTables()[JTI].MBBs;
944 uint64_t Size = PowerOf2Ceil(MBBs.size());
945
946 if (Size != MBBs.size()) {
947 // An index that gets there is out of range: any block of the table will do.
948 MBBs.resize(Size, MBBs.back());
949 MJTI->RemoveJumpTable(JTI);
950 JTI = MJTI->createJumpTableIndex(MBBs);
951 }
952
953 Index = DAG.getNode(ISD::AND, DL, MVT::i64, Index,
954 DAG.getConstant(Size - 1, DL, MVT::i64));
955 Index = DAG.getNode(ISD::SHL, DL, MVT::i64, Index,
956 DAG.getConstant(3, DL, MVT::i64));
957 SDValue Addr = DAG.getNode(ISD::ADD, DL, MVT::i64,
958 DAG.getJumpTable(JTI, MVT::i64), Index);
959 SDValue Load = DAG.getLoad(MVT::i64, DL, Chain, Addr,
961 return DAG.getNode(ISD::BRIND, DL, MVT::Other, Load.getValue(1), Load);
962}
963
964SDValue BPFTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
965 JumpTableSDNode *N = cast<JumpTableSDNode>(Op);
966 return getAddr(N, DAG);
967}
968
970 SelectionDAG &DAG, unsigned Flags) {
971 return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(),
972 N->getOffset(), Flags);
973}
974
976 SelectionDAG &DAG, unsigned Flags) {
977 return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);
978}
979
980template <class NodeTy>
981SDValue BPFTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
982 unsigned Flags) const {
983 SDLoc DL(N);
984
985 SDValue GA = getTargetNode(N, DL, MVT::i64, DAG, Flags);
986
987 return DAG.getNode(BPFISD::Wrapper, DL, MVT::i64, GA);
988}
989
990SDValue BPFTargetLowering::LowerGlobalAddress(SDValue Op,
991 SelectionDAG &DAG) const {
992 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
993 if (N->getOffset() != 0)
994 report_fatal_error("invalid offset for global address: " +
995 Twine(N->getOffset()));
996
997 const GlobalValue *GVal = N->getGlobal();
998 SDLoc DL(Op);
999
1000 // Wrap it in a TargetGlobalAddress
1001 SDValue Addr = DAG.getTargetGlobalAddress(GVal, DL, MVT::i64);
1002
1003 // Emit pseudo instruction
1004 return SDValue(DAG.getMachineNode(BPF::LDIMM64, DL, MVT::i64, Addr), 0);
1005}
1006
1007SDValue BPFTargetLowering::LowerConstantPool(SDValue Op,
1008 SelectionDAG &DAG) const {
1009 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
1010
1011 return getAddr(N, DAG);
1012}
1013
1014SDValue BPFTargetLowering::LowerBlockAddress(SDValue Op,
1015 SelectionDAG &DAG) const {
1016 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
1017 SDLoc DL(Op);
1018
1019 // Wrap it in a TargetBlockAddress
1020 SDValue Addr = DAG.getTargetBlockAddress(BA, MVT::i64);
1021
1022 // Emit pseudo instruction
1023 return SDValue(DAG.getMachineNode(BPF::LDIMM64, DL, MVT::i64, Addr), 0);
1024}
1025
1026unsigned
1027BPFTargetLowering::EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB,
1028 unsigned Reg, bool isSigned) const {
1029 const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
1030 const TargetRegisterClass *RC = getRegClassFor(MVT::i64);
1031 int RShiftOp = isSigned ? BPF::SRA_ri : BPF::SRL_ri;
1032 MachineFunction *F = BB->getParent();
1033 DebugLoc DL = MI.getDebugLoc();
1034
1035 MachineRegisterInfo &RegInfo = F->getRegInfo();
1036
1037 if (!isSigned) {
1038 Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
1039 BuildMI(BB, DL, TII.get(BPF::MOV_32_64), PromotedReg0).addReg(Reg);
1040 return PromotedReg0;
1041 }
1042 Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
1043 Register PromotedReg1 = RegInfo.createVirtualRegister(RC);
1044 Register PromotedReg2 = RegInfo.createVirtualRegister(RC);
1045 if (HasMovsx) {
1046 BuildMI(BB, DL, TII.get(BPF::MOVSX_rr_32), PromotedReg0).addReg(Reg);
1047 } else {
1048 BuildMI(BB, DL, TII.get(BPF::MOV_32_64), PromotedReg0).addReg(Reg);
1049 BuildMI(BB, DL, TII.get(BPF::SLL_ri), PromotedReg1)
1050 .addReg(PromotedReg0).addImm(32);
1051 BuildMI(BB, DL, TII.get(RShiftOp), PromotedReg2)
1052 .addReg(PromotedReg1).addImm(32);
1053 }
1054
1055 return PromotedReg2;
1056}
1057
1059BPFTargetLowering::EmitInstrWithCustomInserterMemcpy(MachineInstr &MI,
1061 const {
1062 MachineFunction *MF = MI.getParent()->getParent();
1063 MachineRegisterInfo &MRI = MF->getRegInfo();
1064 MachineInstrBuilder MIB(*MF, MI);
1065 unsigned ScratchReg;
1066
1067 // This function does custom insertion during lowering BPFISD::MEMCPY which
1068 // only has two register operands from memcpy semantics, the copy source
1069 // address and the copy destination address.
1070 //
1071 // Because we will expand BPFISD::MEMCPY into load/store pairs, we will need
1072 // a third scratch register to serve as the destination register of load and
1073 // source register of store.
1074 //
1075 // The scratch register here is with the Define | Dead | EarlyClobber flags.
1076 // The EarlyClobber flag has the semantic property that the operand it is
1077 // attached to is clobbered before the rest of the inputs are read. Hence it
1078 // must be unique among the operands to the instruction. The Define flag is
1079 // needed to coerce the machine verifier that an Undef value isn't a problem
1080 // as we anyway is loading memory into it. The Dead flag is needed as the
1081 // value in scratch isn't supposed to be used by any other instruction.
1082 ScratchReg = MRI.createVirtualRegister(&BPF::GPRRegClass);
1083 MIB.addReg(ScratchReg,
1085
1086 return BB;
1087}
1088
1089MachineBasicBlock *BPFTargetLowering::EmitInstrWithCustomInserterLDimm64(
1090 MachineInstr &MI, MachineBasicBlock *BB) const {
1091 MachineFunction *MF = BB->getParent();
1092 const BPFInstrInfo *TII = MF->getSubtarget<BPFSubtarget>().getInstrInfo();
1093 const TargetRegisterClass *RC = getRegClassFor(MVT::i64);
1094 MachineRegisterInfo &RegInfo = MF->getRegInfo();
1095 DebugLoc DL = MI.getDebugLoc();
1096
1097 // Build address taken map for Global Varaibles and BlockAddresses
1098 DenseMap<const BasicBlock *, MachineBasicBlock *> AddressTakenBBs;
1099 for (MachineBasicBlock &MBB : *MF) {
1100 if (const BasicBlock *BB = MBB.getBasicBlock())
1101 if (BB->hasAddressTaken())
1102 AddressTakenBBs[BB] = &MBB;
1103 }
1104
1105 MachineOperand &MO = MI.getOperand(1);
1106 assert(MO.isBlockAddress() || MO.isGlobal());
1107
1108 Register ResultReg = MI.getOperand(0).getReg();
1109 Register TmpReg = RegInfo.createVirtualRegister(RC);
1110
1111 std::vector<MachineBasicBlock *> Targets;
1112 unsigned JTI;
1113
1114 if (MO.isBlockAddress()) {
1115 auto *BA = MO.getBlockAddress();
1116 MachineBasicBlock *TgtMBB = AddressTakenBBs[BA->getBasicBlock()];
1117 assert(TgtMBB);
1118
1119 Targets.push_back(TgtMBB);
1120 JTI = MF->getOrCreateJumpTableInfo(getJumpTableEncoding())
1121 ->createJumpTableIndex(Targets);
1122
1123 BuildMI(*BB, MI, DL, TII->get(BPF::LD_imm64), TmpReg)
1124 .addJumpTableIndex(JTI);
1125 BuildMI(*BB, MI, DL, TII->get(BPF::LDD), ResultReg)
1126 .addReg(TmpReg)
1127 .addImm(0);
1128 MI.eraseFromParent();
1129 return BB;
1130 }
1131
1132 // Helper: emit LD_imm64 with operand GlobalAddress or JumpTable
1133 auto emitLDImm64 = [&](const GlobalValue *GV = nullptr, unsigned JTI = -1) {
1134 auto MIB = BuildMI(*BB, MI, DL, TII->get(BPF::LD_imm64), ResultReg);
1135 if (GV)
1136 MIB.addGlobalAddress(GV);
1137 else
1138 MIB.addJumpTableIndex(JTI);
1139 MI.eraseFromParent();
1140 return BB;
1141 };
1142
1143 // Must be a global at this point
1144 const GlobalValue *GVal = MO.getGlobal();
1145 const auto *GV = dyn_cast<GlobalVariable>(GVal);
1146
1147 if (!GV || GV->getLinkage() != GlobalValue::PrivateLinkage ||
1148 !GV->isConstant() || !GV->hasInitializer())
1149 return emitLDImm64(GVal);
1150
1151 const auto *CA = dyn_cast<ConstantArray>(GV->getInitializer());
1152 if (!CA)
1153 return emitLDImm64(GVal);
1154
1155 for (const Use &Op : CA->operands()) {
1156 if (!isa<BlockAddress>(Op))
1157 return emitLDImm64(GVal);
1158 auto *BA = cast<BlockAddress>(Op);
1159 MachineBasicBlock *TgtMBB = AddressTakenBBs[BA->getBasicBlock()];
1160 assert(TgtMBB);
1161 Targets.push_back(TgtMBB);
1162 }
1163
1164 JTI = MF->getOrCreateJumpTableInfo(getJumpTableEncoding())
1165 ->createJumpTableIndex(Targets);
1166 return emitLDImm64(nullptr, JTI);
1167}
1168
1171 MachineBasicBlock *BB) const {
1173 DebugLoc DL = MI.getDebugLoc();
1174 unsigned Opc = MI.getOpcode();
1175 bool isSelectRROp = (Opc == BPF::Select ||
1176 Opc == BPF::Select_64_32 ||
1177 Opc == BPF::Select_32 ||
1178 Opc == BPF::Select_32_64);
1179
1180 bool isMemcpyOp = Opc == BPF::MEMCPY;
1181 bool isLDimm64Op = Opc == BPF::LDIMM64;
1182
1183#ifndef NDEBUG
1184 bool isSelectRIOp = (Opc == BPF::Select_Ri ||
1185 Opc == BPF::Select_Ri_64_32 ||
1186 Opc == BPF::Select_Ri_32 ||
1187 Opc == BPF::Select_Ri_32_64);
1188
1189 if (!(isSelectRROp || isSelectRIOp || isMemcpyOp || isLDimm64Op))
1190 report_fatal_error("unhandled instruction type: " + Twine(Opc));
1191#endif
1192
1193 if (isMemcpyOp)
1194 return EmitInstrWithCustomInserterMemcpy(MI, BB);
1195
1196 if (isLDimm64Op)
1197 return EmitInstrWithCustomInserterLDimm64(MI, BB);
1198
1199 bool is32BitCmp = (Opc == BPF::Select_32 ||
1200 Opc == BPF::Select_32_64 ||
1201 Opc == BPF::Select_Ri_32 ||
1202 Opc == BPF::Select_Ri_32_64);
1203
1204 // To "insert" a SELECT instruction, we actually have to insert the diamond
1205 // control-flow pattern. The incoming instruction knows the destination vreg
1206 // to set, the condition code register to branch on, the true/false values to
1207 // select between, and a branch opcode to use.
1208 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1210
1211 // ThisMBB:
1212 // ...
1213 // TrueVal = ...
1214 // jmp_XX r1, r2 goto Copy1MBB
1215 // fallthrough --> Copy0MBB
1216 MachineBasicBlock *ThisMBB = BB;
1217 MachineFunction *F = BB->getParent();
1218 MachineBasicBlock *Copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1219 MachineBasicBlock *Copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
1220
1221 F->insert(I, Copy0MBB);
1222 F->insert(I, Copy1MBB);
1223
1224 // Set the call frame size on entry to the new basic blocks.
1225 unsigned CallFrameSize = TII.getCallFrameSizeAt(MI);
1226 Copy0MBB->setCallFrameSize(CallFrameSize);
1227 Copy1MBB->setCallFrameSize(CallFrameSize);
1228
1229 // Update machine-CFG edges by transferring all successors of the current
1230 // block to the new block which will contain the Phi node for the select.
1231 Copy1MBB->splice(Copy1MBB->begin(), BB,
1232 std::next(MachineBasicBlock::iterator(MI)), BB->end());
1233 Copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
1234 // Next, add the true and fallthrough blocks as its successors.
1235 BB->addSuccessor(Copy0MBB);
1236 BB->addSuccessor(Copy1MBB);
1237
1238 // Insert Branch if Flag
1239 int CC = MI.getOperand(3).getImm();
1240 int NewCC;
1241 switch (CC) {
1242#define SET_NEWCC(X, Y) \
1243 case ISD::X: \
1244 if (is32BitCmp && HasJmp32) \
1245 NewCC = isSelectRROp ? BPF::Y##_rr_32 : BPF::Y##_ri_32; \
1246 else \
1247 NewCC = isSelectRROp ? BPF::Y##_rr : BPF::Y##_ri; \
1248 break
1249 SET_NEWCC(SETGT, JSGT);
1250 SET_NEWCC(SETUGT, JUGT);
1251 SET_NEWCC(SETGE, JSGE);
1252 SET_NEWCC(SETUGE, JUGE);
1253 SET_NEWCC(SETEQ, JEQ);
1254 SET_NEWCC(SETNE, JNE);
1255 SET_NEWCC(SETLT, JSLT);
1256 SET_NEWCC(SETULT, JULT);
1257 SET_NEWCC(SETLE, JSLE);
1258 SET_NEWCC(SETULE, JULE);
1259 default:
1260 report_fatal_error("unimplemented select CondCode " + Twine(CC));
1261 }
1262
1263 Register LHS = MI.getOperand(1).getReg();
1264 bool isSignedCmp = (CC == ISD::SETGT ||
1265 CC == ISD::SETGE ||
1266 CC == ISD::SETLT ||
1267 CC == ISD::SETLE);
1268
1269 // eBPF at the moment only has 64-bit comparison. Any 32-bit comparison need
1270 // to be promoted, however if the 32-bit comparison operands are destination
1271 // registers then they are implicitly zero-extended already, there is no
1272 // need of explicit zero-extend sequence for them.
1273 //
1274 // We simply do extension for all situations in this method, but we will
1275 // try to remove those unnecessary in BPFMIPeephole pass.
1276 if (is32BitCmp && !HasJmp32)
1277 LHS = EmitSubregExt(MI, BB, LHS, isSignedCmp);
1278
1279 if (isSelectRROp) {
1280 Register RHS = MI.getOperand(2).getReg();
1281
1282 if (is32BitCmp && !HasJmp32)
1283 RHS = EmitSubregExt(MI, BB, RHS, isSignedCmp);
1284
1285 BuildMI(BB, DL, TII.get(NewCC)).addReg(LHS).addReg(RHS).addMBB(Copy1MBB);
1286 } else {
1287 int64_t imm32 = MI.getOperand(2).getImm();
1288 // Check before we build J*_ri instruction.
1289 if (!isInt<32>(imm32))
1290 report_fatal_error("immediate overflows 32 bits: " + Twine(imm32));
1291 BuildMI(BB, DL, TII.get(NewCC))
1292 .addReg(LHS).addImm(imm32).addMBB(Copy1MBB);
1293 }
1294
1295 // Copy0MBB:
1296 // %FalseValue = ...
1297 // # fallthrough to Copy1MBB
1298 BB = Copy0MBB;
1299
1300 // Update machine-CFG edges
1301 BB->addSuccessor(Copy1MBB);
1302
1303 // Copy1MBB:
1304 // %Result = phi [ %FalseValue, Copy0MBB ], [ %TrueValue, ThisMBB ]
1305 // ...
1306 BB = Copy1MBB;
1307 BuildMI(*BB, BB->begin(), DL, TII.get(BPF::PHI), MI.getOperand(0).getReg())
1308 .addReg(MI.getOperand(5).getReg())
1309 .addMBB(Copy0MBB)
1310 .addReg(MI.getOperand(4).getReg())
1311 .addMBB(ThisMBB);
1312
1313 MI.eraseFromParent(); // The pseudo instruction is gone now.
1314 return BB;
1315}
1316
1318 EVT VT) const {
1319 return getHasAlu32() ? MVT::i32 : MVT::i64;
1320}
1321
1323 EVT VT) const {
1324 return (getHasAlu32() && VT == MVT::i32) ? MVT::i32 : MVT::i64;
1325}
1326
1327bool BPFTargetLowering::isLegalAddressingMode(const DataLayout &DL,
1328 const AddrMode &AM, Type *Ty,
1329 unsigned AS,
1330 Instruction *I) const {
1331 // No global is ever allowed as a base.
1332 if (AM.BaseGV)
1333 return false;
1334
1335 switch (AM.Scale) {
1336 case 0: // "r+i" or just "i", depending on HasBaseReg.
1337 break;
1338 case 1:
1339 if (!AM.HasBaseReg) // allow "r+i".
1340 break;
1341 return false; // disallow "r+r" or "r+r+i".
1342 default:
1343 return false;
1344 }
1345
1346 return true;
1347}
1348
1349bool BPFTargetLowering::CanLowerReturn(
1350 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
1352 const Type *RetTy) const {
1354 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
1355 return CCInfo.CheckReturn(Outs, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
1356}
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static uint32_t * regMaskFromTemplate(const TargetRegisterInfo *TRI, MachineFunction &MF, const uint32_t *BaseRegMask)
static Function * createBPFUnreachable(Module *M)
static cl::opt< bool > BPFAllowsLibcalls("bpf-allows-libcalls", cl::Hidden, cl::init(false), cl::desc("Allow libcalls instead of rejecting unsupported built-in " "functions"))
static SDValue getTargetNode(ConstantPoolSDNode *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned Flags)
static cl::opt< bool > BPFExpandMemcpyInOrder("bpf-expand-memcpy-in-order", cl::Hidden, cl::init(false), cl::desc("Expand memcpy into load/store pairs in order"))
static SDValue convertLocValType(SelectionDAG &DAG, const SDLoc &DL, const CCValAssign &VA, EVT RegVT, SDValue ArgValue)
static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg, SDValue Val={})
static cl::opt< unsigned > BPFMinimumJumpTableEntries("bpf-min-jump-table-entries", cl::init(13), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on BPF"))
static void resetRegMaskBit(const TargetRegisterInfo *TRI, uint32_t *RegMask, MCRegister Reg)
static void NegateCC(SDValue &LHS, SDValue &RHS, ISD::CondCode &CC)
#define SET_NEWCC(X, Y)
#define BPF_TRAP
Definition BPF.h:29
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool isSigned(unsigned Opcode)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
RISCVCC::CondCode CC
MachineRegisterInfo & MRI
const char * Msg
Value * RHS
Value * LHS
an instruction that atomically reads a memory location, combines it with another value,...
@ Add
*p = old + v
@ Sub
*p = old - v
@ And
*p = old & v
@ Xor
*p = old ^ v
BinOp getOperation() const
unsigned getCommonMaxStoresPerMemFunc() const
bool hasHmul() const
bool hasLoadAcqStoreRel() const
bool hasSdivSmod() const
bool getAllowsMisalignedMemAccess() const
bool getHasJmpExt() const
const BPFSelectionDAGInfo * getSelectionDAGInfo() const override
bool hasLdsx() const
bool hasGotox() const
bool hasMovsx() const
bool getHasJmp32() const
const BPFRegisterInfo * getRegisterInfo() const override
bool getHasAlu32() const
BPFTargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned, Align, MachineMemOperand::Flags, unsigned *) const override
Determine if the target supports unaligned memory accesses.
AtomicExpansionKind shouldExpandAtomicStoreInIR(StoreInst *SI) const override
Returns how the given (atomic) store should be expanded by the IR-level AtomicExpand pass into.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
Return the ValueType of the result of SETCC operations.
BPFTargetLowering(const TargetMachine &TM, const BPFSubtarget &STI)
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override
Return the type to use for a scalar shift opcode, given the shifted amount type.
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
BasicBlock * getBasicBlock() const
Definition Constants.h:1125
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
LLVM_ABI DISubroutineType * createSubroutineType(DITypeArray ParameterTypes, DINode::DIFlags Flags=DINode::FlagZero, unsigned CC=0)
Create subroutine type.
LLVM_ABI DISubprogram * createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, DINode::DIFlags Flags=DINode::FlagZero, DISubprogram::DISPFlags SPFlags=DISubprogram::SPFlagZero, DITemplateParameterArray TParams=nullptr, DISubprogram *Decl=nullptr, DITypeArray ThrownTypes=nullptr, DINodeArray Annotations=nullptr, StringRef TargetFuncName="", bool UseKeyInstructions=false)
Create a new descriptor for the specified subprogram.
LLVM_ABI DITypeArray getOrCreateTypeArray(ArrayRef< Metadata * > Elements)
Get a DITypeArray, create one if required.
Subprogram description. Uses SubclassData1.
Type array for a subprogram.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Definition DataLayout.h:791
A debug info location.
Definition DebugLoc.h:126
Diagnostic information for unsupported feature in backend.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void setSubprogram(DISubprogram *SP)
Set the attached subprogram.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:169
void setCallingConv(CallingConv::ID CC)
Definition Function.h:277
LLVM_ABI void setSection(StringRef S)
Change the section for this global.
Definition Globals.cpp:348
LinkageTypes getLinkage() const
Module * getParent()
Get the module that this global value is contained inside of...
void setDSOLocal(bool Local)
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ ExternalWeakLinkage
ExternalWeak linkage description.
Definition GlobalValue.h:62
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Machine Value Type.
SimpleValueType SimpleTy
static auto integer_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
bool hasAddressTaken() const
Test whether this block is used as something other than the target of a terminator,...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
uint32_t * allocateRegMask()
Allocate and initialize a register mask with NumRegister bits.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addJumpTableIndex(unsigned Idx, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
void RemoveJumpTable(unsigned Idx)
RemoveJumpTable - Mark the specific index as being dead.
LLVM_ABI unsigned createJumpTableIndex(const std::vector< MachineBasicBlock * > &DestBBs)
createJumpTableIndex - Create a new jump table.
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.
const std::vector< MachineJumpTableEntry > & getJumpTables() const
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
const GlobalValue * getGlobal() const
const BlockAddress * getBlockAddress() const
static unsigned getRegMaskSize(unsigned NumRegs)
Returns number of elements needed for a regmask array.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
bool isBlockAddress() const
isBlockAddress - Tests if this is a MO_BlockAddress operand.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
const SDValue & getOperand(unsigned Num) const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI 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),...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getJumpTable(int JTI, EVT VT, bool isTarget=false, unsigned TargetFlags=0)
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
TargetInstrInfo - Interface to description of machine instruction set.
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...
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual 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...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
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...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
void expandShiftParts(SDNode *N, SDValue &Lo, SDValue &Hi, SelectionDAG &DAG) const
Expand shift-by-parts.
Primary interface to the complete machine description for the target machine.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
self_iterator getIterator()
Definition ilist_node.h:123
A raw_ostream that writes to an std::string.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition CallingConv.h:66
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:845
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:277
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:805
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:879
@ GlobalAddress
Definition ISDOpcodes.h:90
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
@ MEMBARRIER
MEMBARRIER - Compiler barrier only; generate a no-op.
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:282
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:814
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:870
@ BR_CC
BR_CC - Conditional branch.
@ BRIND
BRIND - Indirect branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:822
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:714
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:787
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:876
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:837
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:914
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
@ TRAP
TRAP - Trapping instruction.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:813
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:882
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:859
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:64
LLVM_ABI CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y).
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:63
@ System
Synchronized with respect to all concurrently executing threads.
Definition LLVMContext.h:66
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
@ Dead
Unused definition.
@ EarlyClobber
Register definition happens before uses.
@ Define
Register definition.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Load
The value being inserted comes from a load (InsertElement only).
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
Definition STLExtras.h:1167
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
Definition MathExtras.h:380
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
@ Fast
Assign the register banks as fast as possible (default).
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:160
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:411
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:354
LLVM_ABI void print(raw_ostream &OS) const
Implement operator<<.
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:175
LLVM IR metadata carried by a MachineMemOperand.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getJumpTable(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a jump table entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs