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" 30using namespace llvm; 31 32#define DEBUG_TYPE "wasm-replace-phys-regs" 33 34namespace { 35class WebAssemblyReplacePhysRegs final : public MachineFunctionPass { 36public: 37 static char ID; // Pass identification, replacement for typeid 38 WebAssemblyReplacePhysRegs() : MachineFunctionPass(ID) {} 39 40private: 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 54char WebAssemblyReplacePhysRegs::ID = 0; 55INITIALIZE_PASS(WebAssemblyReplacePhysRegs, DEBUG_TYPE, 56 "Replace physical registers with virtual registers", false, 57 false) 58 59FunctionPass *llvm::createWebAssemblyReplacePhysRegs() { 60 return new WebAssemblyReplacePhysRegs(); 61} 62 63bool 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