1 //===-- WebAssemblyReplacePhysRegs.cpp - Replace phys regs with virt regs -===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file implements a pass that replaces physical registers with 11 /// virtual registers. 12 /// 13 /// LLVM expects certain physical registers, such as a stack pointer. However, 14 /// WebAssembly doesn't actually have such physical registers. This pass is run 15 /// once LLVM no longer needs these registers, and replaces them with virtual 16 /// registers, so they can participate in register stackifying and coloring in 17 /// the normal way. 18 /// 19 //===----------------------------------------------------------------------===// 20 21 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 22 #include "WebAssembly.h" 23 #include "WebAssemblyMachineFunctionInfo.h" 24 #include "WebAssemblySubtarget.h" 25 #include "llvm/CodeGen/MachineFunctionPass.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-replace-phys-regs" 33 34 namespace { 35 class WebAssemblyReplacePhysRegs final : public MachineFunctionPass { 36 public: 37 static char ID; // Pass identification, replacement for typeid 38 WebAssemblyReplacePhysRegs() : MachineFunctionPass(ID) {} 39 40 private: 41 StringRef getPassName() const override { 42 return "WebAssembly Replace Physical Registers"; 43 } 44 45 void getAnalysisUsage(AnalysisUsage &AU) const override { 46 AU.setPreservesCFG(); 47 MachineFunctionPass::getAnalysisUsage(AU); 48 } 49 50 bool runOnMachineFunction(MachineFunction &MF) override; 51 }; 52 } // end anonymous namespace 53 54 char WebAssemblyReplacePhysRegs::ID = 0; 55 INITIALIZE_PASS(WebAssemblyReplacePhysRegs, DEBUG_TYPE, 56 "Replace physical registers with virtual registers", false, 57 false) 58 59 FunctionPass *llvm::createWebAssemblyReplacePhysRegs() { 60 return new WebAssemblyReplacePhysRegs(); 61 } 62 63 bool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) { 64 LLVM_DEBUG({ 65 dbgs() << "********** Replace Physical Registers **********\n" 66 << "********** Function: " << MF.getName() << '\n'; 67 }); 68 69 MachineRegisterInfo &MRI = MF.getRegInfo(); 70 auto &TRI = *MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo(); 71 bool Changed = false; 72 73 assert(!mustPreserveAnalysisID(LiveIntervalsID) && 74 "LiveIntervals shouldn't be active yet!"); 75 // We don't preserve SSA or liveness. 76 MRI.leaveSSA(); 77 MRI.invalidateLiveness(); 78 79 for (unsigned PReg = WebAssembly::NoRegister + 1; 80 PReg < WebAssembly::NUM_TARGET_REGS; ++PReg) { 81 // Skip fake registers that are never used explicitly. 82 if (PReg == WebAssembly::VALUE_STACK || PReg == WebAssembly::ARGUMENTS) 83 continue; 84 85 // Replace explicit uses of the physical register with a virtual register. 86 const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PReg); 87 unsigned VReg = WebAssembly::NoRegister; 88 for (auto I = MRI.reg_begin(PReg), E = MRI.reg_end(); I != E;) { 89 MachineOperand &MO = *I++; 90 if (!MO.isImplicit()) { 91 if (VReg == WebAssembly::NoRegister) { 92 VReg = MRI.createVirtualRegister(RC); 93 if (PReg == TRI.getFrameRegister(MF)) { 94 auto FI = MF.getInfo<WebAssemblyFunctionInfo>(); 95 assert(!FI->isFrameBaseVirtual()); 96 FI->setFrameBaseVreg(VReg); 97 LLVM_DEBUG({ 98 dbgs() << "replacing preg " << PReg << " with " << VReg << " (" 99 << Register::virtReg2Index(VReg) << ")\n"; 100 }); 101 } 102 } 103 MO.setReg(VReg); 104 if (MO.getParent()->isDebugValue()) 105 MO.setIsDebug(); 106 Changed = true; 107 } 108 } 109 } 110 111 return Changed; 112 } 113