LLVM  10.0.0svn
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 "BPFRegisterInfo.h"
16 #include "BPFSubtarget.h"
17 #include "BPFTargetMachine.h"
25 #include "llvm/IR/Constants.h"
26 #include "llvm/IR/IntrinsicInst.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/Endian.h"
32 
33 using namespace llvm;
34 
35 #define DEBUG_TYPE "bpf-isel"
36 
37 // Instruction Selector Implementation
38 namespace {
39 
40 class BPFDAGToDAGISel : public SelectionDAGISel {
41 
42  /// Subtarget - Keep a pointer to the BPFSubtarget around so that we can
43  /// make the right decision when generating code for different subtargets.
44  const BPFSubtarget *Subtarget;
45 
46 public:
47  explicit BPFDAGToDAGISel(BPFTargetMachine &TM)
48  : SelectionDAGISel(TM), Subtarget(nullptr) {
49  curr_func_ = nullptr;
50  }
51 
52  StringRef getPassName() const override {
53  return "BPF DAG->DAG Pattern Instruction Selection";
54  }
55 
56  bool runOnMachineFunction(MachineFunction &MF) override {
57  // Reset the subtarget each time through.
58  Subtarget = &MF.getSubtarget<BPFSubtarget>();
60  }
61 
62  void PreprocessISelDAG() override;
63 
64  bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode,
65  std::vector<SDValue> &OutOps) override;
66 
67 
68 private:
69 // Include the pieces autogenerated from the target description.
70 #include "BPFGenDAGISel.inc"
71 
72  void Select(SDNode *N) override;
73 
74  // Complex Pattern for address selection.
75  bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset);
76  bool SelectFIAddr(SDValue Addr, SDValue &Base, SDValue &Offset);
77 
78  // Node preprocessing cases
79  void PreprocessLoad(SDNode *Node, SelectionDAG::allnodes_iterator &I);
80  void PreprocessCopyToReg(SDNode *Node);
81  void PreprocessTrunc(SDNode *Node, SelectionDAG::allnodes_iterator &I);
82 
83  // Find constants from a constant structure
84  typedef std::vector<unsigned char> val_vec_type;
85  bool fillGenericConstant(const DataLayout &DL, const Constant *CV,
86  val_vec_type &Vals, uint64_t Offset);
87  bool fillConstantDataArray(const DataLayout &DL, const ConstantDataArray *CDA,
88  val_vec_type &Vals, int Offset);
89  bool fillConstantArray(const DataLayout &DL, const ConstantArray *CA,
90  val_vec_type &Vals, int Offset);
91  bool fillConstantStruct(const DataLayout &DL, const ConstantStruct *CS,
92  val_vec_type &Vals, int Offset);
93  bool getConstantFieldValue(const GlobalAddressSDNode *Node, uint64_t Offset,
94  uint64_t Size, unsigned char *ByteSeq);
95  bool checkLoadDef(unsigned DefReg, unsigned match_load_op);
96 
97  // Mapping from ConstantStruct global value to corresponding byte-list values
98  std::map<const void *, val_vec_type> cs_vals_;
99  // Mapping from vreg to load memory opcode
100  std::map<unsigned, unsigned> load_to_vreg_;
101  // Current function
102  const Function *curr_func_;
103 };
104 } // namespace
105 
106 // ComplexPattern used on BPF Load/Store instructions
107 bool BPFDAGToDAGISel::SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) {
108  // if Address is FI, get the TargetFrameIndex.
109  SDLoc DL(Addr);
110  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
111  Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64);
112  Offset = CurDAG->getTargetConstant(0, DL, MVT::i64);
113  return true;
114  }
115 
116  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
118  return false;
119 
120  // Addresses of the form Addr+const or Addr|const
121  if (CurDAG->isBaseWithConstantOffset(Addr)) {
123  if (isInt<16>(CN->getSExtValue())) {
124 
125  // If the first operand is a FI, get the TargetFI Node
126  if (FrameIndexSDNode *FIN =
127  dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
128  Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64);
129  else
130  Base = Addr.getOperand(0);
131 
132  Offset = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i64);
133  return true;
134  }
135  }
136 
137  Base = Addr;
138  Offset = CurDAG->getTargetConstant(0, DL, MVT::i64);
139  return true;
140 }
141 
142 // ComplexPattern used on BPF FI instruction
143 bool BPFDAGToDAGISel::SelectFIAddr(SDValue Addr, SDValue &Base,
144  SDValue &Offset) {
145  SDLoc DL(Addr);
146 
147  if (!CurDAG->isBaseWithConstantOffset(Addr))
148  return false;
149 
150  // Addresses of the form Addr+const or Addr|const
152  if (isInt<16>(CN->getSExtValue())) {
153 
154  // If the first operand is a FI, get the TargetFI Node
155  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
156  Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64);
157  else
158  return false;
159 
160  Offset = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i64);
161  return true;
162  }
163 
164  return false;
165 }
166 
167 bool BPFDAGToDAGISel::SelectInlineAsmMemoryOperand(
168  const SDValue &Op, unsigned ConstraintCode, std::vector<SDValue> &OutOps) {
169  SDValue Op0, Op1;
170  switch (ConstraintCode) {
171  default:
172  return true;
173  case InlineAsm::Constraint_m: // memory
174  if (!SelectAddr(Op, Op0, Op1))
175  return true;
176  break;
177  }
178 
179  SDLoc DL(Op);
180  SDValue AluOp = CurDAG->getTargetConstant(ISD::ADD, DL, MVT::i32);;
181  OutOps.push_back(Op0);
182  OutOps.push_back(Op1);
183  OutOps.push_back(AluOp);
184  return false;
185 }
186 
187 void BPFDAGToDAGISel::Select(SDNode *Node) {
188  unsigned Opcode = Node->getOpcode();
189 
190  // If we have a custom node, we already have selected!
191  if (Node->isMachineOpcode()) {
192  LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << '\n');
193  return;
194  }
195 
196  // tablegen selection should be handled here.
197  switch (Opcode) {
198  default:
199  break;
200  case ISD::SDIV: {
201  DebugLoc Empty;
202  const DebugLoc &DL = Node->getDebugLoc();
203  if (DL != Empty)
204  errs() << "Error at line " << DL.getLine() << ": ";
205  else
206  errs() << "Error: ";
207  errs() << "Unsupport signed division for DAG: ";
208  Node->print(errs(), CurDAG);
209  errs() << "Please convert to unsigned div/mod.\n";
210  break;
211  }
212  case ISD::INTRINSIC_W_CHAIN: {
213  unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
214  switch (IntNo) {
215  case Intrinsic::bpf_load_byte:
216  case Intrinsic::bpf_load_half:
217  case Intrinsic::bpf_load_word: {
218  SDLoc DL(Node);
219  SDValue Chain = Node->getOperand(0);
220  SDValue N1 = Node->getOperand(1);
221  SDValue Skb = Node->getOperand(2);
222  SDValue N3 = Node->getOperand(3);
223 
224  SDValue R6Reg = CurDAG->getRegister(BPF::R6, MVT::i64);
225  Chain = CurDAG->getCopyToReg(Chain, DL, R6Reg, Skb, SDValue());
226  Node = CurDAG->UpdateNodeOperands(Node, Chain, N1, R6Reg, N3);
227  break;
228  }
229  }
230  break;
231  }
232 
233  case ISD::FrameIndex: {
234  int FI = cast<FrameIndexSDNode>(Node)->getIndex();
235  EVT VT = Node->getValueType(0);
236  SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
237  unsigned Opc = BPF::MOV_rr;
238  if (Node->hasOneUse()) {
239  CurDAG->SelectNodeTo(Node, Opc, VT, TFI);
240  return;
241  }
242  ReplaceNode(Node, CurDAG->getMachineNode(Opc, SDLoc(Node), VT, TFI));
243  return;
244  }
245  }
246 
247  // Select the default instruction
248  SelectCode(Node);
249 }
250 
251 void BPFDAGToDAGISel::PreprocessLoad(SDNode *Node,
253  union {
254  uint8_t c[8];
255  uint16_t s;
256  uint32_t i;
257  uint64_t d;
258  } new_val; // hold up the constant values replacing loads.
259  bool to_replace = false;
260  SDLoc DL(Node);
261  const LoadSDNode *LD = cast<LoadSDNode>(Node);
262  uint64_t size = LD->getMemOperand()->getSize();
263 
264  if (!size || size > 8 || (size & (size - 1)))
265  return;
266 
267  SDNode *LDAddrNode = LD->getOperand(1).getNode();
268  // Match LDAddr against either global_addr or (global_addr + offset)
269  unsigned opcode = LDAddrNode->getOpcode();
270  if (opcode == ISD::ADD) {
271  SDValue OP1 = LDAddrNode->getOperand(0);
272  SDValue OP2 = LDAddrNode->getOperand(1);
273 
274  // We want to find the pattern global_addr + offset
275  SDNode *OP1N = OP1.getNode();
276  if (OP1N->getOpcode() <= ISD::BUILTIN_OP_END || OP1N->getNumOperands() == 0)
277  return;
278 
279  LLVM_DEBUG(dbgs() << "Check candidate load: "; LD->dump(); dbgs() << '\n');
280 
281  const GlobalAddressSDNode *GADN =
283  const ConstantSDNode *CDN = dyn_cast<ConstantSDNode>(OP2.getNode());
284  if (GADN && CDN)
285  to_replace =
286  getConstantFieldValue(GADN, CDN->getZExtValue(), size, new_val.c);
287  } else if (LDAddrNode->getOpcode() > ISD::BUILTIN_OP_END &&
288  LDAddrNode->getNumOperands() > 0) {
289  LLVM_DEBUG(dbgs() << "Check candidate load: "; LD->dump(); dbgs() << '\n');
290 
291  SDValue OP1 = LDAddrNode->getOperand(0);
292  if (const GlobalAddressSDNode *GADN =
293  dyn_cast<GlobalAddressSDNode>(OP1.getNode()))
294  to_replace = getConstantFieldValue(GADN, 0, size, new_val.c);
295  }
296 
297  if (!to_replace)
298  return;
299 
300  // replacing the old with a new value
301  uint64_t val;
302  if (size == 1)
303  val = new_val.c[0];
304  else if (size == 2)
305  val = new_val.s;
306  else if (size == 4)
307  val = new_val.i;
308  else {
309  val = new_val.d;
310  }
311 
312  LLVM_DEBUG(dbgs() << "Replacing load of size " << size << " with constant "
313  << val << '\n');
314  SDValue NVal = CurDAG->getConstant(val, DL, MVT::i64);
315 
316  // After replacement, the current node is dead, we need to
317  // go backward one step to make iterator still work
318  I--;
319  SDValue From[] = {SDValue(Node, 0), SDValue(Node, 1)};
320  SDValue To[] = {NVal, NVal};
321  CurDAG->ReplaceAllUsesOfValuesWith(From, To, 2);
322  I++;
323  // It is safe to delete node now
324  CurDAG->DeleteNode(Node);
325 }
326 
327 void BPFDAGToDAGISel::PreprocessISelDAG() {
328  // Iterate through all nodes, interested in the following cases:
329  //
330  // . loads from ConstantStruct or ConstantArray of constructs
331  // which can be turns into constant itself, with this we can
332  // avoid reading from read-only section at runtime.
333  //
334  // . reg truncating is often the result of 8/16/32bit->64bit or
335  // 8/16bit->32bit conversion. If the reg value is loaded with
336  // masked byte width, the AND operation can be removed since
337  // BPF LOAD already has zero extension.
338  //
339  // This also solved a correctness issue.
340  // In BPF socket-related program, e.g., __sk_buff->{data, data_end}
341  // are 32-bit registers, but later on, kernel verifier will rewrite
342  // it with 64-bit value. Therefore, truncating the value after the
343  // load will result in incorrect code.
344 
345  // clear the load_to_vreg_ map so that we have a clean start
346  // for this function.
347  if (!curr_func_) {
348  curr_func_ = FuncInfo->Fn;
349  } else if (curr_func_ != FuncInfo->Fn) {
350  load_to_vreg_.clear();
351  curr_func_ = FuncInfo->Fn;
352  }
353 
354  for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
355  E = CurDAG->allnodes_end();
356  I != E;) {
357  SDNode *Node = &*I++;
358  unsigned Opcode = Node->getOpcode();
359  if (Opcode == ISD::LOAD)
360  PreprocessLoad(Node, I);
361  else if (Opcode == ISD::CopyToReg)
362  PreprocessCopyToReg(Node);
363  else if (Opcode == ISD::AND)
364  PreprocessTrunc(Node, I);
365  }
366 }
367 
368 bool BPFDAGToDAGISel::getConstantFieldValue(const GlobalAddressSDNode *Node,
369  uint64_t Offset, uint64_t Size,
370  unsigned char *ByteSeq) {
371  const GlobalVariable *V = dyn_cast<GlobalVariable>(Node->getGlobal());
372 
373  if (!V || !V->hasInitializer())
374  return false;
375 
376  const Constant *Init = V->getInitializer();
377  const DataLayout &DL = CurDAG->getDataLayout();
378  val_vec_type TmpVal;
379 
380  auto it = cs_vals_.find(static_cast<const void *>(Init));
381  if (it != cs_vals_.end()) {
382  TmpVal = it->second;
383  } else {
384  uint64_t total_size = 0;
385  if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(Init))
386  total_size =
387  DL.getStructLayout(cast<StructType>(CS->getType()))->getSizeInBytes();
388  else if (const ConstantArray *CA = dyn_cast<ConstantArray>(Init))
389  total_size = DL.getTypeAllocSize(CA->getType()->getElementType()) *
390  CA->getNumOperands();
391  else
392  return false;
393 
394  val_vec_type Vals(total_size, 0);
395  if (fillGenericConstant(DL, Init, Vals, 0) == false)
396  return false;
397  cs_vals_[static_cast<const void *>(Init)] = Vals;
398  TmpVal = std::move(Vals);
399  }
400 
401  // test whether host endianness matches target
402  union {
403  uint8_t c[2];
404  uint16_t s;
405  } test_buf;
406  uint16_t test_val = 0x2345;
407  if (DL.isLittleEndian())
408  support::endian::write16le(test_buf.c, test_val);
409  else
410  support::endian::write16be(test_buf.c, test_val);
411 
412  bool endian_match = test_buf.s == test_val;
413  for (uint64_t i = Offset, j = 0; i < Offset + Size; i++, j++)
414  ByteSeq[j] = endian_match ? TmpVal[i] : TmpVal[Offset + Size - 1 - j];
415 
416  return true;
417 }
418 
419 bool BPFDAGToDAGISel::fillGenericConstant(const DataLayout &DL,
420  const Constant *CV,
421  val_vec_type &Vals, uint64_t Offset) {
422  uint64_t Size = DL.getTypeAllocSize(CV->getType());
423 
424  if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV))
425  return true; // already done
426 
427  if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
428  uint64_t val = CI->getZExtValue();
429  LLVM_DEBUG(dbgs() << "Byte array at offset " << Offset << " with value "
430  << val << '\n');
431 
432  if (Size > 8 || (Size & (Size - 1)))
433  return false;
434 
435  // Store based on target endian
436  for (uint64_t i = 0; i < Size; ++i) {
437  Vals[Offset + i] = DL.isLittleEndian()
438  ? ((val >> (i * 8)) & 0xFF)
439  : ((val >> ((Size - i - 1) * 8)) & 0xFF);
440  }
441  return true;
442  }
443 
444  if (const ConstantDataArray *CDA = dyn_cast<ConstantDataArray>(CV))
445  return fillConstantDataArray(DL, CDA, Vals, Offset);
446 
447  if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV))
448  return fillConstantArray(DL, CA, Vals, Offset);
449 
450  if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
451  return fillConstantStruct(DL, CVS, Vals, Offset);
452 
453  return false;
454 }
455 
456 bool BPFDAGToDAGISel::fillConstantDataArray(const DataLayout &DL,
457  const ConstantDataArray *CDA,
458  val_vec_type &Vals, int Offset) {
459  for (unsigned i = 0, e = CDA->getNumElements(); i != e; ++i) {
460  if (fillGenericConstant(DL, CDA->getElementAsConstant(i), Vals, Offset) ==
461  false)
462  return false;
463  Offset += DL.getTypeAllocSize(CDA->getElementAsConstant(i)->getType());
464  }
465 
466  return true;
467 }
468 
469 bool BPFDAGToDAGISel::fillConstantArray(const DataLayout &DL,
470  const ConstantArray *CA,
471  val_vec_type &Vals, int Offset) {
472  for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) {
473  if (fillGenericConstant(DL, CA->getOperand(i), Vals, Offset) == false)
474  return false;
475  Offset += DL.getTypeAllocSize(CA->getOperand(i)->getType());
476  }
477 
478  return true;
479 }
480 
481 bool BPFDAGToDAGISel::fillConstantStruct(const DataLayout &DL,
482  const ConstantStruct *CS,
483  val_vec_type &Vals, int Offset) {
484  const StructLayout *Layout = DL.getStructLayout(CS->getType());
485  for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) {
486  const Constant *Field = CS->getOperand(i);
487  uint64_t SizeSoFar = Layout->getElementOffset(i);
488  if (fillGenericConstant(DL, Field, Vals, Offset + SizeSoFar) == false)
489  return false;
490  }
491  return true;
492 }
493 
494 void BPFDAGToDAGISel::PreprocessCopyToReg(SDNode *Node) {
495  const RegisterSDNode *RegN = dyn_cast<RegisterSDNode>(Node->getOperand(1));
496  if (!RegN || !Register::isVirtualRegister(RegN->getReg()))
497  return;
498 
499  const LoadSDNode *LD = dyn_cast<LoadSDNode>(Node->getOperand(2));
500  if (!LD)
501  return;
502 
503  // Assign a load value to a virtual register. record its load width
504  unsigned mem_load_op = 0;
505  switch (LD->getMemOperand()->getSize()) {
506  default:
507  return;
508  case 4:
509  mem_load_op = BPF::LDW;
510  break;
511  case 2:
512  mem_load_op = BPF::LDH;
513  break;
514  case 1:
515  mem_load_op = BPF::LDB;
516  break;
517  }
518 
519  LLVM_DEBUG(dbgs() << "Find Load Value to VReg "
520  << Register::virtReg2Index(RegN->getReg()) << '\n');
521  load_to_vreg_[RegN->getReg()] = mem_load_op;
522 }
523 
524 void BPFDAGToDAGISel::PreprocessTrunc(SDNode *Node,
526  ConstantSDNode *MaskN = dyn_cast<ConstantSDNode>(Node->getOperand(1));
527  if (!MaskN)
528  return;
529 
530  // The Reg operand should be a virtual register, which is defined
531  // outside the current basic block. DAG combiner has done a pretty
532  // good job in removing truncating inside a single basic block except
533  // when the Reg operand comes from bpf_load_[byte | half | word] for
534  // which the generic optimizer doesn't understand their results are
535  // zero extended.
536  SDValue BaseV = Node->getOperand(0);
537  if (BaseV.getOpcode() == ISD::INTRINSIC_W_CHAIN) {
538  unsigned IntNo = cast<ConstantSDNode>(BaseV->getOperand(1))->getZExtValue();
539  uint64_t MaskV = MaskN->getZExtValue();
540 
541  if (!((IntNo == Intrinsic::bpf_load_byte && MaskV == 0xFF) ||
542  (IntNo == Intrinsic::bpf_load_half && MaskV == 0xFFFF) ||
543  (IntNo == Intrinsic::bpf_load_word && MaskV == 0xFFFFFFFF)))
544  return;
545 
546  LLVM_DEBUG(dbgs() << "Remove the redundant AND operation in: ";
547  Node->dump(); dbgs() << '\n');
548 
549  I--;
550  CurDAG->ReplaceAllUsesWith(SDValue(Node, 0), BaseV);
551  I++;
552  CurDAG->DeleteNode(Node);
553 
554  return;
555  }
556 
557  // Multiple basic blocks case.
558  if (BaseV.getOpcode() != ISD::CopyFromReg)
559  return;
560 
561  unsigned match_load_op = 0;
562  switch (MaskN->getZExtValue()) {
563  default:
564  return;
565  case 0xFFFFFFFF:
566  match_load_op = BPF::LDW;
567  break;
568  case 0xFFFF:
569  match_load_op = BPF::LDH;
570  break;
571  case 0xFF:
572  match_load_op = BPF::LDB;
573  break;
574  }
575 
576  const RegisterSDNode *RegN =
578  if (!RegN || !Register::isVirtualRegister(RegN->getReg()))
579  return;
580  unsigned AndOpReg = RegN->getReg();
581  LLVM_DEBUG(dbgs() << "Examine " << printReg(AndOpReg) << '\n');
582 
583  // Examine the PHI insns in the MachineBasicBlock to found out the
584  // definitions of this virtual register. At this stage (DAG2DAG
585  // transformation), only PHI machine insns are available in the machine basic
586  // block.
587  MachineBasicBlock *MBB = FuncInfo->MBB;
588  MachineInstr *MII = nullptr;
589  for (auto &MI : *MBB) {
590  for (unsigned i = 0; i < MI.getNumOperands(); ++i) {
591  const MachineOperand &MOP = MI.getOperand(i);
592  if (!MOP.isReg() || !MOP.isDef())
593  continue;
594  Register Reg = MOP.getReg();
595  if (Register::isVirtualRegister(Reg) && Reg == AndOpReg) {
596  MII = &MI;
597  break;
598  }
599  }
600  }
601 
602  if (MII == nullptr) {
603  // No phi definition in this block.
604  if (!checkLoadDef(AndOpReg, match_load_op))
605  return;
606  } else {
607  // The PHI node looks like:
608  // %2 = PHI %0, <%bb.1>, %1, <%bb.3>
609  // Trace each incoming definition, e.g., (%0, %bb.1) and (%1, %bb.3)
610  // The AND operation can be removed if both %0 in %bb.1 and %1 in
611  // %bb.3 are defined with a load matching the MaskN.
612  LLVM_DEBUG(dbgs() << "Check PHI Insn: "; MII->dump(); dbgs() << '\n');
613  unsigned PrevReg = -1;
614  for (unsigned i = 0; i < MII->getNumOperands(); ++i) {
615  const MachineOperand &MOP = MII->getOperand(i);
616  if (MOP.isReg()) {
617  if (MOP.isDef())
618  continue;
619  PrevReg = MOP.getReg();
620  if (!Register::isVirtualRegister(PrevReg))
621  return;
622  if (!checkLoadDef(PrevReg, match_load_op))
623  return;
624  }
625  }
626  }
627 
628  LLVM_DEBUG(dbgs() << "Remove the redundant AND operation in: "; Node->dump();
629  dbgs() << '\n');
630 
631  I--;
632  CurDAG->ReplaceAllUsesWith(SDValue(Node, 0), BaseV);
633  I++;
634  CurDAG->DeleteNode(Node);
635 }
636 
637 bool BPFDAGToDAGISel::checkLoadDef(unsigned DefReg, unsigned match_load_op) {
638  auto it = load_to_vreg_.find(DefReg);
639  if (it == load_to_vreg_.end())
640  return false; // The definition of register is not exported yet.
641 
642  return it->second == match_load_op;
643 }
644 
646  return new BPFDAGToDAGISel(TM);
647 }
BUILTIN_OP_END - This must be the last enum value in this list.
Definition: ISDOpcodes.h:914
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:112
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
const GlobalValue * getGlobal() const
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
static unsigned virtReg2Index(unsigned Reg)
Convert a virtual register number to a 0-based index.
Definition: Register.h:76
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Constant * getElementAsConstant(unsigned i) const
Return a Constant for a specified index&#39;s element.
Definition: Constants.cpp:2773
const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
Definition: DataLayout.cpp:613
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
unsigned Reg
uint64_t getSize() const
Return the size in bytes of the memory reference.
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition: ISDOpcodes.h:130
unsigned getLine() const
Definition: DebugLoc.cpp:25
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:342
A debug info location.
Definition: DebugLoc.h:33
SDNode * getNode() const
get the SDNode which holds the desired result
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const DebugLoc & getDebugLoc() const
Return the source location info.
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition: ISDOpcodes.h:158
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition: DataLayout.h:579
bool hasOneUse() const
Return true if there is exactly one use of this node.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
void write16le(void *P, uint16_t V)
Definition: Endian.h:417
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:414
CopyToReg - This node has three operands: a chain, a register number to set to this value...
Definition: ISDOpcodes.h:169
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
int64_t getSExtValue() const
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:246
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:200
bool isLittleEndian() const
Layout endianness...
Definition: DataLayout.h:233
Value * getOperand(unsigned i) const
Definition: User.h:169
An array constant whose element type is a simple 1/2/4/8-byte integer or float/double, and whose elements are just simple data values (i.e.
Definition: Constants.h:689
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
Definition: Constant.h:41
const SDValue & getOperand(unsigned Num) const
This file contains the declarations for the subclasses of Constant, which represent the different fla...
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition: DataLayout.h:487
constexpr double e
Definition: MathExtras.h:57
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
Extended Value Type.
Definition: ValueTypes.h:33
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
unsigned getNumOperands() const
Return the number of values used by this operation.
void dump() const
Dump this node, for debugging.
Iterator for intrusive lists based on ilist_node.
unsigned getNumOperands() const
Definition: User.h:191
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:1146
#define R6(n)
BlockVerifier::State From
MachineOperand class - Representation of each machine instruction operand.
uint64_t getSizeInBytes() const
Definition: DataLayout.h:587
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
ConstantArray - Constant Array Declarations.
Definition: Constants.h:413
Representation of each machine instruction.
Definition: MachineInstr.h:64
void write16be(void *P, uint16_t V)
Definition: Endian.h:420
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:419
uint64_t getElementOffset(unsigned Idx) const
Definition: DataLayout.h:601
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:643
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:332
uint32_t Size
Definition: Profile.cpp:46
unsigned getOpcode() const
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition: ISDOpcodes.h:174
bool isReg() const
isReg - Tests if this is a MO_Register operand.
unsigned getReg() const
void print(raw_ostream &OS, const SelectionDAG *G=nullptr) const
bool hasInitializer() const
Definitions have initializers, declarations don&#39;t.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:69
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
unsigned getNumElements() const
Return the number of elements in the array or vector.
Definition: Constants.cpp:2456
Register getReg() const
getReg - Returns the register number.
const SDValue & getOperand(unsigned i) const
uint64_t getZExtValue() const
#define LLVM_DEBUG(X)
Definition: Debug.h:122
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
StructType * getType() const
Specialization - reduce amount of casting.
Definition: Constants.h:486
FunctionPass * createBPFISelDag(BPFTargetMachine &TM)
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This class is used to represent ISD::LOAD nodes.