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