Home | History | Annotate | Download | only in WebAssembly
      1 //===-- WebAssemblyInstrInfo.cpp - WebAssembly Instruction Information ----===//
      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 /// \file
     11 /// \brief This file contains the WebAssembly implementation of the
     12 /// TargetInstrInfo class.
     13 ///
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "WebAssemblyInstrInfo.h"
     17 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
     18 #include "WebAssemblySubtarget.h"
     19 #include "llvm/CodeGen/MachineFrameInfo.h"
     20 #include "llvm/CodeGen/MachineInstrBuilder.h"
     21 #include "llvm/CodeGen/MachineMemOperand.h"
     22 #include "llvm/CodeGen/MachineRegisterInfo.h"
     23 using namespace llvm;
     24 
     25 #define DEBUG_TYPE "wasm-instr-info"
     26 
     27 #define GET_INSTRINFO_CTOR_DTOR
     28 #include "WebAssemblyGenInstrInfo.inc"
     29 
     30 WebAssemblyInstrInfo::WebAssemblyInstrInfo(const WebAssemblySubtarget &STI)
     31     : WebAssemblyGenInstrInfo(WebAssembly::ADJCALLSTACKDOWN,
     32                               WebAssembly::ADJCALLSTACKUP),
     33       RI(STI.getTargetTriple()) {}
     34 
     35 void WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     36                                        MachineBasicBlock::iterator I,
     37                                        DebugLoc DL, unsigned DestReg,
     38                                        unsigned SrcReg, bool KillSrc) const {
     39   // This method is called by post-RA expansion, which expects only pregs to
     40   // exist. However we need to handle both here.
     41   auto &MRI = MBB.getParent()->getRegInfo();
     42   const TargetRegisterClass *RC = TargetRegisterInfo::isVirtualRegister(DestReg) ?
     43       MRI.getRegClass(DestReg) :
     44       MRI.getTargetRegisterInfo()->getMinimalPhysRegClass(SrcReg);
     45 
     46   unsigned CopyLocalOpcode;
     47   if (RC == &WebAssembly::I32RegClass)
     48     CopyLocalOpcode = WebAssembly::COPY_LOCAL_I32;
     49   else if (RC == &WebAssembly::I64RegClass)
     50     CopyLocalOpcode = WebAssembly::COPY_LOCAL_I64;
     51   else if (RC == &WebAssembly::F32RegClass)
     52     CopyLocalOpcode = WebAssembly::COPY_LOCAL_F32;
     53   else if (RC == &WebAssembly::F64RegClass)
     54     CopyLocalOpcode = WebAssembly::COPY_LOCAL_F64;
     55   else
     56     llvm_unreachable("Unexpected register class");
     57 
     58   BuildMI(MBB, I, DL, get(CopyLocalOpcode), DestReg)
     59       .addReg(SrcReg, KillSrc ? RegState::Kill : 0);
     60 }
     61 
     62 // Branch analysis.
     63 bool WebAssemblyInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
     64                                          MachineBasicBlock *&TBB,
     65                                          MachineBasicBlock *&FBB,
     66                                          SmallVectorImpl<MachineOperand> &Cond,
     67                                          bool /*AllowModify*/) const {
     68   bool HaveCond = false;
     69   for (MachineInstr &MI : MBB.terminators()) {
     70     switch (MI.getOpcode()) {
     71     default:
     72       // Unhandled instruction; bail out.
     73       return true;
     74     case WebAssembly::BR_IF:
     75       if (HaveCond)
     76         return true;
     77       Cond.push_back(MachineOperand::CreateImm(true));
     78       Cond.push_back(MI.getOperand(0));
     79       TBB = MI.getOperand(1).getMBB();
     80       HaveCond = true;
     81       break;
     82     case WebAssembly::BR_UNLESS:
     83       if (HaveCond)
     84         return true;
     85       Cond.push_back(MachineOperand::CreateImm(false));
     86       Cond.push_back(MI.getOperand(0));
     87       TBB = MI.getOperand(1).getMBB();
     88       HaveCond = true;
     89       break;
     90     case WebAssembly::BR:
     91       if (!HaveCond)
     92         TBB = MI.getOperand(0).getMBB();
     93       else
     94         FBB = MI.getOperand(0).getMBB();
     95       break;
     96     }
     97     if (MI.isBarrier())
     98       break;
     99   }
    100 
    101   return false;
    102 }
    103 
    104 unsigned WebAssemblyInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
    105   MachineBasicBlock::instr_iterator I = MBB.instr_end();
    106   unsigned Count = 0;
    107 
    108   while (I != MBB.instr_begin()) {
    109     --I;
    110     if (I->isDebugValue())
    111       continue;
    112     if (!I->isTerminator())
    113       break;
    114     // Remove the branch.
    115     I->eraseFromParent();
    116     I = MBB.instr_end();
    117     ++Count;
    118   }
    119 
    120   return Count;
    121 }
    122 
    123 unsigned WebAssemblyInstrInfo::InsertBranch(MachineBasicBlock &MBB,
    124                                             MachineBasicBlock *TBB,
    125                                             MachineBasicBlock *FBB,
    126                                             ArrayRef<MachineOperand> Cond,
    127                                             DebugLoc DL) const {
    128   if (Cond.empty()) {
    129     if (!TBB)
    130       return 0;
    131 
    132     BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(TBB);
    133     return 1;
    134   }
    135 
    136   assert(Cond.size() == 2 && "Expected a flag and a successor block");
    137 
    138   if (Cond[0].getImm()) {
    139     BuildMI(&MBB, DL, get(WebAssembly::BR_IF))
    140         .addOperand(Cond[1])
    141         .addMBB(TBB);
    142   } else {
    143     BuildMI(&MBB, DL, get(WebAssembly::BR_UNLESS))
    144         .addOperand(Cond[1])
    145         .addMBB(TBB);
    146   }
    147   if (!FBB)
    148     return 1;
    149 
    150   BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(FBB);
    151   return 2;
    152 }
    153 
    154 bool WebAssemblyInstrInfo::ReverseBranchCondition(
    155     SmallVectorImpl<MachineOperand> &Cond) const {
    156   assert(Cond.size() == 2 && "Expected a flag and a successor block");
    157   Cond.front() = MachineOperand::CreateImm(!Cond.front().getImm());
    158   return false;
    159 }
    160