LCOV - code coverage report
Current view: top level - lib/Target/WebAssembly - WebAssemblyInstrInfo.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 63 64 98.4 %
Date: 2018-10-20 13:21:21 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : /// 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 "WebAssemblyMachineFunctionInfo.h"
      19             : #include "WebAssemblySubtarget.h"
      20             : #include "llvm/CodeGen/MachineFrameInfo.h"
      21             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      22             : #include "llvm/CodeGen/MachineMemOperand.h"
      23             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      24             : using namespace llvm;
      25             : 
      26             : #define DEBUG_TYPE "wasm-instr-info"
      27             : 
      28             : #define GET_INSTRINFO_CTOR_DTOR
      29             : #include "WebAssemblyGenInstrInfo.inc"
      30             : 
      31         293 : WebAssemblyInstrInfo::WebAssemblyInstrInfo(const WebAssemblySubtarget &STI)
      32             :     : WebAssemblyGenInstrInfo(WebAssembly::ADJCALLSTACKDOWN,
      33             :                               WebAssembly::ADJCALLSTACKUP,
      34             :                               WebAssembly::CATCHRET),
      35         293 :       RI(STI.getTargetTriple()) {}
      36             : 
      37        1654 : bool WebAssemblyInstrInfo::isReallyTriviallyReMaterializable(
      38             :     const MachineInstr &MI, AliasAnalysis *AA) const {
      39        1654 :   switch (MI.getOpcode()) {
      40             :   case WebAssembly::CONST_I32:
      41             :   case WebAssembly::CONST_I64:
      42             :   case WebAssembly::CONST_F32:
      43             :   case WebAssembly::CONST_F64:
      44             :     // isReallyTriviallyReMaterializableGeneric misses these because of the
      45             :     // ARGUMENTS implicit def, so we manualy override it here.
      46             :     return true;
      47             :   default:
      48             :     return false;
      49             :   }
      50             : }
      51             : 
      52          76 : void WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
      53             :                                        MachineBasicBlock::iterator I,
      54             :                                        const DebugLoc &DL, unsigned DestReg,
      55             :                                        unsigned SrcReg, bool KillSrc) const {
      56             :   // This method is called by post-RA expansion, which expects only pregs to
      57             :   // exist. However we need to handle both here.
      58          76 :   auto &MRI = MBB.getParent()->getRegInfo();
      59             :   const TargetRegisterClass *RC =
      60             :       TargetRegisterInfo::isVirtualRegister(DestReg)
      61          76 :           ? MRI.getRegClass(DestReg)
      62          18 :           : MRI.getTargetRegisterInfo()->getMinimalPhysRegClass(DestReg);
      63             : 
      64             :   unsigned CopyOpcode;
      65          76 :   if (RC == &WebAssembly::I32RegClass)
      66             :     CopyOpcode = WebAssembly::COPY_I32;
      67          11 :   else if (RC == &WebAssembly::I64RegClass)
      68             :     CopyOpcode = WebAssembly::COPY_I64;
      69           6 :   else if (RC == &WebAssembly::F32RegClass)
      70             :     CopyOpcode = WebAssembly::COPY_F32;
      71           6 :   else if (RC == &WebAssembly::F64RegClass)
      72             :     CopyOpcode = WebAssembly::COPY_F64;
      73             :   else
      74           0 :     llvm_unreachable("Unexpected register class");
      75             : 
      76         152 :   BuildMI(MBB, I, DL, get(CopyOpcode), DestReg)
      77         152 :       .addReg(SrcReg, KillSrc ? RegState::Kill : 0);
      78          76 : }
      79             : 
      80        6908 : MachineInstr *WebAssemblyInstrInfo::commuteInstructionImpl(
      81             :     MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const {
      82             :   // If the operands are stackified, we can't reorder them.
      83             :   WebAssemblyFunctionInfo &MFI =
      84        6908 :       *MI.getParent()->getParent()->getInfo<WebAssemblyFunctionInfo>();
      85       13840 :   if (MFI.isVRegStackified(MI.getOperand(OpIdx1).getReg()) ||
      86        6908 :       MFI.isVRegStackified(MI.getOperand(OpIdx2).getReg()))
      87             :     return nullptr;
      88             : 
      89             :   // Otherwise use the default implementation.
      90        6908 :   return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
      91             : }
      92             : 
      93             : // Branch analysis.
      94       31947 : bool WebAssemblyInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
      95             :                                          MachineBasicBlock *&TBB,
      96             :                                          MachineBasicBlock *&FBB,
      97             :                                          SmallVectorImpl<MachineOperand> &Cond,
      98             :                                          bool /*AllowModify*/) const {
      99             :   bool HaveCond = false;
     100       40694 :   for (MachineInstr &MI : MBB.terminators()) {
     101       59834 :     switch (MI.getOpcode()) {
     102             :     default:
     103             :       // Unhandled instruction; bail out.
     104             :       return true;
     105        7290 :     case WebAssembly::BR_IF:
     106        7290 :       if (HaveCond)
     107             :         return true;
     108             :       // If we're running after CFGStackify, we can't optimize further.
     109       14580 :       if (!MI.getOperand(0).isMBB())
     110             :         return true;
     111       13376 :       Cond.push_back(MachineOperand::CreateImm(true));
     112       13376 :       Cond.push_back(MI.getOperand(1));
     113        6688 :       TBB = MI.getOperand(0).getMBB();
     114             :       HaveCond = true;
     115        6688 :       break;
     116        2103 :     case WebAssembly::BR_UNLESS:
     117        2103 :       if (HaveCond)
     118             :         return true;
     119             :       // If we're running after CFGStackify, we can't optimize further.
     120        4206 :       if (!MI.getOperand(0).isMBB())
     121             :         return true;
     122        4118 :       Cond.push_back(MachineOperand::CreateImm(false));
     123        4118 :       Cond.push_back(MI.getOperand(1));
     124        2059 :       TBB = MI.getOperand(0).getMBB();
     125             :       HaveCond = true;
     126        2059 :       break;
     127        5618 :     case WebAssembly::BR:
     128             :       // If we're running after CFGStackify, we can't optimize further.
     129       11236 :       if (!MI.getOperand(0).isMBB())
     130             :         return true;
     131        5392 :       if (!HaveCond)
     132        2308 :         TBB = MI.getOperand(0).getMBB();
     133             :       else
     134        3084 :         FBB = MI.getOperand(0).getMBB();
     135             :       break;
     136             :     }
     137       14139 :     if (MI.isBarrier())
     138             :       break;
     139             :   }
     140             : 
     141             :   return false;
     142             : }
     143             : 
     144         938 : unsigned WebAssemblyInstrInfo::removeBranch(MachineBasicBlock &MBB,
     145             :                                             int *BytesRemoved) const {
     146             :   assert(!BytesRemoved && "code size not handled");
     147             : 
     148             :   MachineBasicBlock::instr_iterator I = MBB.instr_end();
     149             :   unsigned Count = 0;
     150             : 
     151        2154 :   while (I != MBB.instr_begin()) {
     152             :     --I;
     153             :     if (I->isDebugInstr())
     154             :       continue;
     155        2026 :     if (!I->isTerminator())
     156             :       break;
     157             :     // Remove the branch.
     158        1206 :     I->eraseFromParent();
     159             :     I = MBB.instr_end();
     160        1206 :     ++Count;
     161             :   }
     162             : 
     163         938 :   return Count;
     164             : }
     165             : 
     166         920 : unsigned WebAssemblyInstrInfo::insertBranch(
     167             :     MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
     168             :     ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
     169             :   assert(!BytesAdded && "code size not handled");
     170             : 
     171         920 :   if (Cond.empty()) {
     172         259 :     if (!TBB)
     173             :       return 0;
     174             : 
     175         259 :     BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(TBB);
     176         259 :     return 1;
     177             :   }
     178             : 
     179             :   assert(Cond.size() == 2 && "Expected a flag and a successor block");
     180             : 
     181         661 :   if (Cond[0].getImm()) {
     182         350 :     BuildMI(&MBB, DL, get(WebAssembly::BR_IF)).addMBB(TBB).add(Cond[1]);
     183             :   } else {
     184         311 :     BuildMI(&MBB, DL, get(WebAssembly::BR_UNLESS)).addMBB(TBB).add(Cond[1]);
     185             :   }
     186         661 :   if (!FBB)
     187             :     return 1;
     188             : 
     189          24 :   BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(FBB);
     190          24 :   return 2;
     191             : }
     192             : 
     193         492 : bool WebAssemblyInstrInfo::reverseBranchCondition(
     194             :     SmallVectorImpl<MachineOperand> &Cond) const {
     195             :   assert(Cond.size() == 2 && "Expected a flag and a successor block");
     196         492 :   Cond.front() = MachineOperand::CreateImm(!Cond.front().getImm());
     197         492 :   return false;
     198             : }

Generated by: LCOV version 1.13