diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp')
| -rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp | 110 | 
1 files changed, 110 insertions, 0 deletions
| diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp new file mode 100644 index 000000000000..72e7a7cf5042 --- /dev/null +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp @@ -0,0 +1,110 @@ +//===-- WebAssemblyRegNumbering.cpp - Register Numbering ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file implements a pass which assigns WebAssembly register +/// numbers for CodeGen virtual registers. +/// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" +#include "WebAssembly.h" +#include "WebAssemblyMachineFunctionInfo.h" +#include "WebAssemblySubtarget.h" +#include "WebAssemblyUtilities.h" +#include "llvm/ADT/SCCIterator.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +#define DEBUG_TYPE "wasm-reg-numbering" + +namespace { +class WebAssemblyRegNumbering final : public MachineFunctionPass { +  StringRef getPassName() const override { +    return "WebAssembly Register Numbering"; +  } + +  void getAnalysisUsage(AnalysisUsage &AU) const override { +    AU.setPreservesCFG(); +    MachineFunctionPass::getAnalysisUsage(AU); +  } + +  bool runOnMachineFunction(MachineFunction &MF) override; + +public: +  static char ID; // Pass identification, replacement for typeid +  WebAssemblyRegNumbering() : MachineFunctionPass(ID) {} +}; +} // end anonymous namespace + +char WebAssemblyRegNumbering::ID = 0; +INITIALIZE_PASS(WebAssemblyRegNumbering, DEBUG_TYPE, +                "Assigns WebAssembly register numbers for virtual registers", +                false, false) + +FunctionPass *llvm::createWebAssemblyRegNumbering() { +  return new WebAssemblyRegNumbering(); +} + +bool WebAssemblyRegNumbering::runOnMachineFunction(MachineFunction &MF) { +  LLVM_DEBUG(dbgs() << "********** Register Numbering **********\n" +                       "********** Function: " +                    << MF.getName() << '\n'); + +  WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>(); +  MachineRegisterInfo &MRI = MF.getRegInfo(); + +  MFI.initWARegs(); + +  // WebAssembly argument registers are in the same index space as local +  // variables. Assign the numbers for them first. +  MachineBasicBlock &EntryMBB = MF.front(); +  for (MachineInstr &MI : EntryMBB) { +    if (!WebAssembly::isArgument(MI.getOpcode())) +      break; + +    int64_t Imm = MI.getOperand(1).getImm(); +    LLVM_DEBUG(dbgs() << "Arg VReg " << MI.getOperand(0).getReg() +                      << " -> WAReg " << Imm << "\n"); +    MFI.setWAReg(MI.getOperand(0).getReg(), Imm); +  } + +  // Then assign regular WebAssembly registers for all remaining used +  // virtual registers. TODO: Consider sorting the registers by frequency of +  // use, to maximize usage of small immediate fields. +  unsigned NumVRegs = MF.getRegInfo().getNumVirtRegs(); +  unsigned NumStackRegs = 0; +  // Start the numbering for locals after the arg regs +  unsigned CurReg = MFI.getParams().size(); +  for (unsigned VRegIdx = 0; VRegIdx < NumVRegs; ++VRegIdx) { +    unsigned VReg = Register::index2VirtReg(VRegIdx); +    // Skip unused registers. +    if (MRI.use_empty(VReg)) +      continue; +    // Handle stackified registers. +    if (MFI.isVRegStackified(VReg)) { +      LLVM_DEBUG(dbgs() << "VReg " << VReg << " -> WAReg " +                        << (INT32_MIN | NumStackRegs) << "\n"); +      MFI.setWAReg(VReg, INT32_MIN | NumStackRegs++); +      continue; +    } +    if (MFI.getWAReg(VReg) == WebAssemblyFunctionInfo::UnusedReg) { +      LLVM_DEBUG(dbgs() << "VReg " << VReg << " -> WAReg " << CurReg << "\n"); +      MFI.setWAReg(VReg, CurReg++); +    } +  } + +  return true; +} | 
