brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · cb152f5 Raw
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