10cfb5f85SDan Gohman //===-- WebAssemblyReplacePhysRegs.cpp - Replace phys regs with virt regs -===//
20cfb5f85SDan Gohman //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60cfb5f85SDan Gohman //
70cfb5f85SDan Gohman //===----------------------------------------------------------------------===//
80cfb5f85SDan Gohman ///
90cfb5f85SDan Gohman /// \file
105f8f34e4SAdrian Prantl /// This file implements a pass that replaces physical registers with
110cfb5f85SDan Gohman /// virtual registers.
120cfb5f85SDan Gohman ///
130cfb5f85SDan Gohman /// LLVM expects certain physical registers, such as a stack pointer. However,
140cfb5f85SDan Gohman /// WebAssembly doesn't actually have such physical registers. This pass is run
150cfb5f85SDan Gohman /// once LLVM no longer needs these registers, and replaces them with virtual
160cfb5f85SDan Gohman /// registers, so they can participate in register stackifying and coloring in
170cfb5f85SDan Gohman /// the normal way.
180cfb5f85SDan Gohman ///
190cfb5f85SDan Gohman //===----------------------------------------------------------------------===//
200cfb5f85SDan Gohman 
210cfb5f85SDan Gohman #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
226bda14b3SChandler Carruth #include "WebAssembly.h"
230cfb5f85SDan Gohman #include "WebAssemblyMachineFunctionInfo.h"
240cfb5f85SDan Gohman #include "WebAssemblySubtarget.h"
250cfb5f85SDan Gohman #include "llvm/CodeGen/MachineFunctionPass.h"
260cfb5f85SDan Gohman #include "llvm/CodeGen/MachineRegisterInfo.h"
270cfb5f85SDan Gohman #include "llvm/CodeGen/Passes.h"
280cfb5f85SDan Gohman #include "llvm/Support/Debug.h"
290cfb5f85SDan Gohman #include "llvm/Support/raw_ostream.h"
300cfb5f85SDan Gohman using namespace llvm;
310cfb5f85SDan Gohman 
320cfb5f85SDan Gohman #define DEBUG_TYPE "wasm-replace-phys-regs"
330cfb5f85SDan Gohman 
340cfb5f85SDan Gohman namespace {
350cfb5f85SDan Gohman class WebAssemblyReplacePhysRegs final : public MachineFunctionPass {
360cfb5f85SDan Gohman public:
370cfb5f85SDan Gohman   static char ID; // Pass identification, replacement for typeid
WebAssemblyReplacePhysRegs()380cfb5f85SDan Gohman   WebAssemblyReplacePhysRegs() : MachineFunctionPass(ID) {}
390cfb5f85SDan Gohman 
400cfb5f85SDan Gohman private:
getPassName() const41117296c0SMehdi Amini   StringRef getPassName() const override {
420cfb5f85SDan Gohman     return "WebAssembly Replace Physical Registers";
430cfb5f85SDan Gohman   }
440cfb5f85SDan Gohman 
getAnalysisUsage(AnalysisUsage & AU) const450cfb5f85SDan Gohman   void getAnalysisUsage(AnalysisUsage &AU) const override {
460cfb5f85SDan Gohman     AU.setPreservesCFG();
470cfb5f85SDan Gohman     MachineFunctionPass::getAnalysisUsage(AU);
480cfb5f85SDan Gohman   }
490cfb5f85SDan Gohman 
500cfb5f85SDan Gohman   bool runOnMachineFunction(MachineFunction &MF) override;
510cfb5f85SDan Gohman };
520cfb5f85SDan Gohman } // end anonymous namespace
530cfb5f85SDan Gohman 
540cfb5f85SDan Gohman char WebAssemblyReplacePhysRegs::ID = 0;
5540926451SJacob Gravelle INITIALIZE_PASS(WebAssemblyReplacePhysRegs, DEBUG_TYPE,
56f208f631SHeejin Ahn                 "Replace physical registers with virtual registers", false,
57f208f631SHeejin Ahn                 false)
5840926451SJacob Gravelle 
createWebAssemblyReplacePhysRegs()590cfb5f85SDan Gohman FunctionPass *llvm::createWebAssemblyReplacePhysRegs() {
600cfb5f85SDan Gohman   return new WebAssemblyReplacePhysRegs();
610cfb5f85SDan Gohman }
620cfb5f85SDan Gohman 
runOnMachineFunction(MachineFunction & MF)630cfb5f85SDan Gohman bool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) {
64d34e60caSNicola Zaghen   LLVM_DEBUG({
650cfb5f85SDan Gohman     dbgs() << "********** Replace Physical Registers **********\n"
660cfb5f85SDan Gohman            << "********** Function: " << MF.getName() << '\n';
670cfb5f85SDan Gohman   });
680cfb5f85SDan Gohman 
690cfb5f85SDan Gohman   MachineRegisterInfo &MRI = MF.getRegInfo();
70ff171acfSDerek Schuff   auto &TRI = *MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo();
710cfb5f85SDan Gohman   bool Changed = false;
720cfb5f85SDan Gohman 
730cfb5f85SDan Gohman   assert(!mustPreserveAnalysisID(LiveIntervalsID) &&
740cfb5f85SDan Gohman          "LiveIntervals shouldn't be active yet!");
750cfb5f85SDan Gohman 
760cfb5f85SDan Gohman   for (unsigned PReg = WebAssembly::NoRegister + 1;
770cfb5f85SDan Gohman        PReg < WebAssembly::NUM_TARGET_REGS; ++PReg) {
780cfb5f85SDan Gohman     // Skip fake registers that are never used explicitly.
79e040533eSDan Gohman     if (PReg == WebAssembly::VALUE_STACK || PReg == WebAssembly::ARGUMENTS)
800cfb5f85SDan Gohman       continue;
810cfb5f85SDan Gohman 
820cfb5f85SDan Gohman     // Replace explicit uses of the physical register with a virtual register.
830cfb5f85SDan Gohman     const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PReg);
840cfb5f85SDan Gohman     unsigned VReg = WebAssembly::NoRegister;
85*85b4b21cSKazu Hirata     for (MachineOperand &MO :
86*85b4b21cSKazu Hirata          llvm::make_early_inc_range(MRI.reg_operands(PReg))) {
870cfb5f85SDan Gohman       if (!MO.isImplicit()) {
88ff171acfSDerek Schuff         if (VReg == WebAssembly::NoRegister) {
890cfb5f85SDan Gohman           VReg = MRI.createVirtualRegister(RC);
90ff171acfSDerek Schuff           if (PReg == TRI.getFrameRegister(MF)) {
91ff171acfSDerek Schuff             auto FI = MF.getInfo<WebAssemblyFunctionInfo>();
92ff171acfSDerek Schuff             assert(!FI->isFrameBaseVirtual());
93ff171acfSDerek Schuff             FI->setFrameBaseVreg(VReg);
94ff171acfSDerek Schuff             LLVM_DEBUG({
95ff171acfSDerek Schuff               dbgs() << "replacing preg " << PReg << " with " << VReg << " ("
96ff171acfSDerek Schuff                      << Register::virtReg2Index(VReg) << ")\n";
97ff171acfSDerek Schuff             });
98ff171acfSDerek Schuff           }
99ff171acfSDerek Schuff         }
1000cfb5f85SDan Gohman         MO.setReg(VReg);
1010cfb5f85SDan Gohman         Changed = true;
1020cfb5f85SDan Gohman       }
1030cfb5f85SDan Gohman     }
1040cfb5f85SDan Gohman   }
1050cfb5f85SDan Gohman 
1060cfb5f85SDan Gohman   return Changed;
1070cfb5f85SDan Gohman }
108