LLVM 24.0.0git
BPFISelDAGToDAG.cpp
Go to the documentation of this file.
1//===-- BPFISelDAGToDAG.cpp - A dag to dag inst selector for BPF ----------===//
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 a DAG pattern matching instruction selector for BPF,
10// converting from a legalized dag to a BPF dag.
11//
12//===----------------------------------------------------------------------===//
13
14#include "BPF.h"
15#include "BPFSubtarget.h"
16#include "BPFTargetMachine.h"
22#include "llvm/IR/Constants.h"
24#include "llvm/IR/IntrinsicsBPF.h"
25#include "llvm/Support/Debug.h"
26#include "llvm/Support/Endian.h"
29
30using namespace llvm;
31
32#define DEBUG_TYPE "bpf-isel"
33#define PASS_NAME "BPF DAG->DAG Pattern Instruction Selection"
34
35// Instruction Selector Implementation
36namespace {
37
38class BPFDAGToDAGISel : public SelectionDAGISel {
39
40 /// Subtarget - Keep a pointer to the BPFSubtarget around so that we can
41 /// make the right decision when generating code for different subtargets.
43
44public:
45 BPFDAGToDAGISel() = delete;
46
47 explicit BPFDAGToDAGISel(BPFTargetMachine &TM)
48 : SelectionDAGISel(TM), Subtarget(nullptr) {}
49
50 bool runOnMachineFunction(MachineFunction &MF) override {
51 // Reset the subtarget each time through.
54 }
55
56 void PreprocessISelDAG() override;
57
58 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
59 InlineAsm::ConstraintCode ConstraintCode,
60 std::vector<SDValue> &OutOps) override;
61
62private:
63// Include the pieces autogenerated from the target description.
64#include "BPFGenDAGISel.inc"
65
66 void Select(SDNode *N) override;
67
68 // Complex Pattern for address selection.
70 bool SelectFIAddr(SDValue Addr, SDValue &Base, SDValue &Offset);
71
72 // Node preprocessing cases
73 void PreprocessLoad(SDNode *Node, SelectionDAG::allnodes_iterator &I);
74 void PreprocessTrunc(SDNode *Node, SelectionDAG::allnodes_iterator &I);
75
76 // Find constants from a constant structure
77 typedef std::vector<unsigned char> val_vec_type;
78 bool fillGenericConstant(const DataLayout &DL, const Constant *CV,
79 val_vec_type &Vals, uint64_t Offset);
80 bool fillConstantDataArray(const DataLayout &DL, const ConstantDataArray *CDA,
81 val_vec_type &Vals, int Offset);
82 bool fillConstantArray(const DataLayout &DL, const ConstantArray *CA,
83 val_vec_type &Vals, int Offset);
84 bool fillConstantStruct(const DataLayout &DL, const ConstantStruct *CS,
85 val_vec_type &Vals, int Offset);
86 bool getConstantFieldValue(const GlobalAddressSDNode *Node, uint64_t Offset,
87 uint64_t Size, unsigned char *ByteSeq);
88 // Mapping from ConstantStruct global value to corresponding byte-list values
89 std::map<const void *, val_vec_type> cs_vals_;
90};
91
92class BPFDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
93public:
94 static char ID;
95 BPFDAGToDAGISelLegacy(BPFTargetMachine &TM)
96 : SelectionDAGISelLegacy(ID, std::make_unique<BPFDAGToDAGISel>(TM)) {}
97};
98} // namespace
99
100char BPFDAGToDAGISelLegacy::ID = 0;
101
102INITIALIZE_PASS(BPFDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false)
103
104// ComplexPattern used on BPF Load/Store instructions
105bool BPFDAGToDAGISel::SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) {
106 // if Address is FI, get the TargetFrameIndex.
107 SDLoc DL(Addr);
108 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
109 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64);
110 Offset = CurDAG->getTargetConstant(0, DL, MVT::i64);
111 return true;
112 }
113
114 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
115 Addr.getOpcode() == ISD::TargetGlobalAddress)
116 return false;
117
118 // Addresses of the form Addr+const or Addr|const
119 if (CurDAG->isBaseWithConstantOffset(Addr)) {
120 auto *CN = cast<ConstantSDNode>(Addr.getOperand(1));
121 if (isInt<16>(CN->getSExtValue())) {
122 // If the first operand is a FI, get the TargetFI Node
123 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
124 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64);
125 else
126 Base = Addr.getOperand(0);
127
128 Offset = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i64);
129 return true;
130 }
131 }
132
133 Base = Addr;
134 Offset = CurDAG->getTargetConstant(0, DL, MVT::i64);
135 return true;
136}
137
138// ComplexPattern used on BPF FI instruction
139bool BPFDAGToDAGISel::SelectFIAddr(SDValue Addr, SDValue &Base,
140 SDValue &Offset) {
141 SDLoc DL(Addr);
142
143 if (!CurDAG->isBaseWithConstantOffset(Addr))
144 return false;
145
146 // Addresses of the form Addr+const or Addr|const
147 auto *CN = cast<ConstantSDNode>(Addr.getOperand(1));
148 if (isInt<16>(CN->getSExtValue())) {
149 // If the first operand is a FI, get the TargetFI Node
150 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
151 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64);
152 else
153 return false;
154
155 Offset = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i64);
156 return true;
157 }
158
159 return false;
160}
161
162bool BPFDAGToDAGISel::SelectInlineAsmMemoryOperand(
163 const SDValue &Op, InlineAsm::ConstraintCode ConstraintCode,
164 std::vector<SDValue> &OutOps) {
165 SDValue Op0, Op1;
166 switch (ConstraintCode) {
167 default:
168 return true;
169 case InlineAsm::ConstraintCode::m: // memory
170 if (!SelectAddr(Op, Op0, Op1))
171 return true;
172 break;
173 }
174
175 SDLoc DL(Op);
176 SDValue AluOp = CurDAG->getTargetConstant(ISD::ADD, DL, MVT::i32);
177 OutOps.push_back(Op0);
178 OutOps.push_back(Op1);
179 OutOps.push_back(AluOp);
180 return false;
181}
182
183void BPFDAGToDAGISel::Select(SDNode *Node) {
184 unsigned Opcode = Node->getOpcode();
185
186 // If we have a custom node, we already have selected!
187 if (Node->isMachineOpcode()) {
188 LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << '\n');
189 return;
190 }
191
192 // tablegen selection should be handled here.
193 switch (Opcode) {
194 default:
195 break;
196 case ISD::POISON:
197 case ISD::UNDEF: {
198 // IMPLICIT_DEF leaves the register as it is. The verifier rejects a read
199 // of a register that was not written, no matter what is done with the
200 // value.
201 EVT VT = Node->getValueType(0);
202 if (VT != MVT::i64 && VT != MVT::i32)
203 break;
204 CurDAG->SelectNodeTo(Node, VT == MVT::i64 ? BPF::MOV_ri : BPF::MOV_ri_32,
205 VT, CurDAG->getTargetConstant(0, SDLoc(Node), VT));
206 return;
207 }
208
209 case BPFISD::LOAD_STACK_ARG: {
210 SDValue Chain = Node->getOperand(0);
211 auto *CN = cast<ConstantSDNode>(Node->getOperand(1));
212 SDValue Off =
213 CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Node), MVT::i64);
214 EVT ValVT = Node->getValueType(0);
215 CurDAG->SelectNodeTo(Node, BPF::LOAD_STACK_ARG_PSEUDO, ValVT, MVT::Other,
216 Off, Chain);
217 return;
218 }
219
220 case BPFISD::STORE_STACK_ARG: {
221 SDValue Chain = Node->getOperand(0);
222 auto *CN = cast<ConstantSDNode>(Node->getOperand(1));
223 SDValue Off =
224 CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Node), MVT::i64);
225 SDValue Val = Node->getOperand(2);
226
227 // Use store-immediate when the value is a constant that fits in 32 bits.
228 if (auto *ValCN = dyn_cast<ConstantSDNode>(Val);
229 ValCN && Subtarget->hasStoreImm() && isInt<32>(ValCN->getSExtValue())) {
230 SDValue Imm = CurDAG->getTargetConstant(ValCN->getSExtValue(),
231 SDLoc(Node), MVT::i64);
232 CurDAG->SelectNodeTo(Node, BPF::STORE_STACK_ARG_IMM_PSEUDO, MVT::Other,
233 Off, Imm, Chain);
234 } else {
235 CurDAG->SelectNodeTo(Node, BPF::STORE_STACK_ARG_PSEUDO, MVT::Other, Off,
236 Val, Chain);
237 }
238 return;
239 }
240
241 case ISD::FrameIndex: {
242 int FI = cast<FrameIndexSDNode>(Node)->getIndex();
243 EVT VT = Node->getValueType(0);
244 SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
245 unsigned Opc = BPF::MOV_rr;
246 if (Node->hasOneUse()) {
247 CurDAG->SelectNodeTo(Node, Opc, VT, TFI);
248 return;
249 }
250 ReplaceNode(Node, CurDAG->getMachineNode(Opc, SDLoc(Node), VT, TFI));
251 return;
252 }
253 }
254
255 // Select the default instruction
256 SelectCode(Node);
257}
258
259void BPFDAGToDAGISel::PreprocessLoad(SDNode *Node,
261 union {
262 uint8_t c[8];
263 uint16_t s;
264 uint32_t i;
265 uint64_t d;
266 } new_val; // hold up the constant values replacing loads.
267 bool to_replace = false;
268 SDLoc DL(Node);
269 const LoadSDNode *LD = cast<LoadSDNode>(Node);
270 if (!LD->getMemOperand()->getSize().hasValue())
271 return;
272 uint64_t size = LD->getMemOperand()->getSize().getValue();
273
274 if (!size || size > 8 || (size & (size - 1)) || !LD->isSimple())
275 return;
276
277 SDNode *LDAddrNode = LD->getOperand(1).getNode();
278 // Match LDAddr against either global_addr or (global_addr + offset)
279 unsigned opcode = LDAddrNode->getOpcode();
280 if (opcode == ISD::ADD) {
281 SDValue OP1 = LDAddrNode->getOperand(0);
282 SDValue OP2 = LDAddrNode->getOperand(1);
283
284 // We want to find the pattern global_addr + offset
285 SDNode *OP1N = OP1.getNode();
286 if (OP1N->getOpcode() <= ISD::BUILTIN_OP_END || OP1N->getNumOperands() == 0)
287 return;
288
289 LLVM_DEBUG(dbgs() << "Check candidate load: "; LD->dump(); dbgs() << '\n');
290
291 const GlobalAddressSDNode *GADN =
293 const ConstantSDNode *CDN = dyn_cast<ConstantSDNode>(OP2.getNode());
294 if (GADN && CDN)
295 to_replace =
296 getConstantFieldValue(GADN, CDN->getZExtValue(), size, new_val.c);
297 } else if (LDAddrNode->getOpcode() > ISD::BUILTIN_OP_END &&
298 LDAddrNode->getNumOperands() > 0) {
299 LLVM_DEBUG(dbgs() << "Check candidate load: "; LD->dump(); dbgs() << '\n');
300
301 SDValue OP1 = LDAddrNode->getOperand(0);
302 if (const GlobalAddressSDNode *GADN =
304 to_replace = getConstantFieldValue(GADN, 0, size, new_val.c);
305 }
306
307 if (!to_replace)
308 return;
309
310 // replacing the old with a new value
311 uint64_t val;
312 if (size == 1)
313 val = new_val.c[0];
314 else if (size == 2)
315 val = new_val.s;
316 else if (size == 4)
317 val = new_val.i;
318 else {
319 val = new_val.d;
320 }
321
322 LLVM_DEBUG(dbgs() << "Replacing load of size " << size << " with constant "
323 << val << '\n');
324 EVT VT = LD->getValueType(0);
325 APInt MemVal(size * 8, val);
326 SDValue NVal = CurDAG->getConstant(LD->getExtensionType() == ISD::SEXTLOAD
327 ? MemVal.sext(VT.getSizeInBits())
328 : MemVal.zext(VT.getSizeInBits()),
329 DL, VT);
330
331 // After replacement, the current node is dead, we need to
332 // go backward one step to make iterator still work
333 I--;
334 SDValue From[] = {SDValue(Node, 0), SDValue(Node, 1)};
335 SDValue To[] = {NVal, NVal};
336 CurDAG->ReplaceAllUsesOfValuesWith(From, To, 2);
337 I++;
338 // It is safe to delete node now
339 CurDAG->DeleteNode(Node);
340}
341
342void BPFDAGToDAGISel::PreprocessISelDAG() {
343 // Iterate through all nodes, interested in the following case:
344 //
345 // . loads from ConstantStruct or ConstantArray of constructs
346 // which can be turns into constant itself, with this we can
347 // avoid reading from read-only section at runtime.
348 //
349 // . Removing redundant AND for intrinsic narrow loads.
350 for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
351 E = CurDAG->allnodes_end();
352 I != E;) {
353 SDNode *Node = &*I++;
354 unsigned Opcode = Node->getOpcode();
355 if (Opcode == ISD::LOAD)
356 PreprocessLoad(Node, I);
357 else if (Opcode == ISD::AND)
358 PreprocessTrunc(Node, I);
359 }
360}
361
362bool BPFDAGToDAGISel::getConstantFieldValue(const GlobalAddressSDNode *Node,
364 unsigned char *ByteSeq) {
365 const GlobalVariable *V = dyn_cast<GlobalVariable>(Node->getGlobal());
366
367 if (!V || !V->hasInitializer() || !V->isConstant())
368 return false;
369
370 const Constant *Init = V->getInitializer();
371 const DataLayout &DL = CurDAG->getDataLayout();
372 val_vec_type TmpVal;
373
374 auto it = cs_vals_.find(static_cast<const void *>(Init));
375 if (it != cs_vals_.end()) {
376 TmpVal = it->second;
377 } else {
378 uint64_t total_size = 0;
379 if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(Init))
380 total_size =
381 DL.getStructLayout(cast<StructType>(CS->getType()))->getSizeInBytes();
382 else if (const ConstantArray *CA = dyn_cast<ConstantArray>(Init))
383 total_size = DL.getTypeAllocSize(CA->getType()->getElementType()) *
384 CA->getNumOperands();
385 else
386 return false;
387
388 val_vec_type Vals(total_size, 0);
389 if (fillGenericConstant(DL, Init, Vals, 0) == false)
390 return false;
391 cs_vals_[static_cast<const void *>(Init)] = Vals;
392 TmpVal = std::move(Vals);
393 }
394
395 // test whether host endianness matches target
396 union {
397 uint8_t c[2];
398 uint16_t s;
399 } test_buf;
400 uint16_t test_val = 0x2345;
401 if (DL.isLittleEndian())
402 support::endian::write16le(test_buf.c, test_val);
403 else
404 support::endian::write16be(test_buf.c, test_val);
405
406 bool endian_match = test_buf.s == test_val;
407 for (uint64_t i = Offset, j = 0; i < Offset + Size; i++, j++)
408 ByteSeq[j] = endian_match ? TmpVal[i] : TmpVal[Offset + Size - 1 - j];
409
410 return true;
411}
412
413bool BPFDAGToDAGISel::fillGenericConstant(const DataLayout &DL,
414 const Constant *CV,
415 val_vec_type &Vals, uint64_t Offset) {
416 uint64_t Size = DL.getTypeAllocSize(CV->getType());
417
419 return true; // already done
420
421 if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
422 uint64_t val = CI->getZExtValue();
423 LLVM_DEBUG(dbgs() << "Byte array at offset " << Offset << " with value "
424 << val << '\n');
425
426 if (Size > 8 || (Size & (Size - 1)))
427 return false;
428
429 // Store based on target endian
430 for (uint64_t i = 0; i < Size; ++i) {
431 Vals[Offset + i] = DL.isLittleEndian()
432 ? ((val >> (i * 8)) & 0xFF)
433 : ((val >> ((Size - i - 1) * 8)) & 0xFF);
434 }
435 return true;
436 }
437
438 if (const ConstantDataArray *CDA = dyn_cast<ConstantDataArray>(CV))
439 return fillConstantDataArray(DL, CDA, Vals, Offset);
440
441 if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV))
442 return fillConstantArray(DL, CA, Vals, Offset);
443
444 if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
445 return fillConstantStruct(DL, CVS, Vals, Offset);
446
447 return false;
448}
449
450bool BPFDAGToDAGISel::fillConstantDataArray(const DataLayout &DL,
451 const ConstantDataArray *CDA,
452 val_vec_type &Vals, int Offset) {
453 for (unsigned i = 0, e = CDA->getNumElements(); i != e; ++i) {
454 if (fillGenericConstant(DL, CDA->getElementAsConstant(i), Vals, Offset) ==
455 false)
456 return false;
457 Offset += DL.getTypeAllocSize(CDA->getElementAsConstant(i)->getType());
458 }
459
460 return true;
461}
462
463bool BPFDAGToDAGISel::fillConstantArray(const DataLayout &DL,
464 const ConstantArray *CA,
465 val_vec_type &Vals, int Offset) {
466 for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) {
467 if (fillGenericConstant(DL, CA->getOperand(i), Vals, Offset) == false)
468 return false;
469 Offset += DL.getTypeAllocSize(CA->getOperand(i)->getType());
470 }
471
472 return true;
473}
474
475bool BPFDAGToDAGISel::fillConstantStruct(const DataLayout &DL,
476 const ConstantStruct *CS,
477 val_vec_type &Vals, int Offset) {
478 const StructLayout *Layout = DL.getStructLayout(CS->getType());
479 for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) {
480 const Constant *Field = CS->getOperand(i);
481 uint64_t SizeSoFar = Layout->getElementOffset(i);
482 if (fillGenericConstant(DL, Field, Vals, Offset + SizeSoFar) == false)
483 return false;
484 }
485 return true;
486}
487
488void BPFDAGToDAGISel::PreprocessTrunc(SDNode *Node,
490 ConstantSDNode *MaskN = dyn_cast<ConstantSDNode>(Node->getOperand(1));
491 if (!MaskN)
492 return;
493
494 // The Reg operand should be a virtual register, which is defined
495 // outside the current basic block. DAG combiner has done a pretty
496 // good job in removing truncating inside a single basic block except
497 // when the Reg operand comes from bpf_load_[byte | half | word] for
498 // which the generic optimizer doesn't understand their results are
499 // zero extended.
500 SDValue BaseV = Node->getOperand(0);
501 if (BaseV.getOpcode() != ISD::INTRINSIC_W_CHAIN)
502 return;
503
504 unsigned IntNo = BaseV->getConstantOperandVal(1);
505 uint64_t MaskV = MaskN->getZExtValue();
506
507 if (!((IntNo == Intrinsic::bpf_load_byte && MaskV == 0xFF) ||
508 (IntNo == Intrinsic::bpf_load_half && MaskV == 0xFFFF) ||
509 (IntNo == Intrinsic::bpf_load_word && MaskV == 0xFFFFFFFF)))
510 return;
511
512 LLVM_DEBUG(dbgs() << "Remove the redundant AND operation in: ";
513 Node->dump(); dbgs() << '\n');
514
515 I--;
516 CurDAG->ReplaceAllUsesWith(SDValue(Node, 0), BaseV);
517 I++;
518 CurDAG->DeleteNode(Node);
519}
520
522 return new BPFDAGToDAGISelLegacy(TM);
523}
524
return SDValue()
const AArch64Subtarget & Subtarget
uint64_t uint64_t
uint64_t Imm
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define DEBUG_TYPE
#define I(x, y, z)
Definition MD5.cpp:57
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
OptimizedStructLayoutField Field
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
#define LLVM_DEBUG(...)
Definition Debug.h:119
#define PASS_NAME
BPFISelDAGToDAGPass(BPFTargetMachine &TM)
ConstantArray - Constant Array Declarations.
Definition Constants.h:590
An array constant whose element type is a simple 1/2/4/8-byte integer, bytes or float/double,...
Definition Constants.h:865
LLVM_ABI Constant * getElementAsConstant(uint64_t i) const
Return a Constant for a specified index's element.
LLVM_ABI uint64_t getNumElements() const
Return the number of elements in the array or vector.
uint64_t getZExtValue() const
StructType * getType() const
Specialization - reduce amount of casting.
Definition Constants.h:661
This is an important base class in LLVM.
Definition Constant.h:44
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
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
const SDValue & getOperand(unsigned i) const
unsigned getOpcode() const
Storage of either a normal Value address, or a select instruction together with a pair of addresses f...
SelectionDAGISelPass(std::unique_ptr< SelectionDAGISel > Selector)
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual bool runOnMachineFunction(MachineFunction &mf)
ilist< SDNode >::iterator allnodes_iterator
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:774
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
@ POISON
POISON - A poison node.
Definition ISDOpcodes.h:238
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ TargetExternalSymbol
Definition ISDOpcodes.h:192
@ UNDEF
UNDEF - An undefined node.
Definition ISDOpcodes.h:235
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition ISDOpcodes.h:187
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition ISDOpcodes.h:215
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
void write16be(void *P, uint16_t V)
Definition Endian.h:461
void write16le(void *P, uint16_t V)
Definition Endian.h:452
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1685
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
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
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
FunctionPass * createBPFISelDag(BPFTargetMachine &TM)
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
#define N
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:411