• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "BPF.h"
15 #include "BPFInstrInfo.h"
16 #include "BPFSubtarget.h"
17 #include "BPFTargetMachine.h"
18 #include "llvm/CodeGen/MachineFunctionPass.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/TargetRegistry.h"
23 #include "llvm/ADT/STLExtras.h"
24 #include "llvm/ADT/SmallVector.h"
25 
26 #define GET_INSTRINFO_CTOR_DTOR
27 #include "BPFGenInstrInfo.inc"
28 
29 using namespace llvm;
30 
BPFInstrInfo()31 BPFInstrInfo::BPFInstrInfo()
32     : BPFGenInstrInfo(BPF::ADJCALLSTACKDOWN, BPF::ADJCALLSTACKUP) {}
33 
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,DebugLoc DL,unsigned DestReg,unsigned SrcReg,bool KillSrc) const34 void BPFInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
35                                MachineBasicBlock::iterator I, DebugLoc DL,
36                                unsigned DestReg, unsigned SrcReg,
37                                bool KillSrc) const {
38   if (BPF::GPRRegClass.contains(DestReg, SrcReg))
39     BuildMI(MBB, I, DL, get(BPF::MOV_rr), DestReg)
40         .addReg(SrcReg, getKillRegState(KillSrc));
41   else
42     llvm_unreachable("Impossible reg-to-reg copy");
43 }
44 
storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,unsigned SrcReg,bool IsKill,int FI,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI) const45 void BPFInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
46                                        MachineBasicBlock::iterator I,
47                                        unsigned SrcReg, bool IsKill, int FI,
48                                        const TargetRegisterClass *RC,
49                                        const TargetRegisterInfo *TRI) const {
50   DebugLoc DL;
51   if (I != MBB.end())
52     DL = I->getDebugLoc();
53 
54   if (RC == &BPF::GPRRegClass)
55     BuildMI(MBB, I, DL, get(BPF::STD))
56         .addReg(SrcReg, getKillRegState(IsKill))
57         .addFrameIndex(FI)
58         .addImm(0);
59   else
60     llvm_unreachable("Can't store this register to stack slot");
61 }
62 
loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,unsigned DestReg,int FI,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI) const63 void BPFInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
64                                         MachineBasicBlock::iterator I,
65                                         unsigned DestReg, int FI,
66                                         const TargetRegisterClass *RC,
67                                         const TargetRegisterInfo *TRI) const {
68   DebugLoc DL;
69   if (I != MBB.end())
70     DL = I->getDebugLoc();
71 
72   if (RC == &BPF::GPRRegClass)
73     BuildMI(MBB, I, DL, get(BPF::LDD), DestReg).addFrameIndex(FI).addImm(0);
74   else
75     llvm_unreachable("Can't load this register from stack slot");
76 }
77 
AnalyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const78 bool BPFInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
79                                  MachineBasicBlock *&TBB,
80                                  MachineBasicBlock *&FBB,
81                                  SmallVectorImpl<MachineOperand> &Cond,
82                                  bool AllowModify) const {
83   // Start from the bottom of the block and work up, examining the
84   // terminator instructions.
85   MachineBasicBlock::iterator I = MBB.end();
86   while (I != MBB.begin()) {
87     --I;
88     if (I->isDebugValue())
89       continue;
90 
91     // Working from the bottom, when we see a non-terminator
92     // instruction, we're done.
93     if (!isUnpredicatedTerminator(I))
94       break;
95 
96     // A terminator that isn't a branch can't easily be handled
97     // by this analysis.
98     if (!I->isBranch())
99       return true;
100 
101     // Handle unconditional branches.
102     if (I->getOpcode() == BPF::JMP) {
103       if (!AllowModify) {
104         TBB = I->getOperand(0).getMBB();
105         continue;
106       }
107 
108       // If the block has any instructions after a J, delete them.
109       while (std::next(I) != MBB.end())
110         std::next(I)->eraseFromParent();
111       Cond.clear();
112       FBB = 0;
113 
114       // Delete the J if it's equivalent to a fall-through.
115       if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
116         TBB = 0;
117         I->eraseFromParent();
118         I = MBB.end();
119         continue;
120       }
121 
122       // TBB is used to indicate the unconditinal destination.
123       TBB = I->getOperand(0).getMBB();
124       continue;
125     }
126     // Cannot handle conditional branches
127     return true;
128   }
129 
130   return false;
131 }
132 
InsertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,ArrayRef<MachineOperand> Cond,DebugLoc DL) const133 unsigned BPFInstrInfo::InsertBranch(MachineBasicBlock &MBB,
134                                     MachineBasicBlock *TBB,
135                                     MachineBasicBlock *FBB,
136                                     ArrayRef<MachineOperand> Cond,
137                                     DebugLoc DL) const {
138   // Shouldn't be a fall through.
139   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
140 
141   if (Cond.empty()) {
142     // Unconditional branch
143     assert(!FBB && "Unconditional branch with multiple successors!");
144     BuildMI(&MBB, DL, get(BPF::JMP)).addMBB(TBB);
145     return 1;
146   }
147 
148   llvm_unreachable("Unexpected conditional branch");
149 }
150 
RemoveBranch(MachineBasicBlock & MBB) const151 unsigned BPFInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
152   MachineBasicBlock::iterator I = MBB.end();
153   unsigned Count = 0;
154 
155   while (I != MBB.begin()) {
156     --I;
157     if (I->isDebugValue())
158       continue;
159     if (I->getOpcode() != BPF::JMP)
160       break;
161     // Remove the branch.
162     I->eraseFromParent();
163     I = MBB.end();
164     ++Count;
165   }
166 
167   return Count;
168 }
169