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