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
24using namespace llvm;
25
26#define DEBUG_TYPE "amdgpu-reserve-wwm-regs"
27
28namespace {
29
30class AMDGPUReserveWWMRegsLegacy : public MachineFunctionPass {
31public:
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
48class AMDGPUReserveWWMRegs {
49public:
50 bool run(MachineFunction &MF);
51};
52
53} // End anonymous namespace.
54
55INITIALIZE_PASS(AMDGPUReserveWWMRegsLegacy, DEBUG_TYPE,
56 "AMDGPU Reserve WWM Registers", false, false)
57
58char AMDGPUReserveWWMRegsLegacy::ID = 0;
59
60char &llvm::AMDGPUReserveWWMRegsLegacyID = AMDGPUReserveWWMRegsLegacy::ID;
61
62bool AMDGPUReserveWWMRegsLegacy::runOnMachineFunction(MachineFunction &MF) {
63 return AMDGPUReserveWWMRegs().run(MF);
64}
65
66PreservedAnalyses
67AMDGPUReserveWWMRegsPass::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
75bool 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(i: 0).getReg()
88 : MI.getOperand(i: 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