LLVM  7.0.0svn
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 
48  unsigned SrcReg, bool IsKill, int FI,
49  const TargetRegisterClass *RC,
50  const TargetRegisterInfo *TRI) const {
51  DebugLoc DL;
52  if (I != MBB.end())
53  DL = I->getDebugLoc();
54 
55  if (RC == &BPF::GPRRegClass)
56  BuildMI(MBB, I, DL, get(BPF::STD))
57  .addReg(SrcReg, getKillRegState(IsKill))
58  .addFrameIndex(FI)
59  .addImm(0);
60  else if (RC == &BPF::GPR32RegClass)
61  BuildMI(MBB, I, DL, get(BPF::STW32))
62  .addReg(SrcReg, getKillRegState(IsKill))
63  .addFrameIndex(FI)
64  .addImm(0);
65  else
66  llvm_unreachable("Can't store this register to stack slot");
67 }
68 
71  unsigned DestReg, int FI,
72  const TargetRegisterClass *RC,
73  const TargetRegisterInfo *TRI) const {
74  DebugLoc DL;
75  if (I != MBB.end())
76  DL = I->getDebugLoc();
77 
78  if (RC == &BPF::GPRRegClass)
79  BuildMI(MBB, I, DL, get(BPF::LDD), DestReg).addFrameIndex(FI).addImm(0);
80  else if (RC == &BPF::GPR32RegClass)
81  BuildMI(MBB, I, DL, get(BPF::LDW32), DestReg).addFrameIndex(FI).addImm(0);
82  else
83  llvm_unreachable("Can't load this register from stack slot");
84 }
85 
87  MachineBasicBlock *&TBB,
88  MachineBasicBlock *&FBB,
90  bool AllowModify) const {
91  // Start from the bottom of the block and work up, examining the
92  // terminator instructions.
94  while (I != MBB.begin()) {
95  --I;
96  if (I->isDebugInstr())
97  continue;
98 
99  // Working from the bottom, when we see a non-terminator
100  // instruction, we're done.
101  if (!isUnpredicatedTerminator(*I))
102  break;
103 
104  // A terminator that isn't a branch can't easily be handled
105  // by this analysis.
106  if (!I->isBranch())
107  return true;
108 
109  // Handle unconditional branches.
110  if (I->getOpcode() == BPF::JMP) {
111  if (!AllowModify) {
112  TBB = I->getOperand(0).getMBB();
113  continue;
114  }
115 
116  // If the block has any instructions after a J, delete them.
117  while (std::next(I) != MBB.end())
118  std::next(I)->eraseFromParent();
119  Cond.clear();
120  FBB = nullptr;
121 
122  // Delete the J if it's equivalent to a fall-through.
123  if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
124  TBB = nullptr;
125  I->eraseFromParent();
126  I = MBB.end();
127  continue;
128  }
129 
130  // TBB is used to indicate the unconditinal destination.
131  TBB = I->getOperand(0).getMBB();
132  continue;
133  }
134  // Cannot handle conditional branches
135  return true;
136  }
137 
138  return false;
139 }
140 
142  MachineBasicBlock *TBB,
143  MachineBasicBlock *FBB,
145  const DebugLoc &DL,
146  int *BytesAdded) const {
147  assert(!BytesAdded && "code size not handled");
148 
149  // Shouldn't be a fall through.
150  assert(TBB && "insertBranch must not be told to insert a fallthrough");
151 
152  if (Cond.empty()) {
153  // Unconditional branch
154  assert(!FBB && "Unconditional branch with multiple successors!");
155  BuildMI(&MBB, DL, get(BPF::JMP)).addMBB(TBB);
156  return 1;
157  }
158 
159  llvm_unreachable("Unexpected conditional branch");
160 }
161 
163  int *BytesRemoved) const {
164  assert(!BytesRemoved && "code size not handled");
165 
167  unsigned Count = 0;
168 
169  while (I != MBB.begin()) {
170  --I;
171  if (I->isDebugInstr())
172  continue;
173  if (I->getOpcode() != BPF::JMP)
174  break;
175  // Remove the branch.
176  I->eraseFromParent();
177  I = MBB.end();
178  ++Count;
179  }
180 
181  return Count;
182 }
Compute iterated dominance frontiers using a linear time algorithm.
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)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
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...
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())
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
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:144