WebAssemblyReplacePhysRegs.cpp revision 344779
1//===-- WebAssemblyReplacePhysRegs.cpp - Replace phys regs with virt regs -===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9/// 10/// \file 11/// This file implements a pass that replaces physical registers with 12/// virtual registers. 13/// 14/// LLVM expects certain physical registers, such as a stack pointer. However, 15/// WebAssembly doesn't actually have such physical registers. This pass is run 16/// once LLVM no longer needs these registers, and replaces them with virtual 17/// registers, so they can participate in register stackifying and coloring in 18/// the normal way. 19/// 20//===----------------------------------------------------------------------===// 21 22#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 23#include "WebAssembly.h" 24#include "WebAssemblyMachineFunctionInfo.h" 25#include "WebAssemblySubtarget.h" 26#include "llvm/CodeGen/MachineFunctionPass.h" 27#include "llvm/CodeGen/MachineRegisterInfo.h" 28#include "llvm/CodeGen/Passes.h" 29#include "llvm/Support/Debug.h" 30#include "llvm/Support/raw_ostream.h" 31using namespace llvm; 32 33#define DEBUG_TYPE "wasm-replace-phys-regs" 34 35namespace { 36class WebAssemblyReplacePhysRegs final : public MachineFunctionPass { 37public: 38 static char ID; // Pass identification, replacement for typeid 39 WebAssemblyReplacePhysRegs() : MachineFunctionPass(ID) {} 40 41private: 42 StringRef getPassName() const override { 43 return "WebAssembly Replace Physical Registers"; 44 } 45 46 void getAnalysisUsage(AnalysisUsage &AU) const override { 47 AU.setPreservesCFG(); 48 MachineFunctionPass::getAnalysisUsage(AU); 49 } 50 51 bool runOnMachineFunction(MachineFunction &MF) override; 52}; 53} // end anonymous namespace 54 55char WebAssemblyReplacePhysRegs::ID = 0; 56INITIALIZE_PASS(WebAssemblyReplacePhysRegs, DEBUG_TYPE, 57 "Replace physical registers with virtual registers", false, 58 false) 59 60FunctionPass *llvm::createWebAssemblyReplacePhysRegs() { 61 return new WebAssemblyReplacePhysRegs(); 62} 63 64bool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) { 65 LLVM_DEBUG({ 66 dbgs() << "********** Replace Physical Registers **********\n" 67 << "********** Function: " << MF.getName() << '\n'; 68 }); 69 70 MachineRegisterInfo &MRI = MF.getRegInfo(); 71 const auto &TRI = *MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo(); 72 bool Changed = false; 73 74 assert(!mustPreserveAnalysisID(LiveIntervalsID) && 75 "LiveIntervals shouldn't be active yet!"); 76 // We don't preserve SSA or liveness. 77 MRI.leaveSSA(); 78 MRI.invalidateLiveness(); 79 80 for (unsigned PReg = WebAssembly::NoRegister + 1; 81 PReg < WebAssembly::NUM_TARGET_REGS; ++PReg) { 82 // Skip fake registers that are never used explicitly. 83 if (PReg == WebAssembly::VALUE_STACK || PReg == WebAssembly::ARGUMENTS) 84 continue; 85 86 // Replace explicit uses of the physical register with a virtual register. 87 const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PReg); 88 unsigned VReg = WebAssembly::NoRegister; 89 for (auto I = MRI.reg_begin(PReg), E = MRI.reg_end(); I != E;) { 90 MachineOperand &MO = *I++; 91 if (!MO.isImplicit()) { 92 if (VReg == WebAssembly::NoRegister) 93 VReg = MRI.createVirtualRegister(RC); 94 MO.setReg(VReg); 95 if (MO.getParent()->isDebugValue()) 96 MO.setIsDebug(); 97 Changed = true; 98 } 99 } 100 } 101 102 return Changed; 103} 104