WebAssemblyReplacePhysRegs.cpp revision 321369
1303231Sdim//===-- WebAssemblyReplacePhysRegs.cpp - Replace phys regs with virt regs -===// 2303231Sdim// 3303231Sdim// The LLVM Compiler Infrastructure 4303231Sdim// 5303231Sdim// This file is distributed under the University of Illinois Open Source 6303231Sdim// License. See LICENSE.TXT for details. 7303231Sdim// 8303231Sdim//===----------------------------------------------------------------------===// 9303231Sdim/// 10303231Sdim/// \file 11303231Sdim/// \brief This file implements a pass that replaces physical registers with 12303231Sdim/// virtual registers. 13303231Sdim/// 14303231Sdim/// LLVM expects certain physical registers, such as a stack pointer. However, 15303231Sdim/// WebAssembly doesn't actually have such physical registers. This pass is run 16303231Sdim/// once LLVM no longer needs these registers, and replaces them with virtual 17303231Sdim/// registers, so they can participate in register stackifying and coloring in 18303231Sdim/// the normal way. 19303231Sdim/// 20303231Sdim//===----------------------------------------------------------------------===// 21303231Sdim 22321369Sdim#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 23303231Sdim#include "WebAssembly.h" 24303231Sdim#include "WebAssemblyMachineFunctionInfo.h" 25303231Sdim#include "WebAssemblySubtarget.h" 26303231Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 27303231Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 28303231Sdim#include "llvm/CodeGen/Passes.h" 29303231Sdim#include "llvm/Support/Debug.h" 30303231Sdim#include "llvm/Support/raw_ostream.h" 31303231Sdimusing namespace llvm; 32303231Sdim 33303231Sdim#define DEBUG_TYPE "wasm-replace-phys-regs" 34303231Sdim 35303231Sdimnamespace { 36303231Sdimclass WebAssemblyReplacePhysRegs final : public MachineFunctionPass { 37303231Sdimpublic: 38303231Sdim static char ID; // Pass identification, replacement for typeid 39303231Sdim WebAssemblyReplacePhysRegs() : MachineFunctionPass(ID) {} 40303231Sdim 41303231Sdimprivate: 42314564Sdim StringRef getPassName() const override { 43303231Sdim return "WebAssembly Replace Physical Registers"; 44303231Sdim } 45303231Sdim 46303231Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 47303231Sdim AU.setPreservesCFG(); 48303231Sdim MachineFunctionPass::getAnalysisUsage(AU); 49303231Sdim } 50303231Sdim 51303231Sdim bool runOnMachineFunction(MachineFunction &MF) override; 52303231Sdim}; 53303231Sdim} // end anonymous namespace 54303231Sdim 55303231Sdimchar WebAssemblyReplacePhysRegs::ID = 0; 56303231SdimFunctionPass *llvm::createWebAssemblyReplacePhysRegs() { 57303231Sdim return new WebAssemblyReplacePhysRegs(); 58303231Sdim} 59303231Sdim 60303231Sdimbool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) { 61303231Sdim DEBUG({ 62303231Sdim dbgs() << "********** Replace Physical Registers **********\n" 63303231Sdim << "********** Function: " << MF.getName() << '\n'; 64303231Sdim }); 65303231Sdim 66303231Sdim MachineRegisterInfo &MRI = MF.getRegInfo(); 67303231Sdim const auto &TRI = *MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo(); 68303231Sdim bool Changed = false; 69303231Sdim 70303231Sdim assert(!mustPreserveAnalysisID(LiveIntervalsID) && 71303231Sdim "LiveIntervals shouldn't be active yet!"); 72303231Sdim // We don't preserve SSA or liveness. 73303231Sdim MRI.leaveSSA(); 74303231Sdim MRI.invalidateLiveness(); 75303231Sdim 76303231Sdim for (unsigned PReg = WebAssembly::NoRegister + 1; 77303231Sdim PReg < WebAssembly::NUM_TARGET_REGS; ++PReg) { 78303231Sdim // Skip fake registers that are never used explicitly. 79314564Sdim if (PReg == WebAssembly::VALUE_STACK || PReg == WebAssembly::ARGUMENTS) 80303231Sdim continue; 81303231Sdim 82303231Sdim // Replace explicit uses of the physical register with a virtual register. 83303231Sdim const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PReg); 84303231Sdim unsigned VReg = WebAssembly::NoRegister; 85303231Sdim for (auto I = MRI.reg_begin(PReg), E = MRI.reg_end(); I != E; ) { 86303231Sdim MachineOperand &MO = *I++; 87303231Sdim if (!MO.isImplicit()) { 88303231Sdim if (VReg == WebAssembly::NoRegister) 89303231Sdim VReg = MRI.createVirtualRegister(RC); 90303231Sdim MO.setReg(VReg); 91314564Sdim if (MO.getParent()->isDebugValue()) 92314564Sdim MO.setIsDebug(); 93303231Sdim Changed = true; 94303231Sdim } 95303231Sdim } 96303231Sdim } 97303231Sdim 98303231Sdim return Changed; 99303231Sdim} 100