1 //===-- WebAssemblyRegNumbering.cpp - Register Numbering ------------------===//
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-exception
7 //===----------------------------------------------------------------------===//
10 /// This file implements a pass which assigns WebAssembly register
11 /// numbers for CodeGen virtual registers.
13 //===----------------------------------------------------------------------===//
15 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
16 #include "Utils/WebAssemblyUtilities.h"
17 #include "WebAssembly.h"
18 #include "WebAssemblyMachineFunctionInfo.h"
19 #include "WebAssemblySubtarget.h"
20 #include "llvm/ADT/SCCIterator.h"
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineInstrBuilder.h"
24 #include "llvm/CodeGen/MachineLoopInfo.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/Passes.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/raw_ostream.h"
31 #define DEBUG_TYPE "wasm-reg-numbering"
34 class WebAssemblyRegNumbering final
: public MachineFunctionPass
{
35 StringRef
getPassName() const override
{
36 return "WebAssembly Register Numbering";
39 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
41 MachineFunctionPass::getAnalysisUsage(AU
);
44 bool runOnMachineFunction(MachineFunction
&MF
) override
;
47 static char ID
; // Pass identification, replacement for typeid
48 WebAssemblyRegNumbering() : MachineFunctionPass(ID
) {}
50 } // end anonymous namespace
52 char WebAssemblyRegNumbering::ID
= 0;
53 INITIALIZE_PASS(WebAssemblyRegNumbering
, DEBUG_TYPE
,
54 "Assigns WebAssembly register numbers for virtual registers",
57 FunctionPass
*llvm::createWebAssemblyRegNumbering() {
58 return new WebAssemblyRegNumbering();
61 bool WebAssemblyRegNumbering::runOnMachineFunction(MachineFunction
&MF
) {
62 LLVM_DEBUG(dbgs() << "********** Register Numbering **********\n"
63 "********** Function: "
64 << MF
.getName() << '\n');
66 WebAssemblyFunctionInfo
&MFI
= *MF
.getInfo
<WebAssemblyFunctionInfo
>();
67 MachineRegisterInfo
&MRI
= MF
.getRegInfo();
71 // WebAssembly argument registers are in the same index space as local
72 // variables. Assign the numbers for them first.
73 MachineBasicBlock
&EntryMBB
= MF
.front();
74 for (MachineInstr
&MI
: EntryMBB
) {
75 if (!WebAssembly::isArgument(MI
.getOpcode()))
78 int64_t Imm
= MI
.getOperand(1).getImm();
79 LLVM_DEBUG(dbgs() << "Arg VReg " << MI
.getOperand(0).getReg()
80 << " -> WAReg " << Imm
<< "\n");
81 MFI
.setWAReg(MI
.getOperand(0).getReg(), Imm
);
84 // Then assign regular WebAssembly registers for all remaining used
85 // virtual registers. TODO: Consider sorting the registers by frequency of
86 // use, to maximize usage of small immediate fields.
87 unsigned NumVRegs
= MF
.getRegInfo().getNumVirtRegs();
88 unsigned NumStackRegs
= 0;
89 // Start the numbering for locals after the arg regs
90 unsigned CurReg
= MFI
.getParams().size();
91 for (unsigned VRegIdx
= 0; VRegIdx
< NumVRegs
; ++VRegIdx
) {
92 Register VReg
= Register::index2VirtReg(VRegIdx
);
93 // Skip unused registers.
94 if (MRI
.use_empty(VReg
))
96 // Handle stackified registers.
97 if (MFI
.isVRegStackified(VReg
)) {
98 LLVM_DEBUG(dbgs() << "VReg " << VReg
<< " -> WAReg "
99 << (INT32_MIN
| NumStackRegs
) << "\n");
100 MFI
.setWAReg(VReg
, INT32_MIN
| NumStackRegs
++);
103 if (MFI
.getWAReg(VReg
) == WebAssemblyFunctionInfo::UnusedReg
) {
104 LLVM_DEBUG(dbgs() << "VReg " << VReg
<< " -> WAReg " << CurReg
<< "\n");
105 MFI
.setWAReg(VReg
, CurReg
++);