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 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::VALUE_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 (MachineOperand &MO : 86 llvm::make_early_inc_range(MRI.reg_operands(PReg))) { 87 if (!MO.isImplicit()) { 88 if (VReg == WebAssembly::NoRegister) { 89 VReg = MRI.createVirtualRegister(RC); 90 if (PReg == TRI.getFrameRegister(MF)) { 91 auto FI = MF.getInfo<WebAssemblyFunctionInfo>(); 92 assert(!FI->isFrameBaseVirtual()); 93 FI->setFrameBaseVreg(VReg); 94 LLVM_DEBUG({ 95 dbgs() << "replacing preg " << PReg << " with " << VReg << " (" 96 << Register::virtReg2Index(VReg) << ")\n"; 97 }); 98 } 99 } 100 MO.setReg(VReg); 101 Changed = true; 102 } 103 } 104 } 105 106 return Changed; 107 } 108