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