123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- //===-- 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 "Utils/WebAssemblyUtilities.h"
- #include "WebAssembly.h"
- #include "WebAssemblyMachineFunctionInfo.h"
- #include "WebAssemblySubtarget.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(MRI);
- // 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) {
- Register 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;
- }
|