1cf4748f1SDan Gohman //===-- WebAssemblyRegNumbering.cpp - Register Numbering ------------------===// 2cf4748f1SDan Gohman // 3cf4748f1SDan Gohman // The LLVM Compiler Infrastructure 4cf4748f1SDan Gohman // 5cf4748f1SDan Gohman // This file is distributed under the University of Illinois Open Source 6cf4748f1SDan Gohman // License. See LICENSE.TXT for details. 7cf4748f1SDan Gohman // 8cf4748f1SDan Gohman //===----------------------------------------------------------------------===// 9cf4748f1SDan Gohman /// 10cf4748f1SDan Gohman /// \file 11cf4748f1SDan Gohman /// \brief This file implements a pass which assigns WebAssembly register 12cf4748f1SDan Gohman /// numbers for CodeGen virtual registers. 13cf4748f1SDan Gohman /// 14cf4748f1SDan Gohman //===----------------------------------------------------------------------===// 15cf4748f1SDan Gohman 16cf4748f1SDan Gohman #include "WebAssembly.h" 17cf4748f1SDan Gohman #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 18cf4748f1SDan Gohman #include "WebAssemblyMachineFunctionInfo.h" 19cf4748f1SDan Gohman #include "WebAssemblySubtarget.h" 20*4fc4e42dSDan Gohman #include "WebAssemblyUtilities.h" 21cf4748f1SDan Gohman #include "llvm/ADT/SCCIterator.h" 229769debfSDerek Schuff #include "llvm/CodeGen/MachineFrameInfo.h" 2383947569SDan Gohman #include "llvm/CodeGen/MachineFunction.h" 24cf4748f1SDan Gohman #include "llvm/CodeGen/MachineInstrBuilder.h" 25cf4748f1SDan Gohman #include "llvm/CodeGen/MachineLoopInfo.h" 26cf4748f1SDan Gohman #include "llvm/CodeGen/MachineRegisterInfo.h" 27cf4748f1SDan Gohman #include "llvm/CodeGen/Passes.h" 28cf4748f1SDan Gohman #include "llvm/Support/Debug.h" 29cf4748f1SDan Gohman #include "llvm/Support/raw_ostream.h" 30cf4748f1SDan Gohman using namespace llvm; 31cf4748f1SDan Gohman 32cf4748f1SDan Gohman #define DEBUG_TYPE "wasm-reg-numbering" 33cf4748f1SDan Gohman 34cf4748f1SDan Gohman namespace { 35cf4748f1SDan Gohman class WebAssemblyRegNumbering final : public MachineFunctionPass { 36117296c0SMehdi Amini StringRef getPassName() const override { 37cf4748f1SDan Gohman return "WebAssembly Register Numbering"; 38cf4748f1SDan Gohman } 39cf4748f1SDan Gohman 40cf4748f1SDan Gohman void getAnalysisUsage(AnalysisUsage &AU) const override { 41cf4748f1SDan Gohman AU.setPreservesCFG(); 42cf4748f1SDan Gohman MachineFunctionPass::getAnalysisUsage(AU); 43cf4748f1SDan Gohman } 44cf4748f1SDan Gohman 45cf4748f1SDan Gohman bool runOnMachineFunction(MachineFunction &MF) override; 46cf4748f1SDan Gohman 47cf4748f1SDan Gohman public: 48cf4748f1SDan Gohman static char ID; // Pass identification, replacement for typeid 49cf4748f1SDan Gohman WebAssemblyRegNumbering() : MachineFunctionPass(ID) {} 50cf4748f1SDan Gohman }; 51cf4748f1SDan Gohman } // end anonymous namespace 52cf4748f1SDan Gohman 53cf4748f1SDan Gohman char WebAssemblyRegNumbering::ID = 0; 54cf4748f1SDan Gohman FunctionPass *llvm::createWebAssemblyRegNumbering() { 55cf4748f1SDan Gohman return new WebAssemblyRegNumbering(); 56cf4748f1SDan Gohman } 57cf4748f1SDan Gohman 58cf4748f1SDan Gohman bool WebAssemblyRegNumbering::runOnMachineFunction(MachineFunction &MF) { 59cf4748f1SDan Gohman DEBUG(dbgs() << "********** Register Numbering **********\n" 60cf4748f1SDan Gohman "********** Function: " 61cf4748f1SDan Gohman << MF.getName() << '\n'); 62cf4748f1SDan Gohman 63cf4748f1SDan Gohman WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>(); 64cf4748f1SDan Gohman MachineRegisterInfo &MRI = MF.getRegInfo(); 65cf4748f1SDan Gohman 66cf4748f1SDan Gohman MFI.initWARegs(); 67cf4748f1SDan Gohman 68cf4748f1SDan Gohman // WebAssembly argument registers are in the same index space as local 69cf4748f1SDan Gohman // variables. Assign the numbers for them first. 704ba4816bSDan Gohman MachineBasicBlock &EntryMBB = MF.front(); 714ba4816bSDan Gohman for (MachineInstr &MI : EntryMBB) { 72*4fc4e42dSDan Gohman if (!WebAssembly::isArgument(MI)) 73*4fc4e42dSDan Gohman break; 74*4fc4e42dSDan Gohman 750cfb5f85SDan Gohman int64_t Imm = MI.getOperand(1).getImm(); 7665194682SDerek Schuff DEBUG(dbgs() << "Arg VReg " << MI.getOperand(0).getReg() << " -> WAReg " 770cfb5f85SDan Gohman << Imm << "\n"); 780cfb5f85SDan Gohman MFI.setWAReg(MI.getOperand(0).getReg(), Imm); 79cf4748f1SDan Gohman } 80cf4748f1SDan Gohman 81cf4748f1SDan Gohman // Then assign regular WebAssembly registers for all remaining used 8208d58bcfSDan Gohman // virtual registers. TODO: Consider sorting the registers by frequency of 8308d58bcfSDan Gohman // use, to maximize usage of small immediate fields. 84cf4748f1SDan Gohman unsigned NumVRegs = MF.getRegInfo().getNumVirtRegs(); 854ba4816bSDan Gohman unsigned NumStackRegs = 0; 8665194682SDerek Schuff // Start the numbering for locals after the arg regs 8765194682SDerek Schuff unsigned CurReg = MFI.getParams().size(); 88cf4748f1SDan Gohman for (unsigned VRegIdx = 0; VRegIdx < NumVRegs; ++VRegIdx) { 89cf4748f1SDan Gohman unsigned VReg = TargetRegisterInfo::index2VirtReg(VRegIdx); 90899cb5abSDan Gohman // Skip unused registers. 91899cb5abSDan Gohman if (MRI.use_empty(VReg)) 92899cb5abSDan Gohman continue; 934ba4816bSDan Gohman // Handle stackified registers. 944ba4816bSDan Gohman if (MFI.isVRegStackified(VReg)) { 9565194682SDerek Schuff DEBUG(dbgs() << "VReg " << VReg << " -> WAReg " 9665194682SDerek Schuff << (INT32_MIN | NumStackRegs) << "\n"); 974ba4816bSDan Gohman MFI.setWAReg(VReg, INT32_MIN | NumStackRegs++); 984ba4816bSDan Gohman continue; 994ba4816bSDan Gohman } 10065194682SDerek Schuff if (MFI.getWAReg(VReg) == WebAssemblyFunctionInfo::UnusedReg) { 10165194682SDerek Schuff DEBUG(dbgs() << "VReg " << VReg << " -> WAReg " << CurReg << "\n"); 10265194682SDerek Schuff MFI.setWAReg(VReg, CurReg++); 10365194682SDerek Schuff } 104cf4748f1SDan Gohman } 105cf4748f1SDan Gohman 106cf4748f1SDan Gohman return true; 107cf4748f1SDan Gohman } 108