//===-- 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 "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblyUtilities.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Analysis.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "wasm-reg-numbering"

namespace {
class WebAssemblyRegNumberingLegacy 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
  WebAssemblyRegNumberingLegacy() : MachineFunctionPass(ID) {}
};
} // end anonymous namespace

char WebAssemblyRegNumberingLegacy::ID = 0;
INITIALIZE_PASS(WebAssemblyRegNumberingLegacy, DEBUG_TYPE,
                "Assigns WebAssembly register numbers for virtual registers",
                false, false)

FunctionPass *llvm::createWebAssemblyRegNumberingLegacyPass() {
  return new WebAssemblyRegNumberingLegacy();
}

static bool regNumbering(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 " << printReg(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 " << printReg(VReg) << " -> WAReg "
                        << (INT32_MIN | NumStackRegs) << "\n");
      MFI.setWAReg(VReg, INT32_MIN | NumStackRegs++);
      continue;
    }
    if (MFI.getWAReg(VReg) == WebAssembly::UnusedReg) {
      LLVM_DEBUG(dbgs() << "VReg " << printReg(VReg) << " -> WAReg " << CurReg
                        << "\n");
      MFI.setWAReg(VReg, CurReg++);
    }
  }

  return true;
}

bool WebAssemblyRegNumberingLegacy::runOnMachineFunction(MachineFunction &MF) {
  return regNumbering(MF);
}

PreservedAnalyses
WebAssemblyRegNumberingPass::run(MachineFunction &MF,
                                 MachineFunctionAnalysisManager &MFAM) {
  return regNumbering(MF) ? getMachineFunctionPassPreservedAnalyses()
                                .preserveSet<CFGAnalyses>()
                          : PreservedAnalyses::all();
}
