LLVM 17.0.0git
MachineUniformityAnalysis.cpp
Go to the documentation of this file.
1//===- MachineUniformityAnalysis.cpp --------------------------------------===//
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
17
18using namespace llvm;
19
20template <>
22 const MachineInstr &I) const {
23 for (auto &op : I.operands()) {
24 if (!op.isReg() || !op.isDef())
25 continue;
26 if (isDivergent(op.getReg()))
27 return true;
28 }
29 return false;
30}
31
32template <>
34 const MachineInstr &Instr, bool AllDefsDivergent) {
35 bool insertedDivergent = false;
36 const auto &MRI = F.getRegInfo();
37 const auto &TRI = *MRI.getTargetRegisterInfo();
38 for (auto &op : Instr.operands()) {
39 if (!op.isReg() || !op.isDef())
40 continue;
41 if (!op.getReg().isVirtual())
42 continue;
43 assert(!op.getSubReg());
44 if (!AllDefsDivergent) {
45 auto *RC = MRI.getRegClassOrNull(op.getReg());
46 if (RC && !TRI.isDivergentRegClass(RC))
47 continue;
48 }
49 insertedDivergent |= markDivergent(op.getReg());
50 }
51 return insertedDivergent;
52}
53
54template <>
56 const auto &InstrInfo = *F.getSubtarget().getInstrInfo();
57
58 for (const MachineBasicBlock &block : F) {
59 for (const MachineInstr &instr : block) {
60 auto uniformity = InstrInfo.getInstructionUniformity(instr);
61 if (uniformity == InstructionUniformity::AlwaysUniform) {
62 addUniformOverride(instr);
63 continue;
64 }
65
66 if (uniformity == InstructionUniformity::NeverUniform) {
67 markDefsDivergent(instr, /* AllDefsDivergent = */ false);
68 }
69 }
70 }
71}
72
73template <>
75 Register Reg) {
76 const auto &RegInfo = F.getRegInfo();
77 for (MachineInstr &UserInstr : RegInfo.use_instructions(Reg)) {
78 if (markDivergent(UserInstr))
79 Worklist.push_back(&UserInstr);
80 }
81}
82
83template <>
85 const MachineInstr &Instr) {
86 assert(!isAlwaysUniform(Instr));
87 if (Instr.isTerminator())
88 return;
89 for (const MachineOperand &op : Instr.operands()) {
90 if (op.isReg() && op.isDef() && op.getReg().isVirtual())
91 pushUsers(op.getReg());
92 }
93}
94
95template <>
97 const MachineInstr &I, const MachineCycle &DefCycle) const {
98 assert(!isAlwaysUniform(I));
99 for (auto &Op : I.operands()) {
100 if (!Op.isReg() || !Op.readsReg())
101 continue;
102 auto Reg = Op.getReg();
103
104 // FIXME: Physical registers need to be properly checked instead of always
105 // returning true
106 if (Reg.isPhysical())
107 return true;
108
109 auto *Def = F.getRegInfo().getVRegDef(Reg);
110 if (DefCycle.contains(Def->getParent()))
111 return true;
112 }
113 return false;
114}
115
116template <>
118 const MachineOperand &U) const {
119 if (!U.isReg())
120 return false;
121
122 auto Reg = U.getReg();
123 if (isDivergent(Reg))
124 return true;
125
126 const auto &RegInfo = F.getRegInfo();
127 auto *Def = RegInfo.getOneDef(Reg);
128 if (!Def)
129 return true;
130
131 auto *DefInstr = Def->getParent();
132 auto *UseInstr = U.getParent();
133 return isTemporalDivergent(*UseInstr->getParent(), *DefInstr);
134}
135
136// This ensures explicit instantiation of
137// GenericUniformityAnalysisImpl::ImplDeleter::operator()
141
144 const MachineCycleInfo &cycleInfo,
145 const MachineDomTree &domTree) {
146 assert(F.getRegInfo().isSSA() && "Expected to be run on SSA form!");
147 return MachineUniformityInfo(F, domTree, cycleInfo);
148}
149
150namespace {
151
152/// Legacy analysis pass which computes a \ref MachineUniformityInfo.
153class MachineUniformityAnalysisPass : public MachineFunctionPass {
155
156public:
157 static char ID;
158
159 MachineUniformityAnalysisPass();
160
161 MachineUniformityInfo &getUniformityInfo() { return UI; }
162 const MachineUniformityInfo &getUniformityInfo() const { return UI; }
163
164 bool runOnMachineFunction(MachineFunction &F) override;
165 void getAnalysisUsage(AnalysisUsage &AU) const override;
166 void print(raw_ostream &OS, const Module *M = nullptr) const override;
167
168 // TODO: verify analysis
169};
170
171class MachineUniformityInfoPrinterPass : public MachineFunctionPass {
172public:
173 static char ID;
174
175 MachineUniformityInfoPrinterPass();
176
177 bool runOnMachineFunction(MachineFunction &F) override;
178 void getAnalysisUsage(AnalysisUsage &AU) const override;
179};
180
181} // namespace
182
183char MachineUniformityAnalysisPass::ID = 0;
184
185MachineUniformityAnalysisPass::MachineUniformityAnalysisPass()
188}
189
190INITIALIZE_PASS_BEGIN(MachineUniformityAnalysisPass, "machine-uniformity",
191 "Machine Uniformity Info Analysis", true, true)
194INITIALIZE_PASS_END(MachineUniformityAnalysisPass, "machine-uniformity",
195 "Machine Uniformity Info Analysis", true, true)
196
197void MachineUniformityAnalysisPass::getAnalysisUsage(AnalysisUsage &AU) const {
198 AU.setPreservesAll();
199 AU.addRequired<MachineCycleInfoWrapperPass>();
200 AU.addRequired<MachineDominatorTree>();
202}
203
204bool MachineUniformityAnalysisPass::runOnMachineFunction(MachineFunction &MF) {
205 auto &DomTree = getAnalysis<MachineDominatorTree>().getBase();
206 auto &CI = getAnalysis<MachineCycleInfoWrapperPass>().getCycleInfo();
207 UI = computeMachineUniformityInfo(MF, CI, DomTree);
208 return false;
209}
210
211void MachineUniformityAnalysisPass::print(raw_ostream &OS,
212 const Module *) const {
213 OS << "MachineUniformityInfo for function: " << UI.getFunction().getName()
214 << "\n";
215 UI.print(OS);
216}
217
218char MachineUniformityInfoPrinterPass::ID = 0;
219
220MachineUniformityInfoPrinterPass::MachineUniformityInfoPrinterPass()
224}
225
226INITIALIZE_PASS_BEGIN(MachineUniformityInfoPrinterPass,
227 "print-machine-uniformity",
228 "Print Machine Uniformity Info Analysis", true, true)
229INITIALIZE_PASS_DEPENDENCY(MachineUniformityAnalysisPass)
230INITIALIZE_PASS_END(MachineUniformityInfoPrinterPass,
231 "print-machine-uniformity",
232 "Print Machine Uniformity Info Analysis", true, true)
233
234void MachineUniformityInfoPrinterPass::getAnalysisUsage(
235 AnalysisUsage &AU) const {
236 AU.setPreservesAll();
237 AU.addRequired<MachineUniformityAnalysisPass>();
239}
240
241bool MachineUniformityInfoPrinterPass::runOnMachineFunction(
243 auto &UI = getAnalysis<MachineUniformityAnalysisPass>();
244 UI.print(errs());
245 return false;
246}
unsigned const MachineRegisterInfo * MRI
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Implementation of uniformity analysis.
#define op(i)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file declares a specialization of the GenericSSAContext<X> template class for Machine IR.
unsigned const TargetRegisterInfo * TRI
machine uniformity
machine Machine Uniformity Info Analysis
machine Machine Uniformity Info true
Machine IR instance of the generic uniformity analysis.
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:55
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:59
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:52
return InstrInfo
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
unify loop Fixup each natural loop to have a single exit block
Represent the analysis usage information of a pass.
Core dominator tree base class.
A possibly irreducible generalization of a Loop.
bool contains(const BlockT *Block) const
Return whether Block is contained in the cycle.
Analysis that identifies uniform values in a data-parallel execution.
bool isDivergentUse(const UseT &U) const
bool hasDivergentDefs(const InstructionT &I) const
bool markDefsDivergent(const InstructionT &Instr, bool AllDefsDivergent=true)
Legacy analysis pass which computes a MachineCycleInfo.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Representation of each machine instruction.
Definition: MachineInstr.h:68
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
Definition: MachineInstr.h:896
iterator_range< mop_iterator > operands()
Definition: MachineInstr.h:641
MachineOperand class - Representation of each machine instruction operand.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
Definition: Pass.cpp:130
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineUniformityInfo computeMachineUniformityInfo(MachineFunction &F, const MachineCycleInfo &cycleInfo, const MachineDomTree &domTree)
Compute uniformity information for a Machine IR function.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void initializeMachineUniformityAnalysisPassPass(PassRegistry &)
GenericUniformityInfo< MachineSSAContext > MachineUniformityInfo
void initializeMachineUniformityInfoPrinterPassPass(PassRegistry &)