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 const 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 MO.setReg(VReg); 94 if (MO.getParent()->isDebugValue()) 95 MO.setIsDebug(); 96 Changed = true; 97 } 98 } 99 } 100 101 return Changed; 102} 103