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

          Line data    Source code
       1             : //===-- WebAssemblyRegNumbering.cpp - Register Numbering ------------------===//
       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 implements a pass which assigns WebAssembly register
      12             : /// numbers for CodeGen virtual registers.
      13             : ///
      14             : //===----------------------------------------------------------------------===//
      15             : 
      16             : #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
      17             : #include "WebAssembly.h"
      18             : #include "WebAssemblyMachineFunctionInfo.h"
      19             : #include "WebAssemblySubtarget.h"
      20             : #include "WebAssemblyUtilities.h"
      21             : #include "llvm/ADT/SCCIterator.h"
      22             : #include "llvm/CodeGen/MachineFrameInfo.h"
      23             : #include "llvm/CodeGen/MachineFunction.h"
      24             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      25             : #include "llvm/CodeGen/MachineLoopInfo.h"
      26             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      27             : #include "llvm/CodeGen/Passes.h"
      28             : #include "llvm/Support/Debug.h"
      29             : #include "llvm/Support/raw_ostream.h"
      30             : using namespace llvm;
      31             : 
      32             : #define DEBUG_TYPE "wasm-reg-numbering"
      33             : 
      34             : namespace {
      35             : class WebAssemblyRegNumbering final : public MachineFunctionPass {
      36         304 :   StringRef getPassName() const override {
      37         304 :     return "WebAssembly Register Numbering";
      38             :   }
      39             : 
      40         304 :   void getAnalysisUsage(AnalysisUsage &AU) const override {
      41         304 :     AU.setPreservesCFG();
      42         304 :     MachineFunctionPass::getAnalysisUsage(AU);
      43         304 :   }
      44             : 
      45             :   bool runOnMachineFunction(MachineFunction &MF) override;
      46             : 
      47             : public:
      48             :   static char ID; // Pass identification, replacement for typeid
      49         305 :   WebAssemblyRegNumbering() : MachineFunctionPass(ID) {}
      50             : };
      51             : } // end anonymous namespace
      52             : 
      53             : char WebAssemblyRegNumbering::ID = 0;
      54      199030 : INITIALIZE_PASS(WebAssemblyRegNumbering, DEBUG_TYPE,
      55             :                 "Assigns WebAssembly register numbers for virtual registers",
      56             :                 false, false)
      57             : 
      58         305 : FunctionPass *llvm::createWebAssemblyRegNumbering() {
      59         305 :   return new WebAssemblyRegNumbering();
      60             : }
      61             : 
      62        2982 : bool WebAssemblyRegNumbering::runOnMachineFunction(MachineFunction &MF) {
      63             :   LLVM_DEBUG(dbgs() << "********** Register Numbering **********\n"
      64             :                        "********** Function: "
      65             :                     << MF.getName() << '\n');
      66             : 
      67             :   WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
      68        2982 :   MachineRegisterInfo &MRI = MF.getRegInfo();
      69             : 
      70        2982 :   MFI.initWARegs();
      71             : 
      72             :   // WebAssembly argument registers are in the same index space as local
      73             :   // variables. Assign the numbers for them first.
      74             :   MachineBasicBlock &EntryMBB = MF.front();
      75        9156 :   for (MachineInstr &MI : EntryMBB) {
      76        9147 :     if (!WebAssembly::isArgument(MI))
      77             :       break;
      78             : 
      79        6174 :     int64_t Imm = MI.getOperand(1).getImm();
      80             :     LLVM_DEBUG(dbgs() << "Arg VReg " << MI.getOperand(0).getReg()
      81             :                       << " -> WAReg " << Imm << "\n");
      82        6174 :     MFI.setWAReg(MI.getOperand(0).getReg(), Imm);
      83             :   }
      84             : 
      85             :   // Then assign regular WebAssembly registers for all remaining used
      86             :   // virtual registers. TODO: Consider sorting the registers by frequency of
      87             :   // use, to maximize usage of small immediate fields.
      88        2982 :   unsigned NumVRegs = MF.getRegInfo().getNumVirtRegs();
      89             :   unsigned NumStackRegs = 0;
      90             :   // Start the numbering for locals after the arg regs
      91        5964 :   unsigned CurReg = MFI.getParams().size();
      92       37538 :   for (unsigned VRegIdx = 0; VRegIdx < NumVRegs; ++VRegIdx) {
      93             :     unsigned VReg = TargetRegisterInfo::index2VirtReg(VRegIdx);
      94             :     // Skip unused registers.
      95       34556 :     if (MRI.use_empty(VReg))
      96             :       continue;
      97             :     // Handle stackified registers.
      98       20557 :     if (MFI.isVRegStackified(VReg)) {
      99             :       LLVM_DEBUG(dbgs() << "VReg " << VReg << " -> WAReg "
     100             :                         << (INT32_MIN | NumStackRegs) << "\n");
     101       14585 :       MFI.setWAReg(VReg, INT32_MIN | NumStackRegs++);
     102       14585 :       continue;
     103             :     }
     104        6371 :     if (MFI.getWAReg(VReg) == WebAssemblyFunctionInfo::UnusedReg) {
     105             :       LLVM_DEBUG(dbgs() << "VReg " << VReg << " -> WAReg " << CurReg << "\n");
     106         201 :       MFI.setWAReg(VReg, CurReg++);
     107             :     }
     108             :   }
     109             : 
     110        2982 :   return true;
     111             : }

Generated by: LCOV version 1.13