WebAssemblyRegNumbering.cpp revision 309124
1292915Sdim//===-- WebAssemblyRegNumbering.cpp - Register Numbering ------------------===// 2292915Sdim// 3292915Sdim// The LLVM Compiler Infrastructure 4292915Sdim// 5292915Sdim// This file is distributed under the University of Illinois Open Source 6292915Sdim// License. See LICENSE.TXT for details. 7292915Sdim// 8292915Sdim//===----------------------------------------------------------------------===// 9292915Sdim/// 10292915Sdim/// \file 11292915Sdim/// \brief This file implements a pass which assigns WebAssembly register 12292915Sdim/// numbers for CodeGen virtual registers. 13292915Sdim/// 14292915Sdim//===----------------------------------------------------------------------===// 15292915Sdim 16292915Sdim#include "WebAssembly.h" 17292915Sdim#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 18292915Sdim#include "WebAssemblyMachineFunctionInfo.h" 19292915Sdim#include "WebAssemblySubtarget.h" 20292915Sdim#include "llvm/ADT/SCCIterator.h" 21309124Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 22292915Sdim#include "llvm/CodeGen/MachineFunction.h" 23292915Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 24292915Sdim#include "llvm/CodeGen/MachineLoopInfo.h" 25292915Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 26292915Sdim#include "llvm/CodeGen/Passes.h" 27292915Sdim#include "llvm/Support/Debug.h" 28292915Sdim#include "llvm/Support/raw_ostream.h" 29292915Sdimusing namespace llvm; 30292915Sdim 31292915Sdim#define DEBUG_TYPE "wasm-reg-numbering" 32292915Sdim 33292915Sdimnamespace { 34292915Sdimclass WebAssemblyRegNumbering final : public MachineFunctionPass { 35292915Sdim const char *getPassName() const override { 36292915Sdim return "WebAssembly Register Numbering"; 37292915Sdim } 38292915Sdim 39292915Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 40292915Sdim AU.setPreservesCFG(); 41292915Sdim MachineFunctionPass::getAnalysisUsage(AU); 42292915Sdim } 43292915Sdim 44292915Sdim bool runOnMachineFunction(MachineFunction &MF) override; 45292915Sdim 46292915Sdimpublic: 47292915Sdim static char ID; // Pass identification, replacement for typeid 48292915Sdim WebAssemblyRegNumbering() : MachineFunctionPass(ID) {} 49292915Sdim}; 50292915Sdim} // end anonymous namespace 51292915Sdim 52292915Sdimchar WebAssemblyRegNumbering::ID = 0; 53292915SdimFunctionPass *llvm::createWebAssemblyRegNumbering() { 54292915Sdim return new WebAssemblyRegNumbering(); 55292915Sdim} 56292915Sdim 57292915Sdimbool WebAssemblyRegNumbering::runOnMachineFunction(MachineFunction &MF) { 58292915Sdim DEBUG(dbgs() << "********** Register Numbering **********\n" 59292915Sdim "********** Function: " 60292915Sdim << MF.getName() << '\n'); 61292915Sdim 62292915Sdim WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>(); 63292915Sdim MachineRegisterInfo &MRI = MF.getRegInfo(); 64292915Sdim 65292915Sdim MFI.initWARegs(); 66292915Sdim 67292915Sdim // WebAssembly argument registers are in the same index space as local 68292915Sdim // variables. Assign the numbers for them first. 69292915Sdim MachineBasicBlock &EntryMBB = MF.front(); 70292915Sdim for (MachineInstr &MI : EntryMBB) { 71292915Sdim switch (MI.getOpcode()) { 72292915Sdim case WebAssembly::ARGUMENT_I32: 73292915Sdim case WebAssembly::ARGUMENT_I64: 74292915Sdim case WebAssembly::ARGUMENT_F32: 75309124Sdim case WebAssembly::ARGUMENT_F64: { 76309124Sdim int64_t Imm = MI.getOperand(1).getImm(); 77309124Sdim DEBUG(dbgs() << "Arg VReg " << MI.getOperand(0).getReg() << " -> WAReg " 78309124Sdim << Imm << "\n"); 79309124Sdim MFI.setWAReg(MI.getOperand(0).getReg(), Imm); 80292915Sdim break; 81309124Sdim } 82292915Sdim default: 83292915Sdim break; 84292915Sdim } 85292915Sdim } 86292915Sdim 87292915Sdim // Then assign regular WebAssembly registers for all remaining used 88292915Sdim // virtual registers. TODO: Consider sorting the registers by frequency of 89292915Sdim // use, to maximize usage of small immediate fields. 90292915Sdim unsigned NumVRegs = MF.getRegInfo().getNumVirtRegs(); 91292915Sdim unsigned NumStackRegs = 0; 92309124Sdim // Start the numbering for locals after the arg regs 93309124Sdim unsigned CurReg = MFI.getParams().size(); 94292915Sdim for (unsigned VRegIdx = 0; VRegIdx < NumVRegs; ++VRegIdx) { 95292915Sdim unsigned VReg = TargetRegisterInfo::index2VirtReg(VRegIdx); 96309124Sdim // Skip unused registers. 97309124Sdim if (MRI.use_empty(VReg)) 98309124Sdim continue; 99292915Sdim // Handle stackified registers. 100292915Sdim if (MFI.isVRegStackified(VReg)) { 101309124Sdim DEBUG(dbgs() << "VReg " << VReg << " -> WAReg " 102309124Sdim << (INT32_MIN | NumStackRegs) << "\n"); 103292915Sdim MFI.setWAReg(VReg, INT32_MIN | NumStackRegs++); 104292915Sdim continue; 105292915Sdim } 106309124Sdim if (MFI.getWAReg(VReg) == WebAssemblyFunctionInfo::UnusedReg) { 107309124Sdim DEBUG(dbgs() << "VReg " << VReg << " -> WAReg " << CurReg << "\n"); 108309124Sdim MFI.setWAReg(VReg, CurReg++); 109309124Sdim } 110292915Sdim } 111292915Sdim 112292915Sdim return true; 113292915Sdim} 114