108 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file implements a pass that replaces physical registers with11/// 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 run15/// once LLVM no longer needs these registers, and replaces them with virtual16/// registers, so they can participate in register stackifying and coloring in17/// 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 typeid38 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 namespace53 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 auto &TRI = *MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo();71 bool Changed = false;72 73 assert(!mustPreserveAnalysisID(LiveIntervalsID) &&74 "LiveIntervals shouldn't be active yet!");75 76 for (unsigned PReg = WebAssembly::NoRegister + 1;77 PReg < WebAssembly::NUM_TARGET_REGS; ++PReg) {78 // Skip fake registers that are never used explicitly.79 if (PReg == WebAssembly::VALUE_STACK || PReg == WebAssembly::ARGUMENTS)80 continue;81 82 // Replace explicit uses of the physical register with a virtual register.83 const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PReg);84 unsigned VReg = WebAssembly::NoRegister;85 for (MachineOperand &MO :86 llvm::make_early_inc_range(MRI.reg_operands(PReg))) {87 if (!MO.isImplicit()) {88 if (VReg == WebAssembly::NoRegister) {89 VReg = MRI.createVirtualRegister(RC);90 if (PReg == TRI.getFrameRegister(MF)) {91 auto FI = MF.getInfo<WebAssemblyFunctionInfo>();92 assert(!FI->isFrameBaseVirtual());93 FI->setFrameBaseVreg(VReg);94 LLVM_DEBUG({95 dbgs() << "replacing preg " << PReg << " with " << VReg << " ("96 << Register(VReg).virtRegIndex() << ")\n";97 });98 }99 }100 MO.setReg(VReg);101 Changed = true;102 }103 }104 }105 106 return Changed;107}108