LLVM 19.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"
17#include "BPFTargetMachine.h"
27#include "llvm/Support/Debug.h"
31
32using namespace llvm;
33
34#define DEBUG_TYPE "bpf-lower"
35
36static cl::opt<bool> BPFExpandMemcpyInOrder("bpf-expand-memcpy-in-order",
37 cl::Hidden, cl::init(false),
38 cl::desc("Expand memcpy into load/store pairs in order"));
39
40static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg,
41 SDValue Val = {}) {
42 std::string Str;
43 if (Val) {
45 Val->print(OS);
46 OS << ' ';
47 }
50 MF.getFunction(), Twine(Str).concat(Msg), DL.getDebugLoc()));
51}
52
54 const BPFSubtarget &STI)
56
57 // Set up the register classes.
58 addRegisterClass(MVT::i64, &BPF::GPRRegClass);
59 if (STI.getHasAlu32())
60 addRegisterClass(MVT::i32, &BPF::GPR32RegClass);
61
62 // Compute derived properties from the register classes
64
66
71
73
77
78 // Set unsupported atomic operations as Custom so
79 // we can emit better error messages than fatal error
80 // from selectiondag.
81 for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
82 if (VT == MVT::i32) {
83 if (STI.getHasAlu32())
84 continue;
85 } else {
87 }
88
94 }
95
96 for (auto VT : { MVT::i32, MVT::i64 }) {
97 if (VT == MVT::i32 && !STI.getHasAlu32())
98 continue;
99
102 if (!STI.hasSdivSmod()) {
105 }
116
120 }
121
122 if (STI.getHasAlu32()) {
125 STI.getHasJmp32() ? Custom : Promote);
126 }
127
132
134 if (!STI.hasMovsx()) {
138 }
139
140 // Extended load operations for i1 types must be promoted
141 for (MVT VT : MVT::integer_valuetypes()) {
145
146 if (!STI.hasLdsx()) {
148 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i16, Expand);
149 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i32, Expand);
150 }
151 }
152
155
156 // Function alignments
159
161 // LLVM generic code will try to expand memcpy into load/store pairs at this
162 // stage which is before quite a few IR optimization passes, therefore the
163 // loads and stores could potentially be moved apart from each other which
164 // will cause trouble to memcpy pattern matcher inside kernel eBPF JIT
165 // compilers.
166 //
167 // When -bpf-expand-memcpy-in-order specified, we want to defer the expand
168 // of memcpy to later stage in IR optimization pipeline so those load/store
169 // pairs won't be touched and could be kept in order. Hence, we set
170 // MaxStoresPerMem* to zero to disable the generic getMemcpyLoadsAndStores
171 // code path, and ask LLVM to use target expander EmitTargetCodeForMemcpy.
176 } else {
177 // inline memcpy() for kernel to see explicit copy
178 unsigned CommonMaxStores =
180
185 }
186
187 // CPU/Feature control
188 HasAlu32 = STI.getHasAlu32();
189 HasJmp32 = STI.getHasJmp32();
190 HasJmpExt = STI.getHasJmpExt();
191 HasMovsx = STI.hasMovsx();
192}
193
195 return false;
196}
197
198bool BPFTargetLowering::isTruncateFree(Type *Ty1, Type *Ty2) const {
199 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
200 return false;
201 unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
202 unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
203 return NumBits1 > NumBits2;
204}
205
206bool BPFTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
207 if (!VT1.isInteger() || !VT2.isInteger())
208 return false;
209 unsigned NumBits1 = VT1.getSizeInBits();
210 unsigned NumBits2 = VT2.getSizeInBits();
211 return NumBits1 > NumBits2;
212}
213
214bool BPFTargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
215 if (!getHasAlu32() || !Ty1->isIntegerTy() || !Ty2->isIntegerTy())
216 return false;
217 unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
218 unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
219 return NumBits1 == 32 && NumBits2 == 64;
220}
221
222bool BPFTargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
223 if (!getHasAlu32() || !VT1.isInteger() || !VT2.isInteger())
224 return false;
225 unsigned NumBits1 = VT1.getSizeInBits();
226 unsigned NumBits2 = VT2.getSizeInBits();
227 return NumBits1 == 32 && NumBits2 == 64;
228}
229
230bool BPFTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
231 EVT VT1 = Val.getValueType();
232 if (Val.getOpcode() == ISD::LOAD && VT1.isSimple() && VT2.isSimple()) {
233 MVT MT1 = VT1.getSimpleVT().SimpleTy;
234 MVT MT2 = VT2.getSimpleVT().SimpleTy;
235 if ((MT1 == MVT::i8 || MT1 == MVT::i16 || MT1 == MVT::i32) &&
236 (MT2 == MVT::i32 || MT2 == MVT::i64))
237 return true;
238 }
239 return TargetLoweringBase::isZExtFree(Val, VT2);
240}
241
244 if (Constraint.size() == 1) {
245 switch (Constraint[0]) {
246 default:
247 break;
248 case 'w':
249 return C_RegisterClass;
250 }
251 }
252
253 return TargetLowering::getConstraintType(Constraint);
254}
255
256std::pair<unsigned, const TargetRegisterClass *>
258 StringRef Constraint,
259 MVT VT) const {
260 if (Constraint.size() == 1) {
261 // GCC Constraint Letters
262 switch (Constraint[0]) {
263 case 'r': // GENERAL_REGS
264 return std::make_pair(0U, &BPF::GPRRegClass);
265 case 'w':
266 if (HasAlu32)
267 return std::make_pair(0U, &BPF::GPR32RegClass);
268 break;
269 default:
270 break;
271 }
272 }
273
275}
276
277void BPFTargetLowering::ReplaceNodeResults(
279 const char *Msg;
280 uint32_t Opcode = N->getOpcode();
281 switch (Opcode) {
282 default:
283 report_fatal_error("unhandled custom legalization: " + Twine(Opcode));
288 case ISD::ATOMIC_SWAP:
290 if (HasAlu32 || Opcode == ISD::ATOMIC_LOAD_ADD)
291 Msg = "unsupported atomic operation, please use 32/64 bit version";
292 else
293 Msg = "unsupported atomic operation, please use 64 bit version";
294 break;
295 }
296
297 SDLoc DL(N);
298 // We'll still produce a fatal error downstream, but this diagnostic is more
299 // user-friendly.
300 fail(DL, DAG, Msg);
301}
302
304 switch (Op.getOpcode()) {
305 default:
306 report_fatal_error("unimplemented opcode: " + Twine(Op.getOpcode()));
307 case ISD::BR_CC:
308 return LowerBR_CC(Op, DAG);
310 return LowerGlobalAddress(Op, DAG);
312 return LowerConstantPool(Op, DAG);
313 case ISD::SELECT_CC:
314 return LowerSELECT_CC(Op, DAG);
315 case ISD::SDIV:
316 case ISD::SREM:
317 return LowerSDIVSREM(Op, DAG);
319 return LowerDYNAMIC_STACKALLOC(Op, DAG);
320 }
321}
322
323// Calling Convention Implementation
324#include "BPFGenCallingConv.inc"
325
326SDValue BPFTargetLowering::LowerFormalArguments(
327 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
328 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
329 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
330 switch (CallConv) {
331 default:
332 report_fatal_error("unimplemented calling convention: " + Twine(CallConv));
333 case CallingConv::C:
335 break;
336 }
337
340
341 // Assign locations to all of the incoming arguments.
343 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
344 CCInfo.AnalyzeFormalArguments(Ins, getHasAlu32() ? CC_BPF32 : CC_BPF64);
345
346 bool HasMemArgs = false;
347 for (size_t I = 0; I < ArgLocs.size(); ++I) {
348 auto &VA = ArgLocs[I];
349
350 if (VA.isRegLoc()) {
351 // Arguments passed in registers
352 EVT RegVT = VA.getLocVT();
353 MVT::SimpleValueType SimpleTy = RegVT.getSimpleVT().SimpleTy;
354 switch (SimpleTy) {
355 default: {
356 std::string Str;
357 {
359 RegVT.print(OS);
360 }
361 report_fatal_error("unhandled argument type: " + Twine(Str));
362 }
363 case MVT::i32:
364 case MVT::i64:
365 Register VReg = RegInfo.createVirtualRegister(
366 SimpleTy == MVT::i64 ? &BPF::GPRRegClass : &BPF::GPR32RegClass);
367 RegInfo.addLiveIn(VA.getLocReg(), VReg);
368 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
369
370 // If this is an value that has been promoted to wider types, insert an
371 // assert[sz]ext to capture this, then truncate to the right size.
372 if (VA.getLocInfo() == CCValAssign::SExt)
373 ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
374 DAG.getValueType(VA.getValVT()));
375 else if (VA.getLocInfo() == CCValAssign::ZExt)
376 ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
377 DAG.getValueType(VA.getValVT()));
378
379 if (VA.getLocInfo() != CCValAssign::Full)
380 ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
381
382 InVals.push_back(ArgValue);
383
384 break;
385 }
386 } else {
387 if (VA.isMemLoc())
388 HasMemArgs = true;
389 else
390 report_fatal_error("unhandled argument location");
391 InVals.push_back(DAG.getConstant(0, DL, VA.getLocVT()));
392 }
393 }
394 if (HasMemArgs)
395 fail(DL, DAG, "stack arguments are not supported");
396 if (IsVarArg)
397 fail(DL, DAG, "variadic functions are not supported");
398 if (MF.getFunction().hasStructRetAttr())
399 fail(DL, DAG, "aggregate returns are not supported");
400
401 return Chain;
402}
403
404const size_t BPFTargetLowering::MaxArgs = 5;
405
406SDValue BPFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
407 SmallVectorImpl<SDValue> &InVals) const {
408 SelectionDAG &DAG = CLI.DAG;
409 auto &Outs = CLI.Outs;
410 auto &OutVals = CLI.OutVals;
411 auto &Ins = CLI.Ins;
412 SDValue Chain = CLI.Chain;
413 SDValue Callee = CLI.Callee;
414 bool &IsTailCall = CLI.IsTailCall;
415 CallingConv::ID CallConv = CLI.CallConv;
416 bool IsVarArg = CLI.IsVarArg;
418
419 // BPF target does not support tail call optimization.
420 IsTailCall = false;
421
422 switch (CallConv) {
423 default:
424 report_fatal_error("unsupported calling convention: " + Twine(CallConv));
426 case CallingConv::C:
427 break;
428 }
429
430 // Analyze operands of the call, assigning locations to each operand.
432 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
433
434 CCInfo.AnalyzeCallOperands(Outs, getHasAlu32() ? CC_BPF32 : CC_BPF64);
435
436 unsigned NumBytes = CCInfo.getStackSize();
437
438 if (Outs.size() > MaxArgs)
439 fail(CLI.DL, DAG, "too many arguments", Callee);
440
441 for (auto &Arg : Outs) {
442 ISD::ArgFlagsTy Flags = Arg.Flags;
443 if (!Flags.isByVal())
444 continue;
445 fail(CLI.DL, DAG, "pass by value not supported", Callee);
446 break;
447 }
448
449 auto PtrVT = getPointerTy(MF.getDataLayout());
450 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
451
452 SmallVector<std::pair<unsigned, SDValue>, MaxArgs> RegsToPass;
453
454 // Walk arg assignments
455 for (size_t i = 0; i < std::min(ArgLocs.size(), MaxArgs); ++i) {
456 CCValAssign &VA = ArgLocs[i];
457 SDValue &Arg = OutVals[i];
458
459 // Promote the value if needed.
460 switch (VA.getLocInfo()) {
461 default:
462 report_fatal_error("unhandled location info: " + Twine(VA.getLocInfo()));
464 break;
466 Arg = DAG.getNode(ISD::SIGN_EXTEND, CLI.DL, VA.getLocVT(), Arg);
467 break;
469 Arg = DAG.getNode(ISD::ZERO_EXTEND, CLI.DL, VA.getLocVT(), Arg);
470 break;
472 Arg = DAG.getNode(ISD::ANY_EXTEND, CLI.DL, VA.getLocVT(), Arg);
473 break;
474 }
475
476 // Push arguments into RegsToPass vector
477 if (VA.isRegLoc())
478 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
479 else
480 report_fatal_error("stack arguments are not supported");
481 }
482
483 SDValue InGlue;
484
485 // Build a sequence of copy-to-reg nodes chained together with token chain and
486 // flag operands which copy the outgoing args into registers. The InGlue in
487 // necessary since all emitted instructions must be stuck together.
488 for (auto &Reg : RegsToPass) {
489 Chain = DAG.getCopyToReg(Chain, CLI.DL, Reg.first, Reg.second, InGlue);
490 InGlue = Chain.getValue(1);
491 }
492
493 // If the callee is a GlobalAddress node (quite common, every direct call is)
494 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
495 // Likewise ExternalSymbol -> TargetExternalSymbol.
496 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
497 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), CLI.DL, PtrVT,
498 G->getOffset(), 0);
499 } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
500 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
501 fail(CLI.DL, DAG,
502 Twine("A call to built-in function '" + StringRef(E->getSymbol()) +
503 "' is not supported."));
504 }
505
506 // Returns a chain & a flag for retval copy to use.
507 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
509 Ops.push_back(Chain);
510 Ops.push_back(Callee);
511
512 // Add argument registers to the end of the list so that they are
513 // known live into the call.
514 for (auto &Reg : RegsToPass)
515 Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
516
517 if (InGlue.getNode())
518 Ops.push_back(InGlue);
519
520 Chain = DAG.getNode(BPFISD::CALL, CLI.DL, NodeTys, Ops);
521 InGlue = Chain.getValue(1);
522
523 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
524
525 // Create the CALLSEQ_END node.
526 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, CLI.DL);
527 InGlue = Chain.getValue(1);
528
529 // Handle result values, copying them out of physregs into vregs that we
530 // return.
531 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, CLI.DL, DAG,
532 InVals);
533}
534
536BPFTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
537 bool IsVarArg,
539 const SmallVectorImpl<SDValue> &OutVals,
540 const SDLoc &DL, SelectionDAG &DAG) const {
541 unsigned Opc = BPFISD::RET_GLUE;
542
543 // CCValAssign - represent the assignment of the return value to a location
546
547 // CCState - Info about the registers and stack slot.
548 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
549
551 fail(DL, DAG, "aggregate returns are not supported");
552 return DAG.getNode(Opc, DL, MVT::Other, Chain);
553 }
554
555 // Analize return values.
556 CCInfo.AnalyzeReturn(Outs, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
557
558 SDValue Glue;
559 SmallVector<SDValue, 4> RetOps(1, Chain);
560
561 // Copy the result values into the output registers.
562 for (size_t i = 0; i != RVLocs.size(); ++i) {
563 CCValAssign &VA = RVLocs[i];
564 if (!VA.isRegLoc())
565 report_fatal_error("stack return values are not supported");
566
567 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Glue);
568
569 // Guarantee that all emitted copies are stuck together,
570 // avoiding something bad.
571 Glue = Chain.getValue(1);
572 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
573 }
574
575 RetOps[0] = Chain; // Update chain.
576
577 // Add the glue if we have it.
578 if (Glue.getNode())
579 RetOps.push_back(Glue);
580
581 return DAG.getNode(Opc, DL, MVT::Other, RetOps);
582}
583
584SDValue BPFTargetLowering::LowerCallResult(
585 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
586 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
587 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
588
590 // Assign locations to each value returned by this call.
592 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
593
594 if (Ins.size() > 1) {
595 fail(DL, DAG, "only small returns supported");
596 for (auto &In : Ins)
597 InVals.push_back(DAG.getConstant(0, DL, In.VT));
598 return DAG.getCopyFromReg(Chain, DL, 1, Ins[0].VT, InGlue).getValue(1);
599 }
600
601 CCInfo.AnalyzeCallResult(Ins, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
602
603 // Copy all of the result registers out of their specified physreg.
604 for (auto &Val : RVLocs) {
605 Chain = DAG.getCopyFromReg(Chain, DL, Val.getLocReg(),
606 Val.getValVT(), InGlue).getValue(1);
607 InGlue = Chain.getValue(2);
608 InVals.push_back(Chain.getValue(0));
609 }
610
611 return Chain;
612}
613
614static void NegateCC(SDValue &LHS, SDValue &RHS, ISD::CondCode &CC) {
615 switch (CC) {
616 default:
617 break;
618 case ISD::SETULT:
619 case ISD::SETULE:
620 case ISD::SETLT:
621 case ISD::SETLE:
623 std::swap(LHS, RHS);
624 break;
625 }
626}
627
628SDValue BPFTargetLowering::LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const {
629 SDLoc DL(Op);
630 fail(DL, DAG,
631 "unsupported signed division, please convert to unsigned div/mod.");
632 return DAG.getUNDEF(Op->getValueType(0));
633}
634
635SDValue BPFTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
636 SelectionDAG &DAG) const {
637 SDLoc DL(Op);
638 fail(DL, DAG, "unsupported dynamic stack allocation");
639 auto Ops = {DAG.getConstant(0, SDLoc(), Op.getValueType()), Op.getOperand(0)};
640 return DAG.getMergeValues(Ops, SDLoc());
641}
642
643SDValue BPFTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
644 SDValue Chain = Op.getOperand(0);
645 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
646 SDValue LHS = Op.getOperand(2);
647 SDValue RHS = Op.getOperand(3);
648 SDValue Dest = Op.getOperand(4);
649 SDLoc DL(Op);
650
651 if (!getHasJmpExt())
652 NegateCC(LHS, RHS, CC);
653
654 return DAG.getNode(BPFISD::BR_CC, DL, Op.getValueType(), Chain, LHS, RHS,
655 DAG.getConstant(CC, DL, LHS.getValueType()), Dest);
656}
657
658SDValue BPFTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
659 SDValue LHS = Op.getOperand(0);
660 SDValue RHS = Op.getOperand(1);
661 SDValue TrueV = Op.getOperand(2);
662 SDValue FalseV = Op.getOperand(3);
663 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
664 SDLoc DL(Op);
665
666 if (!getHasJmpExt())
667 NegateCC(LHS, RHS, CC);
668
669 SDValue TargetCC = DAG.getConstant(CC, DL, LHS.getValueType());
670 SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
671 SDValue Ops[] = {LHS, RHS, TargetCC, TrueV, FalseV};
672
673 return DAG.getNode(BPFISD::SELECT_CC, DL, VTs, Ops);
674}
675
676const char *BPFTargetLowering::getTargetNodeName(unsigned Opcode) const {
677 switch ((BPFISD::NodeType)Opcode) {
679 break;
680 case BPFISD::RET_GLUE:
681 return "BPFISD::RET_GLUE";
682 case BPFISD::CALL:
683 return "BPFISD::CALL";
685 return "BPFISD::SELECT_CC";
686 case BPFISD::BR_CC:
687 return "BPFISD::BR_CC";
688 case BPFISD::Wrapper:
689 return "BPFISD::Wrapper";
690 case BPFISD::MEMCPY:
691 return "BPFISD::MEMCPY";
692 }
693 return nullptr;
694}
695
697 SelectionDAG &DAG, unsigned Flags) {
698 return DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, Flags);
699}
700
702 SelectionDAG &DAG, unsigned Flags) {
703 return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(),
704 N->getOffset(), Flags);
705}
706
707template <class NodeTy>
708SDValue BPFTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
709 unsigned Flags) const {
710 SDLoc DL(N);
711
712 SDValue GA = getTargetNode(N, DL, MVT::i64, DAG, Flags);
713
714 return DAG.getNode(BPFISD::Wrapper, DL, MVT::i64, GA);
715}
716
717SDValue BPFTargetLowering::LowerGlobalAddress(SDValue Op,
718 SelectionDAG &DAG) const {
719 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
720 if (N->getOffset() != 0)
721 report_fatal_error("invalid offset for global address: " +
722 Twine(N->getOffset()));
723 return getAddr(N, DAG);
724}
725
726SDValue BPFTargetLowering::LowerConstantPool(SDValue Op,
727 SelectionDAG &DAG) const {
728 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
729
730 return getAddr(N, DAG);
731}
732
733unsigned
734BPFTargetLowering::EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB,
735 unsigned Reg, bool isSigned) const {
737 const TargetRegisterClass *RC = getRegClassFor(MVT::i64);
738 int RShiftOp = isSigned ? BPF::SRA_ri : BPF::SRL_ri;
739 MachineFunction *F = BB->getParent();
740 DebugLoc DL = MI.getDebugLoc();
741
742 MachineRegisterInfo &RegInfo = F->getRegInfo();
743
744 if (!isSigned) {
745 Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
746 BuildMI(BB, DL, TII.get(BPF::MOV_32_64), PromotedReg0).addReg(Reg);
747 return PromotedReg0;
748 }
749 Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
750 Register PromotedReg1 = RegInfo.createVirtualRegister(RC);
751 Register PromotedReg2 = RegInfo.createVirtualRegister(RC);
752 if (HasMovsx) {
753 BuildMI(BB, DL, TII.get(BPF::MOVSX_rr_32), PromotedReg0).addReg(Reg);
754 } else {
755 BuildMI(BB, DL, TII.get(BPF::MOV_32_64), PromotedReg0).addReg(Reg);
756 BuildMI(BB, DL, TII.get(BPF::SLL_ri), PromotedReg1)
757 .addReg(PromotedReg0).addImm(32);
758 BuildMI(BB, DL, TII.get(RShiftOp), PromotedReg2)
759 .addReg(PromotedReg1).addImm(32);
760 }
761
762 return PromotedReg2;
763}
764
766BPFTargetLowering::EmitInstrWithCustomInserterMemcpy(MachineInstr &MI,
768 const {
769 MachineFunction *MF = MI.getParent()->getParent();
771 MachineInstrBuilder MIB(*MF, MI);
772 unsigned ScratchReg;
773
774 // This function does custom insertion during lowering BPFISD::MEMCPY which
775 // only has two register operands from memcpy semantics, the copy source
776 // address and the copy destination address.
777 //
778 // Because we will expand BPFISD::MEMCPY into load/store pairs, we will need
779 // a third scratch register to serve as the destination register of load and
780 // source register of store.
781 //
782 // The scratch register here is with the Define | Dead | EarlyClobber flags.
783 // The EarlyClobber flag has the semantic property that the operand it is
784 // attached to is clobbered before the rest of the inputs are read. Hence it
785 // must be unique among the operands to the instruction. The Define flag is
786 // needed to coerce the machine verifier that an Undef value isn't a problem
787 // as we anyway is loading memory into it. The Dead flag is needed as the
788 // value in scratch isn't supposed to be used by any other instruction.
789 ScratchReg = MRI.createVirtualRegister(&BPF::GPRRegClass);
790 MIB.addReg(ScratchReg,
792
793 return BB;
794}
795
798 MachineBasicBlock *BB) const {
800 DebugLoc DL = MI.getDebugLoc();
801 unsigned Opc = MI.getOpcode();
802 bool isSelectRROp = (Opc == BPF::Select ||
803 Opc == BPF::Select_64_32 ||
804 Opc == BPF::Select_32 ||
805 Opc == BPF::Select_32_64);
806
807 bool isMemcpyOp = Opc == BPF::MEMCPY;
808
809#ifndef NDEBUG
810 bool isSelectRIOp = (Opc == BPF::Select_Ri ||
811 Opc == BPF::Select_Ri_64_32 ||
812 Opc == BPF::Select_Ri_32 ||
813 Opc == BPF::Select_Ri_32_64);
814
815 if (!(isSelectRROp || isSelectRIOp || isMemcpyOp))
816 report_fatal_error("unhandled instruction type: " + Twine(Opc));
817#endif
818
819 if (isMemcpyOp)
820 return EmitInstrWithCustomInserterMemcpy(MI, BB);
821
822 bool is32BitCmp = (Opc == BPF::Select_32 ||
823 Opc == BPF::Select_32_64 ||
824 Opc == BPF::Select_Ri_32 ||
825 Opc == BPF::Select_Ri_32_64);
826
827 // To "insert" a SELECT instruction, we actually have to insert the diamond
828 // control-flow pattern. The incoming instruction knows the destination vreg
829 // to set, the condition code register to branch on, the true/false values to
830 // select between, and a branch opcode to use.
831 const BasicBlock *LLVM_BB = BB->getBasicBlock();
833
834 // ThisMBB:
835 // ...
836 // TrueVal = ...
837 // jmp_XX r1, r2 goto Copy1MBB
838 // fallthrough --> Copy0MBB
839 MachineBasicBlock *ThisMBB = BB;
840 MachineFunction *F = BB->getParent();
841 MachineBasicBlock *Copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
842 MachineBasicBlock *Copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
843
844 F->insert(I, Copy0MBB);
845 F->insert(I, Copy1MBB);
846 // Update machine-CFG edges by transferring all successors of the current
847 // block to the new block which will contain the Phi node for the select.
848 Copy1MBB->splice(Copy1MBB->begin(), BB,
849 std::next(MachineBasicBlock::iterator(MI)), BB->end());
851 // Next, add the true and fallthrough blocks as its successors.
852 BB->addSuccessor(Copy0MBB);
853 BB->addSuccessor(Copy1MBB);
854
855 // Insert Branch if Flag
856 int CC = MI.getOperand(3).getImm();
857 int NewCC;
858 switch (CC) {
859#define SET_NEWCC(X, Y) \
860 case ISD::X: \
861 if (is32BitCmp && HasJmp32) \
862 NewCC = isSelectRROp ? BPF::Y##_rr_32 : BPF::Y##_ri_32; \
863 else \
864 NewCC = isSelectRROp ? BPF::Y##_rr : BPF::Y##_ri; \
865 break
866 SET_NEWCC(SETGT, JSGT);
867 SET_NEWCC(SETUGT, JUGT);
868 SET_NEWCC(SETGE, JSGE);
869 SET_NEWCC(SETUGE, JUGE);
870 SET_NEWCC(SETEQ, JEQ);
871 SET_NEWCC(SETNE, JNE);
872 SET_NEWCC(SETLT, JSLT);
873 SET_NEWCC(SETULT, JULT);
874 SET_NEWCC(SETLE, JSLE);
875 SET_NEWCC(SETULE, JULE);
876 default:
877 report_fatal_error("unimplemented select CondCode " + Twine(CC));
878 }
879
880 Register LHS = MI.getOperand(1).getReg();
881 bool isSignedCmp = (CC == ISD::SETGT ||
882 CC == ISD::SETGE ||
883 CC == ISD::SETLT ||
884 CC == ISD::SETLE);
885
886 // eBPF at the moment only has 64-bit comparison. Any 32-bit comparison need
887 // to be promoted, however if the 32-bit comparison operands are destination
888 // registers then they are implicitly zero-extended already, there is no
889 // need of explicit zero-extend sequence for them.
890 //
891 // We simply do extension for all situations in this method, but we will
892 // try to remove those unnecessary in BPFMIPeephole pass.
893 if (is32BitCmp && !HasJmp32)
894 LHS = EmitSubregExt(MI, BB, LHS, isSignedCmp);
895
896 if (isSelectRROp) {
897 Register RHS = MI.getOperand(2).getReg();
898
899 if (is32BitCmp && !HasJmp32)
900 RHS = EmitSubregExt(MI, BB, RHS, isSignedCmp);
901
902 BuildMI(BB, DL, TII.get(NewCC)).addReg(LHS).addReg(RHS).addMBB(Copy1MBB);
903 } else {
904 int64_t imm32 = MI.getOperand(2).getImm();
905 // Check before we build J*_ri instruction.
906 if (!isInt<32>(imm32))
907 report_fatal_error("immediate overflows 32 bits: " + Twine(imm32));
908 BuildMI(BB, DL, TII.get(NewCC))
909 .addReg(LHS).addImm(imm32).addMBB(Copy1MBB);
910 }
911
912 // Copy0MBB:
913 // %FalseValue = ...
914 // # fallthrough to Copy1MBB
915 BB = Copy0MBB;
916
917 // Update machine-CFG edges
918 BB->addSuccessor(Copy1MBB);
919
920 // Copy1MBB:
921 // %Result = phi [ %FalseValue, Copy0MBB ], [ %TrueValue, ThisMBB ]
922 // ...
923 BB = Copy1MBB;
924 BuildMI(*BB, BB->begin(), DL, TII.get(BPF::PHI), MI.getOperand(0).getReg())
925 .addReg(MI.getOperand(5).getReg())
926 .addMBB(Copy0MBB)
927 .addReg(MI.getOperand(4).getReg())
928 .addMBB(ThisMBB);
929
930 MI.eraseFromParent(); // The pseudo instruction is gone now.
931 return BB;
932}
933
935 EVT VT) const {
936 return getHasAlu32() ? MVT::i32 : MVT::i64;
937}
938
940 EVT VT) const {
941 return (getHasAlu32() && VT == MVT::i32) ? MVT::i32 : MVT::i64;
942}
943
944bool BPFTargetLowering::isLegalAddressingMode(const DataLayout &DL,
945 const AddrMode &AM, Type *Ty,
946 unsigned AS,
947 Instruction *I) const {
948 // No global is ever allowed as a base.
949 if (AM.BaseGV)
950 return false;
951
952 switch (AM.Scale) {
953 case 0: // "r+i" or just "i", depending on HasBaseReg.
954 break;
955 case 1:
956 if (!AM.HasBaseReg) // allow "r+i".
957 break;
958 return false; // disallow "r+r" or "r+r+i".
959 default:
960 return false;
961 }
962
963 return true;
964}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static SDValue getTargetNode(GlobalAddressSDNode *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 void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg, SDValue Val={})
static void NegateCC(SDValue &LHS, SDValue &RHS, ISD::CondCode &CC)
#define SET_NEWCC(X, Y)
static bool isSigned(unsigned int Opcode)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
unsigned const TargetRegisterInfo * TRI
const char LLVMTargetMachineRef TM
raw_pwrite_stream & OS
Value * RHS
Value * LHS
unsigned getCommonMaxStoresPerMemFunc() const
bool hasSdivSmod() const
Definition: BPFSubtarget.h:92
bool getHasJmpExt() const
Definition: BPFSubtarget.h:85
const BPFSelectionDAGInfo * getSelectionDAGInfo() const override
Definition: BPFSubtarget.h:105
bool hasLdsx() const
Definition: BPFSubtarget.h:89
bool hasMovsx() const
Definition: BPFSubtarget.h:90
bool getHasJmp32() const
Definition: BPFSubtarget.h:86
const BPFRegisterInfo * getRegisterInfo() const override
Definition: BPFSubtarget.h:108
bool getHasAlu32() const
Definition: BPFSubtarget.h:87
BPFTargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
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:60
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
Register getLocReg() const
LocInfo getLocInfo() const
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:110
A debug info location.
Definition: DebugLoc.h:33
Diagnostic information for unsupported feature in backend.
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition: Function.h:661
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:205
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Machine Value Type.
SimpleValueType SimpleTy
static auto integer_valuetypes()
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.
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 '...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
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...
Definition: SelectionDAG.h:225
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:722
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
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 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 ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:773
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:469
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:799
LLVMContext * getContext() const
Definition: SelectionDAG.h:485
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)
Definition: SelectionDAG.h:739
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
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.
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.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
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.
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
bool isAggregateType() const
Return true if the type is an aggregate type.
Definition: Type.h:295
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:228
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
self_iterator getIterator()
Definition: ilist_node.h:109
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:660
@ 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:750
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1126
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1122
@ CTLZ_ZERO_UNDEF
Definition: ISDOpcodes.h:723
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:250
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:714
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:1031
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:783
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
Definition: ISDOpcodes.h:1254
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:255
@ ATOMIC_LOAD_OR
Definition: ISDOpcodes.h:1267
@ ATOMIC_LOAD_XOR
Definition: ISDOpcodes.h:1268
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:774
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
Definition: ISDOpcodes.h:722
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1077
@ BRIND
BRIND - Indirect branch.
Definition: ISDOpcodes.h:1052
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1056
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:727
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:651
@ ATOMIC_LOAD_AND
Definition: ISDOpcodes.h:1265
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:780
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:742
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1041
@ ConstantPool
Definition: ISDOpcodes.h:82
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:798
@ ATOMIC_LOAD_ADD
Definition: ISDOpcodes.h:1263
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
Definition: ISDOpcodes.h:1262
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:786
@ BRCOND
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:1070
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition: ISDOpcodes.h:763
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition: ISDOpcodes.h:61
@ AssertZext
Definition: ISDOpcodes.h:62
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,...
Definition: ISDOpcodes.h:1523
@ Dead
Unused definition.
@ Define
Register definition.
@ EarlyClobber
Register definition happens before uses.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:450
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&... Ranges)
Concatenated range across two or more ranges.
Definition: STLExtras.h:1185
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860
#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:34
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition: ValueTypes.h:136
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:358
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:306
void print(raw_ostream &OS) const
Implement operator<<.
Definition: ValueTypes.h:481
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: ValueTypes.h:151
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals