LLVM  8.0.1
BPFInstrInfo.cpp
Go to the documentation of this file.
1 //===-- BPFInstrInfo.cpp - BPF Instruction Information ----------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the BPF implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "BPFInstrInfo.h"
15 #include "BPF.h"
16 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/IR/DebugLoc.h"
21 #include <cassert>
22 #include <iterator>
23 
24 #define GET_INSTRINFO_CTOR_DTOR
25 #include "BPFGenInstrInfo.inc"
26 
27 using namespace llvm;
28 
30  : BPFGenInstrInfo(BPF::ADJCALLSTACKDOWN, BPF::ADJCALLSTACKUP) {}
31 
34  const DebugLoc &DL, unsigned DestReg,
35  unsigned SrcReg, bool KillSrc) const {
36  if (BPF::GPRRegClass.contains(DestReg, SrcReg))
37  BuildMI(MBB, I, DL, get(BPF::MOV_rr), DestReg)
38  .addReg(SrcReg, getKillRegState(KillSrc));
39  else if (BPF::GPR32RegClass.contains(DestReg, SrcReg))
40  BuildMI(MBB, I, DL, get(BPF::MOV_rr_32), DestReg)
41  .addReg(SrcReg, getKillRegState(KillSrc));
42  else
43  llvm_unreachable("Impossible reg-to-reg copy");
44 }
45 
46 void BPFInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const {
47  unsigned DstReg = MI->getOperand(0).getReg();
48  unsigned SrcReg = MI->getOperand(1).getReg();
49  uint64_t CopyLen = MI->getOperand(2).getImm();
50  uint64_t Alignment = MI->getOperand(3).getImm();
51  unsigned ScratchReg = MI->getOperand(4).getReg();
52  MachineBasicBlock *BB = MI->getParent();
53  DebugLoc dl = MI->getDebugLoc();
54  unsigned LdOpc, StOpc;
55 
56  switch (Alignment) {
57  case 1:
58  LdOpc = BPF::LDB;
59  StOpc = BPF::STB;
60  break;
61  case 2:
62  LdOpc = BPF::LDH;
63  StOpc = BPF::STH;
64  break;
65  case 4:
66  LdOpc = BPF::LDW;
67  StOpc = BPF::STW;
68  break;
69  case 8:
70  LdOpc = BPF::LDD;
71  StOpc = BPF::STD;
72  break;
73  default:
74  llvm_unreachable("unsupported memcpy alignment");
75  }
76 
77  unsigned IterationNum = CopyLen >> Log2_64(Alignment);
78  for(unsigned I = 0; I < IterationNum; ++I) {
79  BuildMI(*BB, MI, dl, get(LdOpc))
80  .addReg(ScratchReg, RegState::Define).addReg(SrcReg)
81  .addImm(I * Alignment);
82  BuildMI(*BB, MI, dl, get(StOpc))
83  .addReg(ScratchReg, RegState::Kill).addReg(DstReg)
84  .addImm(I * Alignment);
85  }
86 
87  unsigned BytesLeft = CopyLen & (Alignment - 1);
88  unsigned Offset = IterationNum * Alignment;
89  bool Hanging4Byte = BytesLeft & 0x4;
90  bool Hanging2Byte = BytesLeft & 0x2;
91  bool Hanging1Byte = BytesLeft & 0x1;
92  if (Hanging4Byte) {
93  BuildMI(*BB, MI, dl, get(BPF::LDW))
94  .addReg(ScratchReg, RegState::Define).addReg(SrcReg).addImm(Offset);
95  BuildMI(*BB, MI, dl, get(BPF::STW))
96  .addReg(ScratchReg, RegState::Kill).addReg(DstReg).addImm(Offset);
97  Offset += 4;
98  }
99  if (Hanging2Byte) {
100  BuildMI(*BB, MI, dl, get(BPF::LDH))
101  .addReg(ScratchReg, RegState::Define).addReg(SrcReg).addImm(Offset);
102  BuildMI(*BB, MI, dl, get(BPF::STH))
103  .addReg(ScratchReg, RegState::Kill).addReg(DstReg).addImm(Offset);
104  Offset += 2;
105  }
106  if (Hanging1Byte) {
107  BuildMI(*BB, MI, dl, get(BPF::LDB))
108  .addReg(ScratchReg, RegState::Define).addReg(SrcReg).addImm(Offset);
109  BuildMI(*BB, MI, dl, get(BPF::STB))
110  .addReg(ScratchReg, RegState::Kill).addReg(DstReg).addImm(Offset);
111  }
112 
113  BB->erase(MI);
114 }
115 
117  if (MI.getOpcode() == BPF::MEMCPY) {
118  expandMEMCPY(MI);
119  return true;
120  }
121 
122  return false;
123 }
124 
127  unsigned SrcReg, bool IsKill, int FI,
128  const TargetRegisterClass *RC,
129  const TargetRegisterInfo *TRI) const {
130  DebugLoc DL;
131  if (I != MBB.end())
132  DL = I->getDebugLoc();
133 
134  if (RC == &BPF::GPRRegClass)
135  BuildMI(MBB, I, DL, get(BPF::STD))
136  .addReg(SrcReg, getKillRegState(IsKill))
137  .addFrameIndex(FI)
138  .addImm(0);
139  else if (RC == &BPF::GPR32RegClass)
140  BuildMI(MBB, I, DL, get(BPF::STW32))
141  .addReg(SrcReg, getKillRegState(IsKill))
142  .addFrameIndex(FI)
143  .addImm(0);
144  else
145  llvm_unreachable("Can't store this register to stack slot");
146 }
147 
150  unsigned DestReg, int FI,
151  const TargetRegisterClass *RC,
152  const TargetRegisterInfo *TRI) const {
153  DebugLoc DL;
154  if (I != MBB.end())
155  DL = I->getDebugLoc();
156 
157  if (RC == &BPF::GPRRegClass)
158  BuildMI(MBB, I, DL, get(BPF::LDD), DestReg).addFrameIndex(FI).addImm(0);
159  else if (RC == &BPF::GPR32RegClass)
160  BuildMI(MBB, I, DL, get(BPF::LDW32), DestReg).addFrameIndex(FI).addImm(0);
161  else
162  llvm_unreachable("Can't load this register from stack slot");
163 }
164 
166  MachineBasicBlock *&TBB,
167  MachineBasicBlock *&FBB,
169  bool AllowModify) const {
170  // Start from the bottom of the block and work up, examining the
171  // terminator instructions.
173  while (I != MBB.begin()) {
174  --I;
175  if (I->isDebugInstr())
176  continue;
177 
178  // Working from the bottom, when we see a non-terminator
179  // instruction, we're done.
180  if (!isUnpredicatedTerminator(*I))
181  break;
182 
183  // A terminator that isn't a branch can't easily be handled
184  // by this analysis.
185  if (!I->isBranch())
186  return true;
187 
188  // Handle unconditional branches.
189  if (I->getOpcode() == BPF::JMP) {
190  if (!AllowModify) {
191  TBB = I->getOperand(0).getMBB();
192  continue;
193  }
194 
195  // If the block has any instructions after a J, delete them.
196  while (std::next(I) != MBB.end())
197  std::next(I)->eraseFromParent();
198  Cond.clear();
199  FBB = nullptr;
200 
201  // Delete the J if it's equivalent to a fall-through.
202  if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
203  TBB = nullptr;
204  I->eraseFromParent();
205  I = MBB.end();
206  continue;
207  }
208 
209  // TBB is used to indicate the unconditinal destination.
210  TBB = I->getOperand(0).getMBB();
211  continue;
212  }
213  // Cannot handle conditional branches
214  return true;
215  }
216 
217  return false;
218 }
219 
221  MachineBasicBlock *TBB,
222  MachineBasicBlock *FBB,
224  const DebugLoc &DL,
225  int *BytesAdded) const {
226  assert(!BytesAdded && "code size not handled");
227 
228  // Shouldn't be a fall through.
229  assert(TBB && "insertBranch must not be told to insert a fallthrough");
230 
231  if (Cond.empty()) {
232  // Unconditional branch
233  assert(!FBB && "Unconditional branch with multiple successors!");
234  BuildMI(&MBB, DL, get(BPF::JMP)).addMBB(TBB);
235  return 1;
236  }
237 
238  llvm_unreachable("Unexpected conditional branch");
239 }
240 
242  int *BytesRemoved) const {
243  assert(!BytesRemoved && "code size not handled");
244 
246  unsigned Count = 0;
247 
248  while (I != MBB.begin()) {
249  --I;
250  if (I->isDebugInstr())
251  continue;
252  if (I->getOpcode() != BPF::JMP)
253  break;
254  // Remove the branch.
255  I->eraseFromParent();
256  I = MBB.end();
257  ++Count;
258  }
259 
260  return Count;
261 }
This class represents lattice values for constants.
Definition: AllocatorList.h:24
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:34
return AArch64::GPR64RegClass contains(Reg)
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
unsigned getKillRegState(bool B)
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const MachineInstrBuilder & addFrameIndex(int Idx) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
bool expandPostRAPseudo(MachineInstr &MI) const override
Representation of each machine instruction.
Definition: MachineInstr.h:64
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
#define I(x, y, z)
Definition: MD5.cpp:58
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:545
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:144