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