LLVM  15.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  MBB.erase(std::next(I), MBB.end());
196  Cond.clear();
197  FBB = nullptr;
198 
199  // Delete the J if it's equivalent to a fall-through.
200  if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
201  TBB = nullptr;
202  I->eraseFromParent();
203  I = MBB.end();
204  continue;
205  }
206 
207  // TBB is used to indicate the unconditinal destination.
208  TBB = I->getOperand(0).getMBB();
209  continue;
210  }
211  // Cannot handle conditional branches
212  return true;
213  }
214 
215  return false;
216 }
217 
219  MachineBasicBlock *TBB,
220  MachineBasicBlock *FBB,
222  const DebugLoc &DL,
223  int *BytesAdded) const {
224  assert(!BytesAdded && "code size not handled");
225 
226  // Shouldn't be a fall through.
227  assert(TBB && "insertBranch must not be told to insert a fallthrough");
228 
229  if (Cond.empty()) {
230  // Unconditional branch
231  assert(!FBB && "Unconditional branch with multiple successors!");
232  BuildMI(&MBB, DL, get(BPF::JMP)).addMBB(TBB);
233  return 1;
234  }
235 
236  llvm_unreachable("Unexpected conditional branch");
237 }
238 
240  int *BytesRemoved) const {
241  assert(!BytesRemoved && "code size not handled");
242 
244  unsigned Count = 0;
245 
246  while (I != MBB.begin()) {
247  --I;
248  if (I->isDebugInstr())
249  continue;
250  if (I->getOpcode() != BPF::JMP)
251  break;
252  // Remove the branch.
253  I->eraseFromParent();
254  I = MBB.end();
255  ++Count;
256  }
257 
258  return Count;
259 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
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:234
llvm::ARMISD::MEMCPY
@ MEMCPY
Definition: ARMISelLowering.h:310
BPF.h
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
llvm::BPFInstrInfo::expandPostRAPseudo
bool expandPostRAPseudo(MachineInstr &MI) const override
Definition: BPFInstrInfo.cpp:115
llvm::MachineBasicBlock::erase
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
Definition: MachineBasicBlock.cpp:1299
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:629
llvm::MachineInstrBuilder::addMBB
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:146
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:45
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
DebugLoc.h
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::MachineInstrBuilder::addFrameIndex
const MachineInstrBuilder & addFrameIndex(int Idx) const
Definition: MachineInstrBuilder.h:152
llvm::SPIRV::Decoration::Alignment
@ Alignment
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::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:416
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
uint64_t
I
#define I(x, y, z)
Definition: MD5.cpp:58
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:137
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
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:239
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::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:44
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:913
llvm::getKillRegState
unsigned getKillRegState(bool B)
Definition: MachineInstrBuilder.h:508
SmallVector.h
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:278
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::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
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:218
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:280
BPFInstrInfo.h
llvm::MCRegister
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:24