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