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