Home | History | Annotate | Download | only in BPF
      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 
     31 BPFInstrInfo::BPFInstrInfo()
     32     : BPFGenInstrInfo(BPF::ADJCALLSTACKDOWN, BPF::ADJCALLSTACKUP) {}
     33 
     34 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 
     45 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 
     63 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 
     78 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 
    133 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 
    151 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