xref: /aosp_15_r20/external/llvm/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- WebAssemblyRegNumbering.cpp - Register Numbering ------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker ///
10*9880d681SAndroid Build Coastguard Worker /// \file
11*9880d681SAndroid Build Coastguard Worker /// \brief This file implements a pass which assigns WebAssembly register
12*9880d681SAndroid Build Coastguard Worker /// numbers for CodeGen virtual registers.
13*9880d681SAndroid Build Coastguard Worker ///
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker 
16*9880d681SAndroid Build Coastguard Worker #include "WebAssembly.h"
17*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
18*9880d681SAndroid Build Coastguard Worker #include "WebAssemblyMachineFunctionInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "WebAssemblySubtarget.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SCCIterator.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineLoopInfo.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
29*9880d681SAndroid Build Coastguard Worker using namespace llvm;
30*9880d681SAndroid Build Coastguard Worker 
31*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "wasm-reg-numbering"
32*9880d681SAndroid Build Coastguard Worker 
33*9880d681SAndroid Build Coastguard Worker namespace {
34*9880d681SAndroid Build Coastguard Worker class WebAssemblyRegNumbering final : public MachineFunctionPass {
getPassName() const35*9880d681SAndroid Build Coastguard Worker   const char *getPassName() const override {
36*9880d681SAndroid Build Coastguard Worker     return "WebAssembly Register Numbering";
37*9880d681SAndroid Build Coastguard Worker   }
38*9880d681SAndroid Build Coastguard Worker 
getAnalysisUsage(AnalysisUsage & AU) const39*9880d681SAndroid Build Coastguard Worker   void getAnalysisUsage(AnalysisUsage &AU) const override {
40*9880d681SAndroid Build Coastguard Worker     AU.setPreservesCFG();
41*9880d681SAndroid Build Coastguard Worker     MachineFunctionPass::getAnalysisUsage(AU);
42*9880d681SAndroid Build Coastguard Worker   }
43*9880d681SAndroid Build Coastguard Worker 
44*9880d681SAndroid Build Coastguard Worker   bool runOnMachineFunction(MachineFunction &MF) override;
45*9880d681SAndroid Build Coastguard Worker 
46*9880d681SAndroid Build Coastguard Worker public:
47*9880d681SAndroid Build Coastguard Worker   static char ID; // Pass identification, replacement for typeid
WebAssemblyRegNumbering()48*9880d681SAndroid Build Coastguard Worker   WebAssemblyRegNumbering() : MachineFunctionPass(ID) {}
49*9880d681SAndroid Build Coastguard Worker };
50*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
51*9880d681SAndroid Build Coastguard Worker 
52*9880d681SAndroid Build Coastguard Worker char WebAssemblyRegNumbering::ID = 0;
createWebAssemblyRegNumbering()53*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createWebAssemblyRegNumbering() {
54*9880d681SAndroid Build Coastguard Worker   return new WebAssemblyRegNumbering();
55*9880d681SAndroid Build Coastguard Worker }
56*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(MachineFunction & MF)57*9880d681SAndroid Build Coastguard Worker bool WebAssemblyRegNumbering::runOnMachineFunction(MachineFunction &MF) {
58*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "********** Register Numbering **********\n"
59*9880d681SAndroid Build Coastguard Worker                   "********** Function: "
60*9880d681SAndroid Build Coastguard Worker                << MF.getName() << '\n');
61*9880d681SAndroid Build Coastguard Worker 
62*9880d681SAndroid Build Coastguard Worker   WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
63*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF.getRegInfo();
64*9880d681SAndroid Build Coastguard Worker 
65*9880d681SAndroid Build Coastguard Worker   MFI.initWARegs();
66*9880d681SAndroid Build Coastguard Worker 
67*9880d681SAndroid Build Coastguard Worker   // WebAssembly argument registers are in the same index space as local
68*9880d681SAndroid Build Coastguard Worker   // variables. Assign the numbers for them first.
69*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &EntryMBB = MF.front();
70*9880d681SAndroid Build Coastguard Worker   for (MachineInstr &MI : EntryMBB) {
71*9880d681SAndroid Build Coastguard Worker     switch (MI.getOpcode()) {
72*9880d681SAndroid Build Coastguard Worker     case WebAssembly::ARGUMENT_I32:
73*9880d681SAndroid Build Coastguard Worker     case WebAssembly::ARGUMENT_I64:
74*9880d681SAndroid Build Coastguard Worker     case WebAssembly::ARGUMENT_F32:
75*9880d681SAndroid Build Coastguard Worker     case WebAssembly::ARGUMENT_F64: {
76*9880d681SAndroid Build Coastguard Worker       int64_t Imm = MI.getOperand(1).getImm();
77*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << "Arg VReg " << MI.getOperand(0).getReg() << " -> WAReg "
78*9880d681SAndroid Build Coastguard Worker                    << Imm << "\n");
79*9880d681SAndroid Build Coastguard Worker       MFI.setWAReg(MI.getOperand(0).getReg(), Imm);
80*9880d681SAndroid Build Coastguard Worker       break;
81*9880d681SAndroid Build Coastguard Worker     }
82*9880d681SAndroid Build Coastguard Worker     default:
83*9880d681SAndroid Build Coastguard Worker       break;
84*9880d681SAndroid Build Coastguard Worker     }
85*9880d681SAndroid Build Coastguard Worker   }
86*9880d681SAndroid Build Coastguard Worker 
87*9880d681SAndroid Build Coastguard Worker   // Then assign regular WebAssembly registers for all remaining used
88*9880d681SAndroid Build Coastguard Worker   // virtual registers. TODO: Consider sorting the registers by frequency of
89*9880d681SAndroid Build Coastguard Worker   // use, to maximize usage of small immediate fields.
90*9880d681SAndroid Build Coastguard Worker   unsigned NumVRegs = MF.getRegInfo().getNumVirtRegs();
91*9880d681SAndroid Build Coastguard Worker   unsigned NumStackRegs = 0;
92*9880d681SAndroid Build Coastguard Worker   // Start the numbering for locals after the arg regs
93*9880d681SAndroid Build Coastguard Worker   unsigned CurReg = MFI.getParams().size();
94*9880d681SAndroid Build Coastguard Worker   for (unsigned VRegIdx = 0; VRegIdx < NumVRegs; ++VRegIdx) {
95*9880d681SAndroid Build Coastguard Worker     unsigned VReg = TargetRegisterInfo::index2VirtReg(VRegIdx);
96*9880d681SAndroid Build Coastguard Worker     // Skip unused registers.
97*9880d681SAndroid Build Coastguard Worker     if (MRI.use_empty(VReg))
98*9880d681SAndroid Build Coastguard Worker       continue;
99*9880d681SAndroid Build Coastguard Worker     // Handle stackified registers.
100*9880d681SAndroid Build Coastguard Worker     if (MFI.isVRegStackified(VReg)) {
101*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << "VReg " << VReg << " -> WAReg "
102*9880d681SAndroid Build Coastguard Worker                    << (INT32_MIN | NumStackRegs) << "\n");
103*9880d681SAndroid Build Coastguard Worker       MFI.setWAReg(VReg, INT32_MIN | NumStackRegs++);
104*9880d681SAndroid Build Coastguard Worker       continue;
105*9880d681SAndroid Build Coastguard Worker     }
106*9880d681SAndroid Build Coastguard Worker     if (MFI.getWAReg(VReg) == WebAssemblyFunctionInfo::UnusedReg) {
107*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << "VReg " << VReg << " -> WAReg " << CurReg << "\n");
108*9880d681SAndroid Build Coastguard Worker       MFI.setWAReg(VReg, CurReg++);
109*9880d681SAndroid Build Coastguard Worker     }
110*9880d681SAndroid Build Coastguard Worker   }
111*9880d681SAndroid Build Coastguard Worker 
112*9880d681SAndroid Build Coastguard Worker   return true;
113*9880d681SAndroid Build Coastguard Worker }
114