1 //===-- WebAssemblyReplacePhysRegs.cpp - Replace phys regs with virt regs -===// 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 /// \brief This file implements a pass that replaces physical registers with 12 /// virtual registers. 13 /// 14 /// LLVM expects certain physical registers, such as a stack pointer. However, 15 /// WebAssembly doesn't actually have such physical registers. This pass is run 16 /// once LLVM no longer needs these registers, and replaces them with virtual 17 /// registers, so they can participate in register stackifying and coloring in 18 /// the normal way. 19 /// 20 //===----------------------------------------------------------------------===// 21 22 #include "WebAssembly.h" 23 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 24 #include "WebAssemblyMachineFunctionInfo.h" 25 #include "WebAssemblySubtarget.h" 26 #include "llvm/CodeGen/MachineFunctionPass.h" 27 #include "llvm/CodeGen/MachineRegisterInfo.h" 28 #include "llvm/CodeGen/Passes.h" 29 #include "llvm/Support/Debug.h" 30 #include "llvm/Support/raw_ostream.h" 31 using namespace llvm; 32 33 #define DEBUG_TYPE "wasm-replace-phys-regs" 34 35 namespace { 36 class WebAssemblyReplacePhysRegs final : public MachineFunctionPass { 37 public: 38 static char ID; // Pass identification, replacement for typeid WebAssemblyReplacePhysRegs()39 WebAssemblyReplacePhysRegs() : MachineFunctionPass(ID) {} 40 41 private: getPassName() const42 const char *getPassName() const override { 43 return "WebAssembly Replace Physical Registers"; 44 } 45 getAnalysisUsage(AnalysisUsage & AU) const46 void getAnalysisUsage(AnalysisUsage &AU) const override { 47 AU.setPreservesCFG(); 48 MachineFunctionPass::getAnalysisUsage(AU); 49 } 50 51 bool runOnMachineFunction(MachineFunction &MF) override; 52 }; 53 } // end anonymous namespace 54 55 char WebAssemblyReplacePhysRegs::ID = 0; createWebAssemblyReplacePhysRegs()56FunctionPass *llvm::createWebAssemblyReplacePhysRegs() { 57 return new WebAssemblyReplacePhysRegs(); 58 } 59 runOnMachineFunction(MachineFunction & MF)60bool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) { 61 DEBUG({ 62 dbgs() << "********** Replace Physical Registers **********\n" 63 << "********** Function: " << MF.getName() << '\n'; 64 }); 65 66 MachineRegisterInfo &MRI = MF.getRegInfo(); 67 const auto &TRI = *MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo(); 68 bool Changed = false; 69 70 assert(!mustPreserveAnalysisID(LiveIntervalsID) && 71 "LiveIntervals shouldn't be active yet!"); 72 // We don't preserve SSA or liveness. 73 MRI.leaveSSA(); 74 MRI.invalidateLiveness(); 75 76 for (unsigned PReg = WebAssembly::NoRegister + 1; 77 PReg < WebAssembly::NUM_TARGET_REGS; ++PReg) { 78 // Skip fake registers that are never used explicitly. 79 if (PReg == WebAssembly::EXPR_STACK || PReg == WebAssembly::ARGUMENTS) 80 continue; 81 82 // Replace explicit uses of the physical register with a virtual register. 83 const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PReg); 84 unsigned VReg = WebAssembly::NoRegister; 85 for (auto I = MRI.reg_begin(PReg), E = MRI.reg_end(); I != E; ) { 86 MachineOperand &MO = *I++; 87 if (!MO.isImplicit()) { 88 if (VReg == WebAssembly::NoRegister) 89 VReg = MRI.createVirtualRegister(RC); 90 MO.setReg(VReg); 91 Changed = true; 92 } 93 } 94 } 95 96 return Changed; 97 } 98