xref: /aosp_15_r20/external/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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 Worker FunctionPass *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 Worker bool 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