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