1303231Sdim//===-- WebAssemblyReplacePhysRegs.cpp - Replace phys regs with virt regs -===// 2303231Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6303231Sdim// 7303231Sdim//===----------------------------------------------------------------------===// 8303231Sdim/// 9303231Sdim/// \file 10341825Sdim/// This file implements a pass that replaces physical registers with 11303231Sdim/// virtual registers. 12303231Sdim/// 13303231Sdim/// LLVM expects certain physical registers, such as a stack pointer. However, 14303231Sdim/// WebAssembly doesn't actually have such physical registers. This pass is run 15303231Sdim/// once LLVM no longer needs these registers, and replaces them with virtual 16303231Sdim/// registers, so they can participate in register stackifying and coloring in 17303231Sdim/// the normal way. 18303231Sdim/// 19303231Sdim//===----------------------------------------------------------------------===// 20303231Sdim 21321369Sdim#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 22303231Sdim#include "WebAssembly.h" 23303231Sdim#include "WebAssemblyMachineFunctionInfo.h" 24303231Sdim#include "WebAssemblySubtarget.h" 25303231Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 26303231Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 27303231Sdim#include "llvm/CodeGen/Passes.h" 28303231Sdim#include "llvm/Support/Debug.h" 29303231Sdim#include "llvm/Support/raw_ostream.h" 30303231Sdimusing namespace llvm; 31303231Sdim 32303231Sdim#define DEBUG_TYPE "wasm-replace-phys-regs" 33303231Sdim 34303231Sdimnamespace { 35303231Sdimclass WebAssemblyReplacePhysRegs final : public MachineFunctionPass { 36303231Sdimpublic: 37303231Sdim static char ID; // Pass identification, replacement for typeid 38303231Sdim WebAssemblyReplacePhysRegs() : MachineFunctionPass(ID) {} 39303231Sdim 40303231Sdimprivate: 41314564Sdim StringRef getPassName() const override { 42303231Sdim return "WebAssembly Replace Physical Registers"; 43303231Sdim } 44303231Sdim 45303231Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 46303231Sdim AU.setPreservesCFG(); 47303231Sdim MachineFunctionPass::getAnalysisUsage(AU); 48303231Sdim } 49303231Sdim 50303231Sdim bool runOnMachineFunction(MachineFunction &MF) override; 51303231Sdim}; 52303231Sdim} // end anonymous namespace 53303231Sdim 54303231Sdimchar WebAssemblyReplacePhysRegs::ID = 0; 55341825SdimINITIALIZE_PASS(WebAssemblyReplacePhysRegs, DEBUG_TYPE, 56344779Sdim "Replace physical registers with virtual registers", false, 57344779Sdim false) 58341825Sdim 59303231SdimFunctionPass *llvm::createWebAssemblyReplacePhysRegs() { 60303231Sdim return new WebAssemblyReplacePhysRegs(); 61303231Sdim} 62303231Sdim 63303231Sdimbool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) { 64341825Sdim LLVM_DEBUG({ 65303231Sdim dbgs() << "********** Replace Physical Registers **********\n" 66303231Sdim << "********** Function: " << MF.getName() << '\n'; 67303231Sdim }); 68303231Sdim 69303231Sdim MachineRegisterInfo &MRI = MF.getRegInfo(); 70303231Sdim const auto &TRI = *MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo(); 71303231Sdim bool Changed = false; 72303231Sdim 73303231Sdim assert(!mustPreserveAnalysisID(LiveIntervalsID) && 74303231Sdim "LiveIntervals shouldn't be active yet!"); 75303231Sdim // We don't preserve SSA or liveness. 76303231Sdim MRI.leaveSSA(); 77303231Sdim MRI.invalidateLiveness(); 78303231Sdim 79303231Sdim for (unsigned PReg = WebAssembly::NoRegister + 1; 80303231Sdim PReg < WebAssembly::NUM_TARGET_REGS; ++PReg) { 81303231Sdim // Skip fake registers that are never used explicitly. 82314564Sdim if (PReg == WebAssembly::VALUE_STACK || PReg == WebAssembly::ARGUMENTS) 83303231Sdim continue; 84303231Sdim 85303231Sdim // Replace explicit uses of the physical register with a virtual register. 86303231Sdim const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PReg); 87303231Sdim unsigned VReg = WebAssembly::NoRegister; 88344779Sdim for (auto I = MRI.reg_begin(PReg), E = MRI.reg_end(); I != E;) { 89303231Sdim MachineOperand &MO = *I++; 90303231Sdim if (!MO.isImplicit()) { 91303231Sdim if (VReg == WebAssembly::NoRegister) 92303231Sdim VReg = MRI.createVirtualRegister(RC); 93303231Sdim MO.setReg(VReg); 94314564Sdim if (MO.getParent()->isDebugValue()) 95314564Sdim MO.setIsDebug(); 96303231Sdim Changed = true; 97303231Sdim } 98303231Sdim } 99303231Sdim } 100303231Sdim 101303231Sdim return Changed; 102303231Sdim} 103