brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · 17a9144 Raw
108 lines · cpp
1//===-- WebAssemblyRegNumbering.cpp - Register Numbering ------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file implements a pass which assigns WebAssembly register11/// numbers for CodeGen virtual registers.12///13//===----------------------------------------------------------------------===//14 15#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"16#include "WebAssembly.h"17#include "WebAssemblyMachineFunctionInfo.h"18#include "WebAssemblyUtilities.h"19#include "llvm/CodeGen/MachineFrameInfo.h"20#include "llvm/CodeGen/MachineFunction.h"21#include "llvm/CodeGen/MachineRegisterInfo.h"22#include "llvm/CodeGen/Passes.h"23#include "llvm/Support/Debug.h"24#include "llvm/Support/raw_ostream.h"25using namespace llvm;26 27#define DEBUG_TYPE "wasm-reg-numbering"28 29namespace {30class WebAssemblyRegNumbering final : public MachineFunctionPass {31  StringRef getPassName() const override {32    return "WebAssembly Register Numbering";33  }34 35  void getAnalysisUsage(AnalysisUsage &AU) const override {36    AU.setPreservesCFG();37    MachineFunctionPass::getAnalysisUsage(AU);38  }39 40  bool runOnMachineFunction(MachineFunction &MF) override;41 42public:43  static char ID; // Pass identification, replacement for typeid44  WebAssemblyRegNumbering() : MachineFunctionPass(ID) {}45};46} // end anonymous namespace47 48char WebAssemblyRegNumbering::ID = 0;49INITIALIZE_PASS(WebAssemblyRegNumbering, DEBUG_TYPE,50                "Assigns WebAssembly register numbers for virtual registers",51                false, false)52 53FunctionPass *llvm::createWebAssemblyRegNumbering() {54  return new WebAssemblyRegNumbering();55}56 57bool WebAssemblyRegNumbering::runOnMachineFunction(MachineFunction &MF) {58  LLVM_DEBUG(dbgs() << "********** Register Numbering **********\n"59                       "********** Function: "60                    << MF.getName() << '\n');61 62  WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();63  MachineRegisterInfo &MRI = MF.getRegInfo();64 65  MFI.initWARegs(MRI);66 67  // WebAssembly argument registers are in the same index space as local68  // variables. Assign the numbers for them first.69  MachineBasicBlock &EntryMBB = MF.front();70  for (MachineInstr &MI : EntryMBB) {71    if (!WebAssembly::isArgument(MI.getOpcode()))72      break;73 74    int64_t Imm = MI.getOperand(1).getImm();75    LLVM_DEBUG(dbgs() << "Arg VReg " << printReg(MI.getOperand(0).getReg())76                      << " -> WAReg " << Imm << "\n");77    MFI.setWAReg(MI.getOperand(0).getReg(), Imm);78  }79 80  // Then assign regular WebAssembly registers for all remaining used81  // virtual registers. TODO: Consider sorting the registers by frequency of82  // use, to maximize usage of small immediate fields.83  unsigned NumVRegs = MF.getRegInfo().getNumVirtRegs();84  unsigned NumStackRegs = 0;85  // Start the numbering for locals after the arg regs86  unsigned CurReg = MFI.getParams().size();87  for (unsigned VRegIdx = 0; VRegIdx < NumVRegs; ++VRegIdx) {88    Register VReg = Register::index2VirtReg(VRegIdx);89    // Skip unused registers.90    if (MRI.use_empty(VReg))91      continue;92    // Handle stackified registers.93    if (MFI.isVRegStackified(VReg)) {94      LLVM_DEBUG(dbgs() << "VReg " << printReg(VReg) << " -> WAReg "95                        << (INT32_MIN | NumStackRegs) << "\n");96      MFI.setWAReg(VReg, INT32_MIN | NumStackRegs++);97      continue;98    }99    if (MFI.getWAReg(VReg) == WebAssembly::UnusedReg) {100      LLVM_DEBUG(dbgs() << "VReg " << printReg(VReg) << " -> WAReg " << CurReg101                        << "\n");102      MFI.setWAReg(VReg, CurReg++);103    }104  }105 106  return true;107}108