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(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 |