xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUReserveWWMRegs.cpp (revision 9c77fb6aaa366cbabc80ee1b834bcfe4df135491)
1 //===-- AMDGPUReserveWWMRegs.cpp - Add WWM Regs to reserved regs list -----===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// This pass should be invoked at the end of wwm-regalloc pipeline.
11 /// It identifies the WWM regs allocated during this pipeline and add
12 /// them to the list of reserved registers so that they won't be available for
13 /// per-thread VGPR allocation in the subsequent regalloc pipeline.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #include "AMDGPUReserveWWMRegs.h"
18 #include "AMDGPU.h"
19 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
20 #include "SIMachineFunctionInfo.h"
21 #include "llvm/CodeGen/MachineFunctionPass.h"
22 #include "llvm/CodeGen/VirtRegMap.h"
23 
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "amdgpu-reserve-wwm-regs"
27 
28 namespace {
29 
30 class AMDGPUReserveWWMRegsLegacy : public MachineFunctionPass {
31 public:
32   static char ID;
33 
34   AMDGPUReserveWWMRegsLegacy() : MachineFunctionPass(ID) {}
35 
36   bool runOnMachineFunction(MachineFunction &MF) override;
37 
38   StringRef getPassName() const override {
39     return "AMDGPU Reserve WWM Registers";
40   }
41 
42   void getAnalysisUsage(AnalysisUsage &AU) const override {
43     AU.setPreservesAll();
44     MachineFunctionPass::getAnalysisUsage(AU);
45   }
46 };
47 
48 class AMDGPUReserveWWMRegs {
49 public:
50   bool run(MachineFunction &MF);
51 };
52 
53 } // End anonymous namespace.
54 
55 INITIALIZE_PASS(AMDGPUReserveWWMRegsLegacy, DEBUG_TYPE,
56                 "AMDGPU Reserve WWM Registers", false, false)
57 
58 char AMDGPUReserveWWMRegsLegacy::ID = 0;
59 
60 char &llvm::AMDGPUReserveWWMRegsLegacyID = AMDGPUReserveWWMRegsLegacy::ID;
61 
62 bool AMDGPUReserveWWMRegsLegacy::runOnMachineFunction(MachineFunction &MF) {
63   return AMDGPUReserveWWMRegs().run(MF);
64 }
65 
66 PreservedAnalyses
67 AMDGPUReserveWWMRegsPass::run(MachineFunction &MF,
68                               MachineFunctionAnalysisManager &) {
69   AMDGPUReserveWWMRegs().run(MF);
70   // TODO: This should abandon RegisterClassInfo once it is turned into an
71   // analysis.
72   return PreservedAnalyses::all();
73 }
74 
75 bool AMDGPUReserveWWMRegs::run(MachineFunction &MF) {
76   SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
77 
78   bool Changed = false;
79   for (MachineBasicBlock &MBB : MF) {
80     for (MachineInstr &MI : MBB) {
81       unsigned Opc = MI.getOpcode();
82       if (Opc != AMDGPU::SI_SPILL_S32_TO_VGPR &&
83           Opc != AMDGPU::SI_RESTORE_S32_FROM_VGPR)
84         continue;
85 
86       Register Reg = Opc == AMDGPU::SI_SPILL_S32_TO_VGPR
87                          ? MI.getOperand(0).getReg()
88                          : MI.getOperand(1).getReg();
89 
90       assert(Reg.isPhysical() &&
91              "All WWM registers should have been allocated by now.");
92 
93       MFI->reserveWWMRegister(Reg);
94       Changed |= true;
95     }
96   }
97 
98   // The renamable flag can't be set for reserved registers. Reset the flag for
99   // MOs involving wwm-regs as they will be reserved during vgpr-regalloc
100   // pipeline.
101   const MachineRegisterInfo &MRI = MF.getRegInfo();
102   for (Register Reg : MFI->getWWMReservedRegs()) {
103     for (MachineOperand &MO : MRI.reg_operands(Reg))
104       MO.setIsRenamable(false);
105   }
106 
107   // Now clear the NonWWMRegMask earlier set during wwm-regalloc.
108   MFI->clearNonWWMRegAllocMask();
109 
110   return Changed;
111 }
112