LLVM 23.0.0git
SILowerWWMCopies.cpp
Go to the documentation of this file.
1//===-- SILowerWWMCopies.cpp - Lower Copies after regalloc ---===//
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/// Lowering the WWM_COPY instructions for various register classes.
11/// AMDGPU target generates WWM_COPY instruction to differentiate WWM
12/// copy from COPY. This pass generates the necessary exec mask manipulation
13/// instructions to replicate 'Whole Wave Mode' and lowers WWM_COPY back to
14/// COPY.
15//
16//===----------------------------------------------------------------------===//
17
18#include "SILowerWWMCopies.h"
19#include "AMDGPU.h"
20#include "GCNSubtarget.h"
27
28using namespace llvm;
29
30#define DEBUG_TYPE "si-lower-wwm-copies"
31
32namespace {
33
34class SILowerWWMCopies {
35public:
36 SILowerWWMCopies(LiveIntervals *LIS, SlotIndexes *SI, VirtRegMap *VRM)
37 : LIS(LIS), Indexes(SI), VRM(VRM) {}
38 bool run(MachineFunction &MF);
39
40private:
41 bool isSCCLiveAtMI(const MachineInstr &MI);
42 void addToWWMSpills(MachineFunction &MF, Register Reg);
43
44 LiveIntervals *LIS;
45 SlotIndexes *Indexes;
46 VirtRegMap *VRM;
47 const SIRegisterInfo *TRI;
50};
51
52class SILowerWWMCopiesLegacy : public MachineFunctionPass {
53public:
54 static char ID;
55
56 SILowerWWMCopiesLegacy() : MachineFunctionPass(ID) {}
57
58 bool runOnMachineFunction(MachineFunction &MF) override;
59
60 StringRef getPassName() const override { return "SI Lower WWM Copies"; }
61
62 void getAnalysisUsage(AnalysisUsage &AU) const override {
66 AU.setPreservesAll();
68 }
69};
70
71} // End anonymous namespace.
72
73INITIALIZE_PASS_BEGIN(SILowerWWMCopiesLegacy, DEBUG_TYPE, "SI Lower WWM Copies",
74 false, false)
77INITIALIZE_PASS_END(SILowerWWMCopiesLegacy, DEBUG_TYPE, "SI Lower WWM Copies",
79
80char SILowerWWMCopiesLegacy::ID = 0;
81
82char &llvm::SILowerWWMCopiesLegacyID = SILowerWWMCopiesLegacy::ID;
83
84bool SILowerWWMCopies::isSCCLiveAtMI(const MachineInstr &MI) {
85 // We can't determine the liveness info if LIS isn't available. Early return
86 // in that case and always assume SCC is live.
87 if (!LIS)
88 return true;
89
90 LiveRange &LR =
91 LIS->getRegUnit(*MCRegUnitIterator(MCRegister::from(AMDGPU::SCC), TRI));
92 SlotIndex Idx = LIS->getInstructionIndex(MI);
93 return LR.liveAt(Idx);
94}
95
96// If \p Reg is assigned with a physical VGPR, add the latter into wwm-spills
97// for preserving its entire lanes at function prolog/epilog.
98void SILowerWWMCopies::addToWWMSpills(MachineFunction &MF, Register Reg) {
99 if (Reg.isPhysical())
100 return;
101
102 // FIXME: VRM may be null here.
103 MCRegister PhysReg = VRM->getPhys(Reg);
104 assert(PhysReg && "should have allocated a physical register");
105
106 MFI->allocateWWMSpill(MF, PhysReg);
107}
108
109bool SILowerWWMCopiesLegacy::runOnMachineFunction(MachineFunction &MF) {
110 auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
111 auto *LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
112
113 auto *SIWrapper = getAnalysisIfAvailable<SlotIndexesWrapperPass>();
114 auto *Indexes = SIWrapper ? &SIWrapper->getSI() : nullptr;
115
116 auto *VRMWrapper = getAnalysisIfAvailable<VirtRegMapWrapperLegacy>();
117 auto *VRM = VRMWrapper ? &VRMWrapper->getVRM() : nullptr;
118
119 SILowerWWMCopies Impl(LIS, Indexes, VRM);
120 return Impl.run(MF);
121}
122
123PreservedAnalyses
126 auto *LIS = MFAM.getCachedResult<LiveIntervalsAnalysis>(MF);
127 auto *Indexes = MFAM.getCachedResult<SlotIndexesAnalysis>(MF);
128 auto *VRM = MFAM.getCachedResult<VirtRegMapAnalysis>(MF);
129
130 SILowerWWMCopies Impl(LIS, Indexes, VRM);
131 Impl.run(MF);
132 return PreservedAnalyses::all();
133}
134
135bool SILowerWWMCopies::run(MachineFunction &MF) {
136 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
137 const SIInstrInfo *TII = ST.getInstrInfo();
138
139 MFI = MF.getInfo<SIMachineFunctionInfo>();
140 TRI = ST.getRegisterInfo();
141 MRI = &MF.getRegInfo();
142
143 if (!MFI->hasVRegFlags())
144 return false;
145
146 bool Changed = false;
147 for (MachineBasicBlock &MBB : MF) {
148 for (MachineInstr &MI : MBB) {
149 if (MI.getOpcode() != AMDGPU::WWM_COPY)
150 continue;
151
152 // TODO: Club adjacent WWM ops between same exec save/restore
153 assert(TII->isVGPRCopy(MI));
154
155 // For WWM vector copies, manipulate the exec mask around the copy
156 // instruction.
157 const DebugLoc &DL = MI.getDebugLoc();
158 MachineBasicBlock::iterator InsertPt = MI.getIterator();
159 Register RegForExecCopy = MFI->getSGPRForEXECCopy();
160 TII->insertScratchExecCopy(MF, MBB, InsertPt, DL, RegForExecCopy,
161 isSCCLiveAtMI(MI), Indexes);
162 TII->restoreExec(MF, MBB, ++InsertPt, DL, RegForExecCopy, Indexes);
163 addToWWMSpills(MF, MI.getOperand(0).getReg());
164 LLVM_DEBUG(dbgs() << "WWM copy manipulation for " << MI);
165
166 // Lower WWM_COPY back to COPY
167 MI.setDesc(TII->get(AMDGPU::COPY));
168 Changed |= true;
169 }
170 }
171
172 return Changed;
173}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
Provides AMDGPU specific target descriptions.
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
AMD GCN specific subclass of TargetSubtarget.
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Register Reg
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
#define LLVM_DEBUG(...)
Definition Debug.h:114
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
A debug info location.
Definition DebugLoc.h:123
This class represents the liveness of a register, stack slot, etc.
bool liveAt(SlotIndex index) const
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
Definition MCRegister.h:77
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
Wrapper class representing virtual and physical registers.
Definition Register.h:20
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
void allocateWWMSpill(MachineFunction &MF, Register VGPR, uint64_t Size=4, Align Alignment=Align(4))
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
SlotIndexes pass.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
Definition VirtRegMap.h:91
Changed
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
char & SILowerWWMCopiesLegacyID