LLVM 23.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
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 }
117
119
120 for (auto VT : { MVT::i32, MVT::i64 }) {
121 if (VT == MVT::i32 && !STI.getHasAlu32())
122 continue;
123
126 if (!STI.hasSdivSmod()) {
129 }
144
148 }
149
150 if (STI.getHasAlu32()) {
153 STI.getHasJmp32() ? Custom : Promote);
154 }
155
157 if (!STI.hasMovsx()) {
161 }
162
163 // Extended load operations for i1 types must be promoted
164 for (MVT VT : MVT::integer_valuetypes()) {
168
169 if (!STI.hasLdsx()) {
171 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i16, Expand);
172 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i32, Expand);
173 }
174 }
175
179
180 // Function alignments
183
185 // LLVM generic code will try to expand memcpy into load/store pairs at this
186 // stage which is before quite a few IR optimization passes, therefore the
187 // loads and stores could potentially be moved apart from each other which
188 // will cause trouble to memcpy pattern matcher inside kernel eBPF JIT
189 // compilers.
190 //
191 // When -bpf-expand-memcpy-in-order specified, we want to defer the expand
192 // of memcpy to later stage in IR optimization pipeline so those load/store
193 // pairs won't be touched and could be kept in order. Hence, we set
194 // MaxStoresPerMem* to zero to disable the generic getMemcpyLoadsAndStores
195 // code path, and ask LLVM to use target expander EmitTargetCodeForMemcpy.
200 } else {
201 // inline memcpy() for kernel to see explicit copy
202 unsigned CommonMaxStores =
204
209 }
210
211 // CPU/Feature control
212 HasAlu32 = STI.getHasAlu32();
213 HasJmp32 = STI.getHasJmp32();
214 HasJmpExt = STI.getHasJmpExt();
215 HasMovsx = STI.hasMovsx();
216
217 AllowsMisalignedMemAccess = STI.getAllowsMisalignedMemAccess();
218}
219
222 unsigned *Fast) const {
223 // allows-misaligned-mem-access is disabled
224 if (!AllowsMisalignedMemAccess)
225 return false;
226
227 // only allow misalignment for simple value types
228 if (!VT.isSimple())
229 return false;
230
231 // always assume fast mode when misalignment is allowed
232 if (Fast)
233 *Fast = true;
234
235 return true;
236}
237
239 return false;
240}
241
242bool BPFTargetLowering::isTruncateFree(Type *Ty1, Type *Ty2) const {
243 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
244 return false;
245 unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
246 unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
247 return NumBits1 > NumBits2;
248}
249
250bool BPFTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
251 if (!VT1.isInteger() || !VT2.isInteger())
252 return false;
253 unsigned NumBits1 = VT1.getSizeInBits();
254 unsigned NumBits2 = VT2.getSizeInBits();
255 return NumBits1 > NumBits2;
256}
257
258bool BPFTargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
259 if (!getHasAlu32() || !Ty1->isIntegerTy() || !Ty2->isIntegerTy())
260 return false;
261 unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
262 unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
263 return NumBits1 == 32 && NumBits2 == 64;
264}
265
266bool BPFTargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
267 if (!getHasAlu32() || !VT1.isInteger() || !VT2.isInteger())
268 return false;
269 unsigned NumBits1 = VT1.getSizeInBits();
270 unsigned NumBits2 = VT2.getSizeInBits();
271 return NumBits1 == 32 && NumBits2 == 64;
272}
273
274bool BPFTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
275 EVT VT1 = Val.getValueType();
276 if (Val.getOpcode() == ISD::LOAD && VT1.isSimple() && VT2.isSimple()) {
277 MVT MT1 = VT1.getSimpleVT().SimpleTy;
278 MVT MT2 = VT2.getSimpleVT().SimpleTy;
279 if ((MT1 == MVT::i8 || MT1 == MVT::i16 || MT1 == MVT::i32) &&
280 (MT2 == MVT::i32 || MT2 == MVT::i64))
281 return true;
282 }
283 return TargetLoweringBase::isZExtFree(Val, VT2);
284}
285
289
292 if (Constraint.size() == 1) {
293 switch (Constraint[0]) {
294 default:
295 break;
296 case 'w':
297 return C_RegisterClass;
298 }
299 }
300
301 return TargetLowering::getConstraintType(Constraint);
302}
303
304std::pair<unsigned, const TargetRegisterClass *>
306 StringRef Constraint,
307 MVT VT) const {
308 if (Constraint.size() == 1) {
309 // GCC Constraint Letters
310 switch (Constraint[0]) {
311 case 'r': // GENERAL_REGS
312 return std::make_pair(0U, &BPF::GPRRegClass);
313 case 'w':
314 if (HasAlu32)
315 return std::make_pair(0U, &BPF::GPR32RegClass);
316 break;
317 default:
318 break;
319 }
320 }
321
323}
324
325void BPFTargetLowering::ReplaceNodeResults(
327 const char *Msg;
328 uint32_t Opcode = N->getOpcode();
329 switch (Opcode) {
330 default:
331 report_fatal_error("unhandled custom legalization: " + Twine(Opcode));
336 case ISD::ATOMIC_SWAP:
338 if (HasAlu32 || Opcode == ISD::ATOMIC_LOAD_ADD)
339 Msg = "unsupported atomic operation, please use 32/64 bit version";
340 else
341 Msg = "unsupported atomic operation, please use 64 bit version";
342 break;
343 case ISD::ATOMIC_LOAD:
345 return;
346 }
347
348 SDLoc DL(N);
349 // We'll still produce a fatal error downstream, but this diagnostic is more
350 // user-friendly.
351 fail(DL, DAG, Msg);
352}
353
355 switch (Op.getOpcode()) {
356 default:
357 report_fatal_error("unimplemented opcode: " + Twine(Op.getOpcode()));
358 case ISD::BR_CC:
359 return LowerBR_CC(Op, DAG);
360 case ISD::JumpTable:
361 return LowerJumpTable(Op, DAG);
363 return LowerGlobalAddress(Op, DAG);
365 return LowerConstantPool(Op, DAG);
367 return LowerBlockAddress(Op, DAG);
368 case ISD::SELECT_CC:
369 return LowerSELECT_CC(Op, DAG);
370 case ISD::SDIV:
371 case ISD::SREM:
372 return LowerSDIVSREM(Op, DAG);
373 case ISD::SHL_PARTS:
374 case ISD::SRL_PARTS:
375 case ISD::SRA_PARTS:
376 return LowerShiftParts(Op, DAG);
378 return LowerDYNAMIC_STACKALLOC(Op, DAG);
379 case ISD::ATOMIC_LOAD:
381 return LowerATOMIC_LOAD_STORE(Op, DAG);
383 return LowerATOMIC_FENCE(Op, DAG);
384 case ISD::TRAP:
385 return LowerTRAP(Op, DAG);
386 }
387}
388
389// Calling Convention Implementation
390#define GET_CALLING_CONV_IMPL
391#include "BPFGenCallingConv.inc"
392
393// Apply AssertSext/AssertZext and truncate based on VA's LocInfo.
395 const CCValAssign &VA, EVT RegVT,
396 SDValue ArgValue) {
397 if (VA.getLocInfo() == CCValAssign::SExt)
398 ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
399 DAG.getValueType(VA.getValVT()));
400 else if (VA.getLocInfo() == CCValAssign::ZExt)
401 ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
402 DAG.getValueType(VA.getValVT()));
403 if (VA.getLocInfo() != CCValAssign::Full)
404 ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
405 return ArgValue;
406}
407
408SDValue BPFTargetLowering::LowerFormalArguments(
409 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
410 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
411 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
412 switch (CallConv) {
413 default:
414 report_fatal_error("unimplemented calling convention: " + Twine(CallConv));
415 case CallingConv::C:
417 break;
418 }
419
420 MachineFunction &MF = DAG.getMachineFunction();
421 MachineRegisterInfo &RegInfo = MF.getRegInfo();
422
423 // Assign locations to all of the incoming arguments.
425 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
426 CCInfo.AnalyzeFormalArguments(Ins, getHasAlu32() ? CC_BPF32 : CC_BPF64);
427
428 for (size_t I = 0; I < ArgLocs.size(); ++I) {
429 auto &VA = ArgLocs[I];
430 EVT RegVT = VA.getLocVT();
431
432 if (VA.isRegLoc()) {
433 // Arguments passed in registers
434 MVT::SimpleValueType SimpleTy = RegVT.getSimpleVT().SimpleTy;
435 switch (SimpleTy) {
436 default: {
437 std::string Str;
438 {
439 raw_string_ostream OS(Str);
440 RegVT.print(OS);
441 }
442 report_fatal_error("unhandled argument type: " + Twine(Str));
443 }
444 case MVT::i32:
445 case MVT::i64:
446 Register VReg = RegInfo.createVirtualRegister(
447 SimpleTy == MVT::i64 ? &BPF::GPRRegClass : &BPF::GPR32RegClass);
448 RegInfo.addLiveIn(VA.getLocReg(), VReg);
449 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
450 InVals.push_back(convertLocValType(DAG, DL, VA, RegVT, ArgValue));
451 break;
452 }
453 continue;
454 }
455
456 if (VA.isMemLoc()) {
457 // For example, two stack arguments,
458 // arg1: Off = 8
459 // arg2: off = 16
460 int Off = VA.getLocMemOffset() + 8;
461 if (Off > INT16_MAX) {
462 fail(DL, DAG, "extra parameter stack depth exceeded limit");
463 break;
464 }
465
466 // Physical extra argument slot is always 64-bit.
467 SDValue StackVal = DAG.getNode(BPFISD::LOAD_STACK_ARG, DL,
468 DAG.getVTList(MVT::i64, MVT::Other), Chain,
469 DAG.getConstant(Off, DL, MVT::i64));
470 SDValue ArgValue = StackVal.getValue(0);
471 Chain = StackVal.getValue(1);
472 InVals.push_back(convertLocValType(DAG, DL, VA, MVT::i64, ArgValue));
473 continue;
474 }
475 }
476
477 if (IsVarArg)
478 fail(DL, DAG, "variadic functions are not supported");
479 return Chain;
480}
481
482static void resetRegMaskBit(const TargetRegisterInfo *TRI, uint32_t *RegMask,
483 MCRegister Reg) {
484 for (MCPhysReg SubReg : TRI->subregs_inclusive(Reg))
485 RegMask[SubReg / 32] &= ~(1u << (SubReg % 32));
486}
487
489 MachineFunction &MF,
490 const uint32_t *BaseRegMask) {
491 uint32_t *RegMask = MF.allocateRegMask();
492 unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs());
493 memcpy(RegMask, BaseRegMask, sizeof(RegMask[0]) * RegMaskSize);
494 return RegMask;
495}
496
497SDValue BPFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
498 SmallVectorImpl<SDValue> &InVals) const {
499 SelectionDAG &DAG = CLI.DAG;
500 auto &Outs = CLI.Outs;
501 auto &OutVals = CLI.OutVals;
502 auto &Ins = CLI.Ins;
503 SDValue Chain = CLI.Chain;
504 SDValue Callee = CLI.Callee;
505 bool &IsTailCall = CLI.IsTailCall;
506 CallingConv::ID CallConv = CLI.CallConv;
507 bool IsVarArg = CLI.IsVarArg;
508 MachineFunction &MF = DAG.getMachineFunction();
509
510 // BPF target does not support tail call optimization.
511 IsTailCall = false;
512
513 switch (CallConv) {
514 default:
515 report_fatal_error("unsupported calling convention: " + Twine(CallConv));
517 case CallingConv::C:
518 break;
519 }
520
521 // Analyze operands of the call, assigning locations to each operand.
523 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
524
525 CCInfo.AnalyzeCallOperands(Outs, getHasAlu32() ? CC_BPF32 : CC_BPF64);
526
527 unsigned NumBytes = CCInfo.getStackSize();
528
529 for (auto &Arg : Outs) {
530 ISD::ArgFlagsTy Flags = Arg.Flags;
531 if (!Flags.isByVal())
532 continue;
533 fail(CLI.DL, DAG, "pass by value not supported", Callee);
534 break;
535 }
536
537 auto PtrVT = getPointerTy(MF.getDataLayout());
538 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
539
541
542 // Walk arg assignments
543 for (size_t i = 0; i < OutVals.size(); ++i) {
544 CCValAssign &VA = ArgLocs[i];
545 SDValue &Arg = OutVals[i];
546
547 // Promote the value if needed.
548 switch (VA.getLocInfo()) {
549 default:
550 report_fatal_error("unhandled location info: " + Twine(VA.getLocInfo()));
552 break;
554 Arg = DAG.getNode(ISD::SIGN_EXTEND, CLI.DL, VA.getLocVT(), Arg);
555 break;
557 Arg = DAG.getNode(ISD::ZERO_EXTEND, CLI.DL, VA.getLocVT(), Arg);
558 break;
560 Arg = DAG.getNode(ISD::ANY_EXTEND, CLI.DL, VA.getLocVT(), Arg);
561 break;
562 }
563
564 // Push arguments into RegsToPass vector
565 if (VA.isRegLoc()) {
566 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
567 continue;
568 }
569
570 if (VA.isMemLoc()) {
571 int Off = -8 - VA.getLocMemOffset();
572 if (Off < INT16_MIN) {
573 fail(CLI.DL, DAG, "extra parameter stack depth exceeded limit");
574 break;
575 }
576
577 // STORE_STACK_ARG requires i64 operands. With ALU32 mode, the CC
578 // promotion may only extend to i32, so extend to i64 if needed.
579 if (Arg.getValueType() != MVT::i64)
580 Arg = DAG.getNode(ISD::ANY_EXTEND, CLI.DL, MVT::i64, Arg);
581
582 SDValue OffVal = DAG.getConstant(Off, CLI.DL, MVT::i64);
583 Chain = DAG.getNode(BPFISD::STORE_STACK_ARG, CLI.DL, MVT::Other, Chain,
584 OffVal, Arg);
585 continue;
586 }
587
588 report_fatal_error("unhandled argument location");
589 }
590
591 SDValue InGlue;
592
593 // Build a sequence of copy-to-reg nodes chained together with token chain and
594 // flag operands which copy the outgoing args into registers. The InGlue in
595 // necessary since all emitted instructions must be stuck together.
596 for (auto &Reg : RegsToPass) {
597 Chain = DAG.getCopyToReg(Chain, CLI.DL, Reg.first, Reg.second, InGlue);
598 InGlue = Chain.getValue(1);
599 }
600
601 // If the callee is a GlobalAddress node (quite common, every direct call is)
602 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
603 // Likewise ExternalSymbol -> TargetExternalSymbol.
604 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
605 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), CLI.DL, PtrVT,
606 G->getOffset(), 0);
607 } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
608 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
609 StringRef Sym = E->getSymbol();
610 if (!BPFAllowsLibcalls && Sym != BPF_TRAP && Sym != "__multi3" &&
611 Sym != "__divti3" && Sym != "__modti3" && Sym != "__udivti3" &&
612 Sym != "__umodti3" && Sym != "memcpy" && Sym != "memset" &&
613 Sym != "memmove")
614 fail(
615 CLI.DL, DAG,
616 Twine("A call to built-in function '" + Sym + "' is not supported."));
617 }
618
619 // Returns a chain & a flag for retval copy to use.
620 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
622 Ops.push_back(Chain);
623 Ops.push_back(Callee);
624
625 // Add argument registers to the end of the list so that they are
626 // known live into the call.
627 for (auto &Reg : RegsToPass)
628 Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
629
630 bool HasFastCall =
631 (CLI.CB && isa<CallInst>(CLI.CB) && CLI.CB->hasFnAttr("bpf_fastcall"));
632 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
633 if (HasFastCall) {
634 uint32_t *RegMask = regMaskFromTemplate(
635 TRI, MF, TRI->getCallPreservedMask(MF, CallingConv::PreserveAll));
636 for (auto const &RegPair : RegsToPass)
637 resetRegMaskBit(TRI, RegMask, RegPair.first);
638 if (!CLI.CB->getType()->isVoidTy())
639 resetRegMaskBit(TRI, RegMask, BPF::R0);
640 Ops.push_back(DAG.getRegisterMask(RegMask));
641 } else {
642 Ops.push_back(
643 DAG.getRegisterMask(TRI->getCallPreservedMask(MF, CLI.CallConv)));
644 }
645
646 if (InGlue.getNode())
647 Ops.push_back(InGlue);
648
649 Chain = DAG.getNode(BPFISD::CALL, CLI.DL, NodeTys, Ops);
650 InGlue = Chain.getValue(1);
651
652 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
653
654 // Create the CALLSEQ_END node.
655 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, CLI.DL);
656 InGlue = Chain.getValue(1);
657
658 // Handle result values, copying them out of physregs into vregs that we
659 // return.
660 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, CLI.DL, DAG,
661 InVals);
662}
663
665BPFTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
666 bool IsVarArg,
668 const SmallVectorImpl<SDValue> &OutVals,
669 const SDLoc &DL, SelectionDAG &DAG) const {
670 unsigned Opc = BPFISD::RET_GLUE;
671
672 // CCValAssign - represent the assignment of the return value to a location
674 MachineFunction &MF = DAG.getMachineFunction();
675
676 // CCState - Info about the registers and stack slot.
677 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
678
679 // Analize return values.
680 CCInfo.AnalyzeReturn(Outs, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
681
682 SDValue Glue;
683 SmallVector<SDValue, 4> RetOps(1, Chain);
684
685 // Copy the result values into the output registers.
686 for (size_t i = 0; i != RVLocs.size(); ++i) {
687 CCValAssign &VA = RVLocs[i];
688 if (!VA.isRegLoc())
689 report_fatal_error("stack return values are not supported");
690
691 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Glue);
692
693 // Guarantee that all emitted copies are stuck together,
694 // avoiding something bad.
695 Glue = Chain.getValue(1);
696 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
697 }
698
699 RetOps[0] = Chain; // Update chain.
700
701 // Add the glue if we have it.
702 if (Glue.getNode())
703 RetOps.push_back(Glue);
704
705 return DAG.getNode(Opc, DL, MVT::Other, RetOps);
706}
707
708SDValue BPFTargetLowering::LowerCallResult(
709 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
710 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
711 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
712
713 MachineFunction &MF = DAG.getMachineFunction();
714 // Assign locations to each value returned by this call.
716 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
717
718 CCInfo.AnalyzeCallResult(Ins, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
719
720 // Copy all of the result registers out of their specified physreg.
721 for (auto &Val : RVLocs) {
722 Chain = DAG.getCopyFromReg(Chain, DL, Val.getLocReg(),
723 Val.getValVT(), InGlue).getValue(1);
724 InGlue = Chain.getValue(2);
725 InVals.push_back(Chain.getValue(0));
726 }
727
728 return Chain;
729}
730
732 switch (CC) {
733 default:
734 break;
735 case ISD::SETULT:
736 case ISD::SETULE:
737 case ISD::SETLT:
738 case ISD::SETLE:
740 std::swap(LHS, RHS);
741 break;
742 }
743}
744
745SDValue BPFTargetLowering::LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const {
746 SDLoc DL(Op);
747 fail(DL, DAG,
748 "unsupported signed division, please convert to unsigned div/mod.");
749 return DAG.getUNDEF(Op->getValueType(0));
750}
751
752SDValue BPFTargetLowering::LowerShiftParts(SDValue Op,
753 SelectionDAG &DAG) const {
754 SDValue Lo, Hi;
755 expandShiftParts(Op.getNode(), Lo, Hi, DAG);
756 return DAG.getMergeValues({Lo, Hi}, SDLoc(Op));
757}
758
759SDValue BPFTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
760 SelectionDAG &DAG) const {
761 SDLoc DL(Op);
762 fail(DL, DAG, "unsupported dynamic stack allocation");
763 auto Ops = {DAG.getConstant(0, SDLoc(), Op.getValueType()), Op.getOperand(0)};
764 return DAG.getMergeValues(Ops, SDLoc());
765}
766
767SDValue BPFTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
768 SDValue Chain = Op.getOperand(0);
769 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
770 SDValue LHS = Op.getOperand(2);
771 SDValue RHS = Op.getOperand(3);
772 SDValue Dest = Op.getOperand(4);
773 SDLoc DL(Op);
774
775 if (!getHasJmpExt())
776 NegateCC(LHS, RHS, CC);
777
778 return DAG.getNode(BPFISD::BR_CC, DL, Op.getValueType(), Chain, LHS, RHS,
779 DAG.getConstant(CC, DL, LHS.getValueType()), Dest);
780}
781
782SDValue BPFTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
783 SDValue LHS = Op.getOperand(0);
784 SDValue RHS = Op.getOperand(1);
785 SDValue TrueV = Op.getOperand(2);
786 SDValue FalseV = Op.getOperand(3);
787 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
788 SDLoc DL(Op);
789
790 if (!getHasJmpExt())
791 NegateCC(LHS, RHS, CC);
792
793 SDValue TargetCC = DAG.getConstant(CC, DL, LHS.getValueType());
794 SDValue Ops[] = {LHS, RHS, TargetCC, TrueV, FalseV};
795
796 return DAG.getNode(BPFISD::SELECT_CC, DL, Op.getValueType(), Ops);
797}
798
799SDValue BPFTargetLowering::LowerATOMIC_LOAD_STORE(SDValue Op,
800 SelectionDAG &DAG) const {
801 SDNode *N = Op.getNode();
802 SDLoc DL(N);
803
804 if (cast<AtomicSDNode>(N)->getMergedOrdering() ==
806 fail(DL, DAG,
807 "sequentially consistent (seq_cst) "
808 "atomic load/store is not supported");
809
810 return Op;
811}
812
813SDValue BPFTargetLowering::LowerATOMIC_FENCE(SDValue Op,
814 SelectionDAG &DAG) const {
815 SDLoc DL(Op);
816 SyncScope::ID FenceSSID =
817 static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
818
819 if (FenceSSID == SyncScope::SingleThread)
820 // MEMBARRIER is a compiler barrier; it codegens to a no-op.
821 return DAG.getNode(ISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0));
822
823 report_fatal_error("Runtime fence is not supported at the moment");
824}
825
827 if (auto *Fn = M->getFunction(BPF_TRAP))
828 return Fn;
829
830 FunctionType *FT = FunctionType::get(Type::getVoidTy(M->getContext()), false);
831 Function *NewF =
833 NewF->setDSOLocal(true);
835 NewF->setSection(".ksyms");
836
837 if (M->debug_compile_units().empty())
838 return NewF;
839
840 DIBuilder DBuilder(*M);
841 DITypeArray ParamTypes =
842 DBuilder.getOrCreateTypeArray({nullptr /*void return*/});
843 DISubroutineType *FuncType = DBuilder.createSubroutineType(ParamTypes);
844 DICompileUnit *CU = *M->debug_compile_units_begin();
845 DISubprogram *SP =
846 DBuilder.createFunction(CU, BPF_TRAP, BPF_TRAP, nullptr, 0, FuncType, 0,
847 DINode::FlagZero, DISubprogram::SPFlagZero);
848 NewF->setSubprogram(SP);
849 return NewF;
850}
851
852SDValue BPFTargetLowering::LowerTRAP(SDValue Op, SelectionDAG &DAG) const {
853 MachineFunction &MF = DAG.getMachineFunction();
854 TargetLowering::CallLoweringInfo CLI(DAG);
856 SDNode *N = Op.getNode();
857 SDLoc DL(N);
858
860 auto PtrVT = getPointerTy(MF.getDataLayout());
861 CLI.Callee = DAG.getTargetGlobalAddress(Fn, DL, PtrVT);
862 CLI.Chain = N->getOperand(0);
863 CLI.IsTailCall = false;
865 CLI.IsVarArg = false;
866 CLI.DL = std::move(DL);
867 CLI.NoMerge = false;
868 CLI.DoesNotReturn = true;
869 return LowerCall(CLI, InVals);
870}
871
872SDValue BPFTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
873 JumpTableSDNode *N = cast<JumpTableSDNode>(Op);
874 return getAddr(N, DAG);
875}
876
878 SelectionDAG &DAG, unsigned Flags) {
879 return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(),
880 N->getOffset(), Flags);
881}
882
884 SelectionDAG &DAG, unsigned Flags) {
885 return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);
886}
887
888template <class NodeTy>
889SDValue BPFTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
890 unsigned Flags) const {
891 SDLoc DL(N);
892
893 SDValue GA = getTargetNode(N, DL, MVT::i64, DAG, Flags);
894
895 return DAG.getNode(BPFISD::Wrapper, DL, MVT::i64, GA);
896}
897
898SDValue BPFTargetLowering::LowerGlobalAddress(SDValue Op,
899 SelectionDAG &DAG) const {
900 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
901 if (N->getOffset() != 0)
902 report_fatal_error("invalid offset for global address: " +
903 Twine(N->getOffset()));
904
905 const GlobalValue *GVal = N->getGlobal();
906 SDLoc DL(Op);
907
908 // Wrap it in a TargetGlobalAddress
909 SDValue Addr = DAG.getTargetGlobalAddress(GVal, DL, MVT::i64);
910
911 // Emit pseudo instruction
912 return SDValue(DAG.getMachineNode(BPF::LDIMM64, DL, MVT::i64, Addr), 0);
913}
914
915SDValue BPFTargetLowering::LowerConstantPool(SDValue Op,
916 SelectionDAG &DAG) const {
917 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
918
919 return getAddr(N, DAG);
920}
921
922SDValue BPFTargetLowering::LowerBlockAddress(SDValue Op,
923 SelectionDAG &DAG) const {
924 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
925 SDLoc DL(Op);
926
927 // Wrap it in a TargetBlockAddress
928 SDValue Addr = DAG.getTargetBlockAddress(BA, MVT::i64);
929
930 // Emit pseudo instruction
931 return SDValue(DAG.getMachineNode(BPF::LDIMM64, DL, MVT::i64, Addr), 0);
932}
933
934unsigned
935BPFTargetLowering::EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB,
936 unsigned Reg, bool isSigned) const {
937 const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
938 const TargetRegisterClass *RC = getRegClassFor(MVT::i64);
939 int RShiftOp = isSigned ? BPF::SRA_ri : BPF::SRL_ri;
940 MachineFunction *F = BB->getParent();
941 DebugLoc DL = MI.getDebugLoc();
942
943 MachineRegisterInfo &RegInfo = F->getRegInfo();
944
945 if (!isSigned) {
946 Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
947 BuildMI(BB, DL, TII.get(BPF::MOV_32_64), PromotedReg0).addReg(Reg);
948 return PromotedReg0;
949 }
950 Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
951 Register PromotedReg1 = RegInfo.createVirtualRegister(RC);
952 Register PromotedReg2 = RegInfo.createVirtualRegister(RC);
953 if (HasMovsx) {
954 BuildMI(BB, DL, TII.get(BPF::MOVSX_rr_32), PromotedReg0).addReg(Reg);
955 } else {
956 BuildMI(BB, DL, TII.get(BPF::MOV_32_64), PromotedReg0).addReg(Reg);
957 BuildMI(BB, DL, TII.get(BPF::SLL_ri), PromotedReg1)
958 .addReg(PromotedReg0).addImm(32);
959 BuildMI(BB, DL, TII.get(RShiftOp), PromotedReg2)
960 .addReg(PromotedReg1).addImm(32);
961 }
962
963 return PromotedReg2;
964}
965
967BPFTargetLowering::EmitInstrWithCustomInserterMemcpy(MachineInstr &MI,
969 const {
970 MachineFunction *MF = MI.getParent()->getParent();
971 MachineRegisterInfo &MRI = MF->getRegInfo();
972 MachineInstrBuilder MIB(*MF, MI);
973 unsigned ScratchReg;
974
975 // This function does custom insertion during lowering BPFISD::MEMCPY which
976 // only has two register operands from memcpy semantics, the copy source
977 // address and the copy destination address.
978 //
979 // Because we will expand BPFISD::MEMCPY into load/store pairs, we will need
980 // a third scratch register to serve as the destination register of load and
981 // source register of store.
982 //
983 // The scratch register here is with the Define | Dead | EarlyClobber flags.
984 // The EarlyClobber flag has the semantic property that the operand it is
985 // attached to is clobbered before the rest of the inputs are read. Hence it
986 // must be unique among the operands to the instruction. The Define flag is
987 // needed to coerce the machine verifier that an Undef value isn't a problem
988 // as we anyway is loading memory into it. The Dead flag is needed as the
989 // value in scratch isn't supposed to be used by any other instruction.
990 ScratchReg = MRI.createVirtualRegister(&BPF::GPRRegClass);
991 MIB.addReg(ScratchReg,
993
994 return BB;
995}
996
997MachineBasicBlock *BPFTargetLowering::EmitInstrWithCustomInserterLDimm64(
998 MachineInstr &MI, MachineBasicBlock *BB) const {
999 MachineFunction *MF = BB->getParent();
1000 const BPFInstrInfo *TII = MF->getSubtarget<BPFSubtarget>().getInstrInfo();
1001 const TargetRegisterClass *RC = getRegClassFor(MVT::i64);
1002 MachineRegisterInfo &RegInfo = MF->getRegInfo();
1003 DebugLoc DL = MI.getDebugLoc();
1004
1005 // Build address taken map for Global Varaibles and BlockAddresses
1006 DenseMap<const BasicBlock *, MachineBasicBlock *> AddressTakenBBs;
1007 for (MachineBasicBlock &MBB : *MF) {
1008 if (const BasicBlock *BB = MBB.getBasicBlock())
1009 if (BB->hasAddressTaken())
1010 AddressTakenBBs[BB] = &MBB;
1011 }
1012
1013 MachineOperand &MO = MI.getOperand(1);
1014 assert(MO.isBlockAddress() || MO.isGlobal());
1015
1016 Register ResultReg = MI.getOperand(0).getReg();
1017 Register TmpReg = RegInfo.createVirtualRegister(RC);
1018
1019 std::vector<MachineBasicBlock *> Targets;
1020 unsigned JTI;
1021
1022 if (MO.isBlockAddress()) {
1023 auto *BA = MO.getBlockAddress();
1024 MachineBasicBlock *TgtMBB = AddressTakenBBs[BA->getBasicBlock()];
1025 assert(TgtMBB);
1026
1027 Targets.push_back(TgtMBB);
1028 JTI = MF->getOrCreateJumpTableInfo(getJumpTableEncoding())
1029 ->createJumpTableIndex(Targets);
1030
1031 BuildMI(*BB, MI, DL, TII->get(BPF::LD_imm64), TmpReg)
1032 .addJumpTableIndex(JTI);
1033 BuildMI(*BB, MI, DL, TII->get(BPF::LDD), ResultReg)
1034 .addReg(TmpReg)
1035 .addImm(0);
1036 MI.eraseFromParent();
1037 return BB;
1038 }
1039
1040 // Helper: emit LD_imm64 with operand GlobalAddress or JumpTable
1041 auto emitLDImm64 = [&](const GlobalValue *GV = nullptr, unsigned JTI = -1) {
1042 auto MIB = BuildMI(*BB, MI, DL, TII->get(BPF::LD_imm64), ResultReg);
1043 if (GV)
1044 MIB.addGlobalAddress(GV);
1045 else
1046 MIB.addJumpTableIndex(JTI);
1047 MI.eraseFromParent();
1048 return BB;
1049 };
1050
1051 // Must be a global at this point
1052 const GlobalValue *GVal = MO.getGlobal();
1053 const auto *GV = dyn_cast<GlobalVariable>(GVal);
1054
1055 if (!GV || GV->getLinkage() != GlobalValue::PrivateLinkage ||
1056 !GV->isConstant() || !GV->hasInitializer())
1057 return emitLDImm64(GVal);
1058
1059 const auto *CA = dyn_cast<ConstantArray>(GV->getInitializer());
1060 if (!CA)
1061 return emitLDImm64(GVal);
1062
1063 for (const Use &Op : CA->operands()) {
1064 if (!isa<BlockAddress>(Op))
1065 return emitLDImm64(GVal);
1066 auto *BA = cast<BlockAddress>(Op);
1067 MachineBasicBlock *TgtMBB = AddressTakenBBs[BA->getBasicBlock()];
1068 assert(TgtMBB);
1069 Targets.push_back(TgtMBB);
1070 }
1071
1072 JTI = MF->getOrCreateJumpTableInfo(getJumpTableEncoding())
1073 ->createJumpTableIndex(Targets);
1074 return emitLDImm64(nullptr, JTI);
1075}
1076
1079 MachineBasicBlock *BB) const {
1081 DebugLoc DL = MI.getDebugLoc();
1082 unsigned Opc = MI.getOpcode();
1083 bool isSelectRROp = (Opc == BPF::Select ||
1084 Opc == BPF::Select_64_32 ||
1085 Opc == BPF::Select_32 ||
1086 Opc == BPF::Select_32_64);
1087
1088 bool isMemcpyOp = Opc == BPF::MEMCPY;
1089 bool isLDimm64Op = Opc == BPF::LDIMM64;
1090
1091#ifndef NDEBUG
1092 bool isSelectRIOp = (Opc == BPF::Select_Ri ||
1093 Opc == BPF::Select_Ri_64_32 ||
1094 Opc == BPF::Select_Ri_32 ||
1095 Opc == BPF::Select_Ri_32_64);
1096
1097 if (!(isSelectRROp || isSelectRIOp || isMemcpyOp || isLDimm64Op))
1098 report_fatal_error("unhandled instruction type: " + Twine(Opc));
1099#endif
1100
1101 if (isMemcpyOp)
1102 return EmitInstrWithCustomInserterMemcpy(MI, BB);
1103
1104 if (isLDimm64Op)
1105 return EmitInstrWithCustomInserterLDimm64(MI, BB);
1106
1107 bool is32BitCmp = (Opc == BPF::Select_32 ||
1108 Opc == BPF::Select_32_64 ||
1109 Opc == BPF::Select_Ri_32 ||
1110 Opc == BPF::Select_Ri_32_64);
1111
1112 // To "insert" a SELECT instruction, we actually have to insert the diamond
1113 // control-flow pattern. The incoming instruction knows the destination vreg
1114 // to set, the condition code register to branch on, the true/false values to
1115 // select between, and a branch opcode to use.
1116 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1118
1119 // ThisMBB:
1120 // ...
1121 // TrueVal = ...
1122 // jmp_XX r1, r2 goto Copy1MBB
1123 // fallthrough --> Copy0MBB
1124 MachineBasicBlock *ThisMBB = BB;
1125 MachineFunction *F = BB->getParent();
1126 MachineBasicBlock *Copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1127 MachineBasicBlock *Copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
1128
1129 F->insert(I, Copy0MBB);
1130 F->insert(I, Copy1MBB);
1131 // Update machine-CFG edges by transferring all successors of the current
1132 // block to the new block which will contain the Phi node for the select.
1133 Copy1MBB->splice(Copy1MBB->begin(), BB,
1134 std::next(MachineBasicBlock::iterator(MI)), BB->end());
1135 Copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
1136 // Next, add the true and fallthrough blocks as its successors.
1137 BB->addSuccessor(Copy0MBB);
1138 BB->addSuccessor(Copy1MBB);
1139
1140 // Insert Branch if Flag
1141 int CC = MI.getOperand(3).getImm();
1142 int NewCC;
1143 switch (CC) {
1144#define SET_NEWCC(X, Y) \
1145 case ISD::X: \
1146 if (is32BitCmp && HasJmp32) \
1147 NewCC = isSelectRROp ? BPF::Y##_rr_32 : BPF::Y##_ri_32; \
1148 else \
1149 NewCC = isSelectRROp ? BPF::Y##_rr : BPF::Y##_ri; \
1150 break
1151 SET_NEWCC(SETGT, JSGT);
1152 SET_NEWCC(SETUGT, JUGT);
1153 SET_NEWCC(SETGE, JSGE);
1154 SET_NEWCC(SETUGE, JUGE);
1155 SET_NEWCC(SETEQ, JEQ);
1156 SET_NEWCC(SETNE, JNE);
1157 SET_NEWCC(SETLT, JSLT);
1158 SET_NEWCC(SETULT, JULT);
1159 SET_NEWCC(SETLE, JSLE);
1160 SET_NEWCC(SETULE, JULE);
1161 default:
1162 report_fatal_error("unimplemented select CondCode " + Twine(CC));
1163 }
1164
1165 Register LHS = MI.getOperand(1).getReg();
1166 bool isSignedCmp = (CC == ISD::SETGT ||
1167 CC == ISD::SETGE ||
1168 CC == ISD::SETLT ||
1169 CC == ISD::SETLE);
1170
1171 // eBPF at the moment only has 64-bit comparison. Any 32-bit comparison need
1172 // to be promoted, however if the 32-bit comparison operands are destination
1173 // registers then they are implicitly zero-extended already, there is no
1174 // need of explicit zero-extend sequence for them.
1175 //
1176 // We simply do extension for all situations in this method, but we will
1177 // try to remove those unnecessary in BPFMIPeephole pass.
1178 if (is32BitCmp && !HasJmp32)
1179 LHS = EmitSubregExt(MI, BB, LHS, isSignedCmp);
1180
1181 if (isSelectRROp) {
1182 Register RHS = MI.getOperand(2).getReg();
1183
1184 if (is32BitCmp && !HasJmp32)
1185 RHS = EmitSubregExt(MI, BB, RHS, isSignedCmp);
1186
1187 BuildMI(BB, DL, TII.get(NewCC)).addReg(LHS).addReg(RHS).addMBB(Copy1MBB);
1188 } else {
1189 int64_t imm32 = MI.getOperand(2).getImm();
1190 // Check before we build J*_ri instruction.
1191 if (!isInt<32>(imm32))
1192 report_fatal_error("immediate overflows 32 bits: " + Twine(imm32));
1193 BuildMI(BB, DL, TII.get(NewCC))
1194 .addReg(LHS).addImm(imm32).addMBB(Copy1MBB);
1195 }
1196
1197 // Copy0MBB:
1198 // %FalseValue = ...
1199 // # fallthrough to Copy1MBB
1200 BB = Copy0MBB;
1201
1202 // Update machine-CFG edges
1203 BB->addSuccessor(Copy1MBB);
1204
1205 // Copy1MBB:
1206 // %Result = phi [ %FalseValue, Copy0MBB ], [ %TrueValue, ThisMBB ]
1207 // ...
1208 BB = Copy1MBB;
1209 BuildMI(*BB, BB->begin(), DL, TII.get(BPF::PHI), MI.getOperand(0).getReg())
1210 .addReg(MI.getOperand(5).getReg())
1211 .addMBB(Copy0MBB)
1212 .addReg(MI.getOperand(4).getReg())
1213 .addMBB(ThisMBB);
1214
1215 MI.eraseFromParent(); // The pseudo instruction is gone now.
1216 return BB;
1217}
1218
1220 EVT VT) const {
1221 return getHasAlu32() ? MVT::i32 : MVT::i64;
1222}
1223
1225 EVT VT) const {
1226 return (getHasAlu32() && VT == MVT::i32) ? MVT::i32 : MVT::i64;
1227}
1228
1229bool BPFTargetLowering::isLegalAddressingMode(const DataLayout &DL,
1230 const AddrMode &AM, Type *Ty,
1231 unsigned AS,
1232 Instruction *I) const {
1233 // No global is ever allowed as a base.
1234 if (AM.BaseGV)
1235 return false;
1236
1237 switch (AM.Scale) {
1238 case 0: // "r+i" or just "i", depending on HasBaseReg.
1239 break;
1240 case 1:
1241 if (!AM.HasBaseReg) // allow "r+i".
1242 break;
1243 return false; // disallow "r+r" or "r+r+i".
1244 default:
1245 return false;
1246 }
1247
1248 return true;
1249}
1250
1251bool BPFTargetLowering::CanLowerReturn(
1252 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
1254 const Type *RetTy) const {
1256 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
1257 return CCInfo.CheckReturn(Outs, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
1258}
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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:25
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
const char * Msg
Value * RHS
Value * LHS
unsigned getCommonMaxStoresPerMemFunc() 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.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned, Align, MachineMemOperand::Flags, unsigned *) const override
Determine if the target supports unaligned memory accesses.
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
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:168
void setCallingConv(CallingConv::ID CC)
Definition Function.h:276
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
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
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...
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
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.
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.
Flags
Flags values. These may be or'd together.
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:67
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)
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 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 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)
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)
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)
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.
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 setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
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:282
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:197
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
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:255
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:829
@ 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:275
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:789
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ 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:863
@ GlobalAddress
Definition ISDOpcodes.h:88
@ 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:280
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:798
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:854
@ BR_CC
BR_CC - Conditional branch.
@ BRIND
BRIND - Indirect branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:806
@ 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:706
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:860
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:821
@ 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:898
@ 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:797
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:866
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:843
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:62
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:55
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:165
@ 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
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
Definition STLExtras.h:1151
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
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:862
#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:145
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
void print(raw_ostream &OS) const
Implement operator<<.
Definition ValueTypes.h:527
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs