LLVM 18.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())
114
118 }
119
120 if (STI.getHasAlu32()) {
123 STI.getHasJmp32() ? Custom : Promote);
124 }
125
130
132 if (!STI.hasMovsx()) {
136 }
137
138 // Extended load operations for i1 types must be promoted
139 for (MVT VT : MVT::integer_valuetypes()) {
143
144 if (!STI.hasLdsx()) {
146 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i16, Expand);
147 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i32, Expand);
148 }
149 }
150
152
153 // Function alignments
156
158 // LLVM generic code will try to expand memcpy into load/store pairs at this
159 // stage which is before quite a few IR optimization passes, therefore the
160 // loads and stores could potentially be moved apart from each other which
161 // will cause trouble to memcpy pattern matcher inside kernel eBPF JIT
162 // compilers.
163 //
164 // When -bpf-expand-memcpy-in-order specified, we want to defer the expand
165 // of memcpy to later stage in IR optimization pipeline so those load/store
166 // pairs won't be touched and could be kept in order. Hence, we set
167 // MaxStoresPerMem* to zero to disable the generic getMemcpyLoadsAndStores
168 // code path, and ask LLVM to use target expander EmitTargetCodeForMemcpy.
173 } else {
174 // inline memcpy() for kernel to see explicit copy
175 unsigned CommonMaxStores =
177
182 }
183
184 // CPU/Feature control
185 HasAlu32 = STI.getHasAlu32();
186 HasJmp32 = STI.getHasJmp32();
187 HasJmpExt = STI.getHasJmpExt();
188 HasMovsx = STI.hasMovsx();
189}
190
192 return false;
193}
194
195bool BPFTargetLowering::isTruncateFree(Type *Ty1, Type *Ty2) const {
196 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
197 return false;
198 unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
199 unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
200 return NumBits1 > NumBits2;
201}
202
203bool BPFTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
204 if (!VT1.isInteger() || !VT2.isInteger())
205 return false;
206 unsigned NumBits1 = VT1.getSizeInBits();
207 unsigned NumBits2 = VT2.getSizeInBits();
208 return NumBits1 > NumBits2;
209}
210
211bool BPFTargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
212 if (!getHasAlu32() || !Ty1->isIntegerTy() || !Ty2->isIntegerTy())
213 return false;
214 unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
215 unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
216 return NumBits1 == 32 && NumBits2 == 64;
217}
218
219bool BPFTargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
220 if (!getHasAlu32() || !VT1.isInteger() || !VT2.isInteger())
221 return false;
222 unsigned NumBits1 = VT1.getSizeInBits();
223 unsigned NumBits2 = VT2.getSizeInBits();
224 return NumBits1 == 32 && NumBits2 == 64;
225}
226
227bool BPFTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
228 EVT VT1 = Val.getValueType();
229 if (Val.getOpcode() == ISD::LOAD && VT1.isSimple() && VT2.isSimple()) {
230 MVT MT1 = VT1.getSimpleVT().SimpleTy;
231 MVT MT2 = VT2.getSimpleVT().SimpleTy;
232 if ((MT1 == MVT::i8 || MT1 == MVT::i16 || MT1 == MVT::i32) &&
233 (MT2 == MVT::i32 || MT2 == MVT::i64))
234 return true;
235 }
236 return TargetLoweringBase::isZExtFree(Val, VT2);
237}
238
241 if (Constraint.size() == 1) {
242 switch (Constraint[0]) {
243 default:
244 break;
245 case 'w':
246 return C_RegisterClass;
247 }
248 }
249
250 return TargetLowering::getConstraintType(Constraint);
251}
252
253std::pair<unsigned, const TargetRegisterClass *>
255 StringRef Constraint,
256 MVT VT) const {
257 if (Constraint.size() == 1) {
258 // GCC Constraint Letters
259 switch (Constraint[0]) {
260 case 'r': // GENERAL_REGS
261 return std::make_pair(0U, &BPF::GPRRegClass);
262 case 'w':
263 if (HasAlu32)
264 return std::make_pair(0U, &BPF::GPR32RegClass);
265 break;
266 default:
267 break;
268 }
269 }
270
272}
273
274void BPFTargetLowering::ReplaceNodeResults(
276 const char *Msg;
277 uint32_t Opcode = N->getOpcode();
278 switch (Opcode) {
279 default:
280 report_fatal_error("unhandled custom legalization: " + Twine(Opcode));
285 case ISD::ATOMIC_SWAP:
287 if (HasAlu32 || Opcode == ISD::ATOMIC_LOAD_ADD)
288 Msg = "unsupported atomic operation, please use 32/64 bit version";
289 else
290 Msg = "unsupported atomic operation, please use 64 bit version";
291 break;
292 }
293
294 SDLoc DL(N);
295 // We'll still produce a fatal error downstream, but this diagnostic is more
296 // user-friendly.
297 fail(DL, DAG, Msg);
298}
299
301 switch (Op.getOpcode()) {
302 default:
303 report_fatal_error("unimplemented opcode: " + Twine(Op.getOpcode()));
304 case ISD::BR_CC:
305 return LowerBR_CC(Op, DAG);
307 return LowerGlobalAddress(Op, DAG);
308 case ISD::SELECT_CC:
309 return LowerSELECT_CC(Op, DAG);
311 report_fatal_error("unsupported dynamic stack allocation");
312 }
313}
314
315// Calling Convention Implementation
316#include "BPFGenCallingConv.inc"
317
318SDValue BPFTargetLowering::LowerFormalArguments(
319 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
320 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
321 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
322 switch (CallConv) {
323 default:
324 report_fatal_error("unimplemented calling convention: " + Twine(CallConv));
325 case CallingConv::C:
327 break;
328 }
329
332
333 // Assign locations to all of the incoming arguments.
335 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
336 CCInfo.AnalyzeFormalArguments(Ins, getHasAlu32() ? CC_BPF32 : CC_BPF64);
337
338 bool HasMemArgs = false;
339 for (size_t I = 0; I < ArgLocs.size(); ++I) {
340 auto &VA = ArgLocs[I];
341
342 if (VA.isRegLoc()) {
343 // Arguments passed in registers
344 EVT RegVT = VA.getLocVT();
345 MVT::SimpleValueType SimpleTy = RegVT.getSimpleVT().SimpleTy;
346 switch (SimpleTy) {
347 default: {
348 std::string Str;
349 {
351 RegVT.print(OS);
352 }
353 report_fatal_error("unhandled argument type: " + Twine(Str));
354 }
355 case MVT::i32:
356 case MVT::i64:
357 Register VReg = RegInfo.createVirtualRegister(
358 SimpleTy == MVT::i64 ? &BPF::GPRRegClass : &BPF::GPR32RegClass);
359 RegInfo.addLiveIn(VA.getLocReg(), VReg);
360 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
361
362 // If this is an value that has been promoted to wider types, insert an
363 // assert[sz]ext to capture this, then truncate to the right size.
364 if (VA.getLocInfo() == CCValAssign::SExt)
365 ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
366 DAG.getValueType(VA.getValVT()));
367 else if (VA.getLocInfo() == CCValAssign::ZExt)
368 ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
369 DAG.getValueType(VA.getValVT()));
370
371 if (VA.getLocInfo() != CCValAssign::Full)
372 ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
373
374 InVals.push_back(ArgValue);
375
376 break;
377 }
378 } else {
379 if (VA.isMemLoc())
380 HasMemArgs = true;
381 else
382 report_fatal_error("unhandled argument location");
383 InVals.push_back(DAG.getConstant(0, DL, VA.getLocVT()));
384 }
385 }
386 if (HasMemArgs)
387 fail(DL, DAG, "stack arguments are not supported");
388 if (IsVarArg)
389 fail(DL, DAG, "variadic functions are not supported");
390 if (MF.getFunction().hasStructRetAttr())
391 fail(DL, DAG, "aggregate returns are not supported");
392
393 return Chain;
394}
395
396const size_t BPFTargetLowering::MaxArgs = 5;
397
398SDValue BPFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
399 SmallVectorImpl<SDValue> &InVals) const {
400 SelectionDAG &DAG = CLI.DAG;
401 auto &Outs = CLI.Outs;
402 auto &OutVals = CLI.OutVals;
403 auto &Ins = CLI.Ins;
404 SDValue Chain = CLI.Chain;
405 SDValue Callee = CLI.Callee;
406 bool &IsTailCall = CLI.IsTailCall;
407 CallingConv::ID CallConv = CLI.CallConv;
408 bool IsVarArg = CLI.IsVarArg;
410
411 // BPF target does not support tail call optimization.
412 IsTailCall = false;
413
414 switch (CallConv) {
415 default:
416 report_fatal_error("unsupported calling convention: " + Twine(CallConv));
418 case CallingConv::C:
419 break;
420 }
421
422 // Analyze operands of the call, assigning locations to each operand.
424 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
425
426 CCInfo.AnalyzeCallOperands(Outs, getHasAlu32() ? CC_BPF32 : CC_BPF64);
427
428 unsigned NumBytes = CCInfo.getStackSize();
429
430 if (Outs.size() > MaxArgs)
431 fail(CLI.DL, DAG, "too many arguments", Callee);
432
433 for (auto &Arg : Outs) {
434 ISD::ArgFlagsTy Flags = Arg.Flags;
435 if (!Flags.isByVal())
436 continue;
437 fail(CLI.DL, DAG, "pass by value not supported", Callee);
438 break;
439 }
440
441 auto PtrVT = getPointerTy(MF.getDataLayout());
442 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
443
444 SmallVector<std::pair<unsigned, SDValue>, MaxArgs> RegsToPass;
445
446 // Walk arg assignments
447 for (size_t i = 0; i < std::min(ArgLocs.size(), MaxArgs); ++i) {
448 CCValAssign &VA = ArgLocs[i];
449 SDValue &Arg = OutVals[i];
450
451 // Promote the value if needed.
452 switch (VA.getLocInfo()) {
453 default:
454 report_fatal_error("unhandled location info: " + Twine(VA.getLocInfo()));
456 break;
458 Arg = DAG.getNode(ISD::SIGN_EXTEND, CLI.DL, VA.getLocVT(), Arg);
459 break;
461 Arg = DAG.getNode(ISD::ZERO_EXTEND, CLI.DL, VA.getLocVT(), Arg);
462 break;
464 Arg = DAG.getNode(ISD::ANY_EXTEND, CLI.DL, VA.getLocVT(), Arg);
465 break;
466 }
467
468 // Push arguments into RegsToPass vector
469 if (VA.isRegLoc())
470 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
471 else
472 report_fatal_error("stack arguments are not supported");
473 }
474
475 SDValue InGlue;
476
477 // Build a sequence of copy-to-reg nodes chained together with token chain and
478 // flag operands which copy the outgoing args into registers. The InGlue in
479 // necessary since all emitted instructions must be stuck together.
480 for (auto &Reg : RegsToPass) {
481 Chain = DAG.getCopyToReg(Chain, CLI.DL, Reg.first, Reg.second, InGlue);
482 InGlue = Chain.getValue(1);
483 }
484
485 // If the callee is a GlobalAddress node (quite common, every direct call is)
486 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
487 // Likewise ExternalSymbol -> TargetExternalSymbol.
488 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
489 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), CLI.DL, PtrVT,
490 G->getOffset(), 0);
491 } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
492 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
493 fail(CLI.DL, DAG,
494 Twine("A call to built-in function '" + StringRef(E->getSymbol()) +
495 "' is not supported."));
496 }
497
498 // Returns a chain & a flag for retval copy to use.
499 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
501 Ops.push_back(Chain);
502 Ops.push_back(Callee);
503
504 // Add argument registers to the end of the list so that they are
505 // known live into the call.
506 for (auto &Reg : RegsToPass)
507 Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
508
509 if (InGlue.getNode())
510 Ops.push_back(InGlue);
511
512 Chain = DAG.getNode(BPFISD::CALL, CLI.DL, NodeTys, Ops);
513 InGlue = Chain.getValue(1);
514
515 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
516
517 // Create the CALLSEQ_END node.
518 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, CLI.DL);
519 InGlue = Chain.getValue(1);
520
521 // Handle result values, copying them out of physregs into vregs that we
522 // return.
523 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, CLI.DL, DAG,
524 InVals);
525}
526
528BPFTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
529 bool IsVarArg,
531 const SmallVectorImpl<SDValue> &OutVals,
532 const SDLoc &DL, SelectionDAG &DAG) const {
533 unsigned Opc = BPFISD::RET_GLUE;
534
535 // CCValAssign - represent the assignment of the return value to a location
538
539 // CCState - Info about the registers and stack slot.
540 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
541
543 fail(DL, DAG, "aggregate returns are not supported");
544 return DAG.getNode(Opc, DL, MVT::Other, Chain);
545 }
546
547 // Analize return values.
548 CCInfo.AnalyzeReturn(Outs, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
549
550 SDValue Glue;
551 SmallVector<SDValue, 4> RetOps(1, Chain);
552
553 // Copy the result values into the output registers.
554 for (size_t i = 0; i != RVLocs.size(); ++i) {
555 CCValAssign &VA = RVLocs[i];
556 if (!VA.isRegLoc())
557 report_fatal_error("stack return values are not supported");
558
559 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Glue);
560
561 // Guarantee that all emitted copies are stuck together,
562 // avoiding something bad.
563 Glue = Chain.getValue(1);
564 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
565 }
566
567 RetOps[0] = Chain; // Update chain.
568
569 // Add the glue if we have it.
570 if (Glue.getNode())
571 RetOps.push_back(Glue);
572
573 return DAG.getNode(Opc, DL, MVT::Other, RetOps);
574}
575
576SDValue BPFTargetLowering::LowerCallResult(
577 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
578 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
579 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
580
582 // Assign locations to each value returned by this call.
584 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
585
586 if (Ins.size() > 1) {
587 fail(DL, DAG, "only small returns supported");
588 for (auto &In : Ins)
589 InVals.push_back(DAG.getConstant(0, DL, In.VT));
590 return DAG.getCopyFromReg(Chain, DL, 1, Ins[0].VT, InGlue).getValue(1);
591 }
592
593 CCInfo.AnalyzeCallResult(Ins, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
594
595 // Copy all of the result registers out of their specified physreg.
596 for (auto &Val : RVLocs) {
597 Chain = DAG.getCopyFromReg(Chain, DL, Val.getLocReg(),
598 Val.getValVT(), InGlue).getValue(1);
599 InGlue = Chain.getValue(2);
600 InVals.push_back(Chain.getValue(0));
601 }
602
603 return Chain;
604}
605
606static void NegateCC(SDValue &LHS, SDValue &RHS, ISD::CondCode &CC) {
607 switch (CC) {
608 default:
609 break;
610 case ISD::SETULT:
611 case ISD::SETULE:
612 case ISD::SETLT:
613 case ISD::SETLE:
615 std::swap(LHS, RHS);
616 break;
617 }
618}
619
620SDValue BPFTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
621 SDValue Chain = Op.getOperand(0);
622 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
623 SDValue LHS = Op.getOperand(2);
624 SDValue RHS = Op.getOperand(3);
625 SDValue Dest = Op.getOperand(4);
626 SDLoc DL(Op);
627
628 if (!getHasJmpExt())
629 NegateCC(LHS, RHS, CC);
630
631 return DAG.getNode(BPFISD::BR_CC, DL, Op.getValueType(), Chain, LHS, RHS,
632 DAG.getConstant(CC, DL, LHS.getValueType()), Dest);
633}
634
635SDValue BPFTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
636 SDValue LHS = Op.getOperand(0);
637 SDValue RHS = Op.getOperand(1);
638 SDValue TrueV = Op.getOperand(2);
639 SDValue FalseV = Op.getOperand(3);
640 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
641 SDLoc DL(Op);
642
643 if (!getHasJmpExt())
644 NegateCC(LHS, RHS, CC);
645
646 SDValue TargetCC = DAG.getConstant(CC, DL, LHS.getValueType());
647 SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
648 SDValue Ops[] = {LHS, RHS, TargetCC, TrueV, FalseV};
649
650 return DAG.getNode(BPFISD::SELECT_CC, DL, VTs, Ops);
651}
652
653const char *BPFTargetLowering::getTargetNodeName(unsigned Opcode) const {
654 switch ((BPFISD::NodeType)Opcode) {
656 break;
657 case BPFISD::RET_GLUE:
658 return "BPFISD::RET_GLUE";
659 case BPFISD::CALL:
660 return "BPFISD::CALL";
662 return "BPFISD::SELECT_CC";
663 case BPFISD::BR_CC:
664 return "BPFISD::BR_CC";
665 case BPFISD::Wrapper:
666 return "BPFISD::Wrapper";
667 case BPFISD::MEMCPY:
668 return "BPFISD::MEMCPY";
669 }
670 return nullptr;
671}
672
673SDValue BPFTargetLowering::LowerGlobalAddress(SDValue Op,
674 SelectionDAG &DAG) const {
675 auto *N = cast<GlobalAddressSDNode>(Op);
676 if (N->getOffset() != 0)
677 report_fatal_error("invalid offset for global address: " +
678 Twine(N->getOffset()));
679
680 SDLoc DL(Op);
681 const GlobalValue *GV = N->getGlobal();
682 SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i64);
683
684 return DAG.getNode(BPFISD::Wrapper, DL, MVT::i64, GA);
685}
686
687unsigned
688BPFTargetLowering::EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB,
689 unsigned Reg, bool isSigned) const {
691 const TargetRegisterClass *RC = getRegClassFor(MVT::i64);
692 int RShiftOp = isSigned ? BPF::SRA_ri : BPF::SRL_ri;
693 MachineFunction *F = BB->getParent();
694 DebugLoc DL = MI.getDebugLoc();
695
696 MachineRegisterInfo &RegInfo = F->getRegInfo();
697
698 if (!isSigned) {
699 Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
700 BuildMI(BB, DL, TII.get(BPF::MOV_32_64), PromotedReg0).addReg(Reg);
701 return PromotedReg0;
702 }
703 Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
704 Register PromotedReg1 = RegInfo.createVirtualRegister(RC);
705 Register PromotedReg2 = RegInfo.createVirtualRegister(RC);
706 if (HasMovsx) {
707 BuildMI(BB, DL, TII.get(BPF::MOVSX_rr_32), PromotedReg0).addReg(Reg);
708 } else {
709 BuildMI(BB, DL, TII.get(BPF::MOV_32_64), PromotedReg0).addReg(Reg);
710 BuildMI(BB, DL, TII.get(BPF::SLL_ri), PromotedReg1)
711 .addReg(PromotedReg0).addImm(32);
712 BuildMI(BB, DL, TII.get(RShiftOp), PromotedReg2)
713 .addReg(PromotedReg1).addImm(32);
714 }
715
716 return PromotedReg2;
717}
718
720BPFTargetLowering::EmitInstrWithCustomInserterMemcpy(MachineInstr &MI,
722 const {
723 MachineFunction *MF = MI.getParent()->getParent();
725 MachineInstrBuilder MIB(*MF, MI);
726 unsigned ScratchReg;
727
728 // This function does custom insertion during lowering BPFISD::MEMCPY which
729 // only has two register operands from memcpy semantics, the copy source
730 // address and the copy destination address.
731 //
732 // Because we will expand BPFISD::MEMCPY into load/store pairs, we will need
733 // a third scratch register to serve as the destination register of load and
734 // source register of store.
735 //
736 // The scratch register here is with the Define | Dead | EarlyClobber flags.
737 // The EarlyClobber flag has the semantic property that the operand it is
738 // attached to is clobbered before the rest of the inputs are read. Hence it
739 // must be unique among the operands to the instruction. The Define flag is
740 // needed to coerce the machine verifier that an Undef value isn't a problem
741 // as we anyway is loading memory into it. The Dead flag is needed as the
742 // value in scratch isn't supposed to be used by any other instruction.
743 ScratchReg = MRI.createVirtualRegister(&BPF::GPRRegClass);
744 MIB.addReg(ScratchReg,
746
747 return BB;
748}
749
752 MachineBasicBlock *BB) const {
754 DebugLoc DL = MI.getDebugLoc();
755 unsigned Opc = MI.getOpcode();
756 bool isSelectRROp = (Opc == BPF::Select ||
757 Opc == BPF::Select_64_32 ||
758 Opc == BPF::Select_32 ||
759 Opc == BPF::Select_32_64);
760
761 bool isMemcpyOp = Opc == BPF::MEMCPY;
762
763#ifndef NDEBUG
764 bool isSelectRIOp = (Opc == BPF::Select_Ri ||
765 Opc == BPF::Select_Ri_64_32 ||
766 Opc == BPF::Select_Ri_32 ||
767 Opc == BPF::Select_Ri_32_64);
768
769 if (!(isSelectRROp || isSelectRIOp || isMemcpyOp))
770 report_fatal_error("unhandled instruction type: " + Twine(Opc));
771#endif
772
773 if (isMemcpyOp)
774 return EmitInstrWithCustomInserterMemcpy(MI, BB);
775
776 bool is32BitCmp = (Opc == BPF::Select_32 ||
777 Opc == BPF::Select_32_64 ||
778 Opc == BPF::Select_Ri_32 ||
779 Opc == BPF::Select_Ri_32_64);
780
781 // To "insert" a SELECT instruction, we actually have to insert the diamond
782 // control-flow pattern. The incoming instruction knows the destination vreg
783 // to set, the condition code register to branch on, the true/false values to
784 // select between, and a branch opcode to use.
785 const BasicBlock *LLVM_BB = BB->getBasicBlock();
787
788 // ThisMBB:
789 // ...
790 // TrueVal = ...
791 // jmp_XX r1, r2 goto Copy1MBB
792 // fallthrough --> Copy0MBB
793 MachineBasicBlock *ThisMBB = BB;
794 MachineFunction *F = BB->getParent();
795 MachineBasicBlock *Copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
796 MachineBasicBlock *Copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
797
798 F->insert(I, Copy0MBB);
799 F->insert(I, Copy1MBB);
800 // Update machine-CFG edges by transferring all successors of the current
801 // block to the new block which will contain the Phi node for the select.
802 Copy1MBB->splice(Copy1MBB->begin(), BB,
803 std::next(MachineBasicBlock::iterator(MI)), BB->end());
805 // Next, add the true and fallthrough blocks as its successors.
806 BB->addSuccessor(Copy0MBB);
807 BB->addSuccessor(Copy1MBB);
808
809 // Insert Branch if Flag
810 int CC = MI.getOperand(3).getImm();
811 int NewCC;
812 switch (CC) {
813#define SET_NEWCC(X, Y) \
814 case ISD::X: \
815 if (is32BitCmp && HasJmp32) \
816 NewCC = isSelectRROp ? BPF::Y##_rr_32 : BPF::Y##_ri_32; \
817 else \
818 NewCC = isSelectRROp ? BPF::Y##_rr : BPF::Y##_ri; \
819 break
820 SET_NEWCC(SETGT, JSGT);
821 SET_NEWCC(SETUGT, JUGT);
822 SET_NEWCC(SETGE, JSGE);
823 SET_NEWCC(SETUGE, JUGE);
824 SET_NEWCC(SETEQ, JEQ);
825 SET_NEWCC(SETNE, JNE);
826 SET_NEWCC(SETLT, JSLT);
827 SET_NEWCC(SETULT, JULT);
828 SET_NEWCC(SETLE, JSLE);
829 SET_NEWCC(SETULE, JULE);
830 default:
831 report_fatal_error("unimplemented select CondCode " + Twine(CC));
832 }
833
834 Register LHS = MI.getOperand(1).getReg();
835 bool isSignedCmp = (CC == ISD::SETGT ||
836 CC == ISD::SETGE ||
837 CC == ISD::SETLT ||
838 CC == ISD::SETLE);
839
840 // eBPF at the moment only has 64-bit comparison. Any 32-bit comparison need
841 // to be promoted, however if the 32-bit comparison operands are destination
842 // registers then they are implicitly zero-extended already, there is no
843 // need of explicit zero-extend sequence for them.
844 //
845 // We simply do extension for all situations in this method, but we will
846 // try to remove those unnecessary in BPFMIPeephole pass.
847 if (is32BitCmp && !HasJmp32)
848 LHS = EmitSubregExt(MI, BB, LHS, isSignedCmp);
849
850 if (isSelectRROp) {
851 Register RHS = MI.getOperand(2).getReg();
852
853 if (is32BitCmp && !HasJmp32)
854 RHS = EmitSubregExt(MI, BB, RHS, isSignedCmp);
855
856 BuildMI(BB, DL, TII.get(NewCC)).addReg(LHS).addReg(RHS).addMBB(Copy1MBB);
857 } else {
858 int64_t imm32 = MI.getOperand(2).getImm();
859 // Check before we build J*_ri instruction.
860 if (!isInt<32>(imm32))
861 report_fatal_error("immediate overflows 32 bits: " + Twine(imm32));
862 BuildMI(BB, DL, TII.get(NewCC))
863 .addReg(LHS).addImm(imm32).addMBB(Copy1MBB);
864 }
865
866 // Copy0MBB:
867 // %FalseValue = ...
868 // # fallthrough to Copy1MBB
869 BB = Copy0MBB;
870
871 // Update machine-CFG edges
872 BB->addSuccessor(Copy1MBB);
873
874 // Copy1MBB:
875 // %Result = phi [ %FalseValue, Copy0MBB ], [ %TrueValue, ThisMBB ]
876 // ...
877 BB = Copy1MBB;
878 BuildMI(*BB, BB->begin(), DL, TII.get(BPF::PHI), MI.getOperand(0).getReg())
879 .addReg(MI.getOperand(5).getReg())
880 .addMBB(Copy0MBB)
881 .addReg(MI.getOperand(4).getReg())
882 .addMBB(ThisMBB);
883
884 MI.eraseFromParent(); // The pseudo instruction is gone now.
885 return BB;
886}
887
889 EVT VT) const {
890 return getHasAlu32() ? MVT::i32 : MVT::i64;
891}
892
894 EVT VT) const {
895 return (getHasAlu32() && VT == MVT::i32) ? MVT::i32 : MVT::i64;
896}
897
898bool BPFTargetLowering::isLegalAddressingMode(const DataLayout &DL,
899 const AddrMode &AM, Type *Ty,
900 unsigned AS,
901 Instruction *I) const {
902 // No global is ever allowed as a base.
903 if (AM.BaseGV)
904 return false;
905
906 switch (AM.Scale) {
907 case 0: // "r+i" or just "i", depending on HasBaseReg.
908 break;
909 case 1:
910 if (!AM.HasBaseReg) // allow "r+i".
911 break;
912 return false; // disallow "r+r" or "r+r+i".
913 default:
914 return false;
915 }
916
917 return true;
918}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
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 GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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:80
bool getHasJmpExt() const
Definition: BPFSubtarget.h:73
const BPFSelectionDAGInfo * getSelectionDAGInfo() const override
Definition: BPFSubtarget.h:91
const TargetRegisterInfo * getRegisterInfo() const override
Definition: BPFSubtarget.h:94
bool hasLdsx() const
Definition: BPFSubtarget.h:77
bool hasMovsx() const
Definition: BPFSubtarget.h:78
bool getHasJmp32() const
Definition: BPFSubtarget.h:74
bool getHasAlu32() const
Definition: BPFSubtarget.h:75
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:56
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:628
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:181
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:68
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:720
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 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:771
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:797
LLVMContext * getContext() const
Definition: SelectionDAG.h:485
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
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:577
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
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 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:78
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:82
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:642
@ 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:1121
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1117
@ 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:1026
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:780
@ 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:1243
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:255
@ ATOMIC_LOAD_OR
Definition: ISDOpcodes.h:1256
@ ATOMIC_LOAD_XOR
Definition: ISDOpcodes.h:1257
@ 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:1072
@ BRIND
BRIND - Indirect branch.
Definition: ISDOpcodes.h:1047
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1051
@ 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:1254
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:777
@ 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:1036
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:795
@ ATOMIC_LOAD_ADD
Definition: ISDOpcodes.h:1252
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
Definition: ISDOpcodes.h:1251
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:783
@ BRCOND
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:1065
@ 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:1503
@ 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:445
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:1186
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:129
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:351
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:299
void print(raw_ostream &OS) const
Implement operator<<.
Definition: ValueTypes.h:474
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: ValueTypes.h:144
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