LLVM 22.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
18
19using namespace llvm;
20
21template <>
23 const MachineInstr &I) const {
24 for (auto &op : I.all_defs()) {
25 if (isDivergent(op.getReg()))
26 return true;
27 }
28 return false;
29}
30
31template <>
33 const MachineInstr &Instr) {
34 bool insertedDivergent = false;
35 const auto &MRI = F.getRegInfo();
36 const auto &RBI = *F.getSubtarget().getRegBankInfo();
37 const auto &TRI = *MRI.getTargetRegisterInfo();
38 for (auto &op : Instr.all_defs()) {
39 if (!op.getReg().isVirtual())
40 continue;
41 assert(!op.getSubReg());
42 if (TRI.isUniformReg(MRI, RBI, op.getReg()))
43 continue;
44 insertedDivergent |= markDivergent(op.getReg());
45 }
46 return insertedDivergent;
47}
48
49template <>
51 const auto &InstrInfo = *F.getSubtarget().getInstrInfo();
52
53 for (const MachineBasicBlock &block : F) {
54 for (const MachineInstr &instr : block) {
55 auto uniformity = InstrInfo.getInstructionUniformity(instr);
56
57 switch (uniformity) {
60 break;
63 break;
65 break;
66 }
67 }
68 }
69}
70
71template <>
72void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::pushUsers(
73 Register Reg) {
74 assert(isDivergent(Reg));
75 const auto &RegInfo = F.getRegInfo();
76 for (MachineInstr &UserInstr : RegInfo.use_instructions(Reg)) {
77 markDivergent(UserInstr);
78 }
79}
80
81template <>
82void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::pushUsers(
83 const MachineInstr &Instr) {
84 assert(!isAlwaysUniform(Instr));
85 if (Instr.isTerminator())
86 return;
87 for (const MachineOperand &op : Instr.all_defs()) {
88 auto Reg = op.getReg();
89 if (isDivergent(Reg))
90 pushUsers(Reg);
91 }
92}
93
94template <>
95bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::usesValueFromCycle(
96 const MachineInstr &I, const MachineCycle &DefCycle) const {
97 assert(!isAlwaysUniform(I));
98 for (auto &Op : I.operands()) {
99 if (!Op.isReg() || !Op.readsReg())
100 continue;
101 auto Reg = Op.getReg();
102
103 // FIXME: Physical registers need to be properly checked instead of always
104 // returning true
105 if (Reg.isPhysical())
106 return true;
107
108 auto *Def = F.getRegInfo().getVRegDef(Reg);
109 if (DefCycle.contains(Def->getParent()))
110 return true;
111 }
112 return false;
113}
114
115template <>
118 const MachineCycle &DefCycle) {
119 const auto &RegInfo = F.getRegInfo();
120 for (auto &Op : I.all_defs()) {
121 if (!Op.getReg().isVirtual())
122 continue;
123 auto Reg = Op.getReg();
124 for (MachineInstr &UserInstr : RegInfo.use_instructions(Reg)) {
125 if (DefCycle.contains(UserInstr.getParent()))
126 continue;
127 markDivergent(UserInstr);
128
129 recordTemporalDivergence(Reg, &UserInstr, &DefCycle);
130 }
131 }
132}
133
134template <>
136 const MachineOperand &U) const {
137 if (!U.isReg())
138 return false;
139
140 auto Reg = U.getReg();
141 if (isDivergent(Reg))
142 return true;
143
144 const auto &RegInfo = F.getRegInfo();
145 auto *Def = RegInfo.getOneDef(Reg);
146 if (!Def)
147 return true;
148
149 auto *DefInstr = Def->getParent();
150 auto *UseInstr = U.getParent();
151 return isTemporalDivergent(*UseInstr->getParent(), *DefInstr);
152}
153
154// This ensures explicit instantiation of
155// GenericUniformityAnalysisImpl::ImplDeleter::operator()
159
161 MachineFunction &F, const MachineCycleInfo &cycleInfo,
162 const MachineDominatorTree &domTree, bool HasBranchDivergence) {
163 assert(F.getRegInfo().isSSA() && "Expected to be run on SSA form!");
164 MachineUniformityInfo UI(domTree, cycleInfo);
165 if (HasBranchDivergence)
166 UI.compute();
167 return UI;
168}
169
170namespace {
171
172class MachineUniformityInfoPrinterPass : public MachineFunctionPass {
173public:
174 static char ID;
175
176 MachineUniformityInfoPrinterPass();
177
178 bool runOnMachineFunction(MachineFunction &F) override;
179 void getAnalysisUsage(AnalysisUsage &AU) const override;
180};
181
182} // namespace
183
184AnalysisKey MachineUniformityAnalysis::Key;
185
189 auto &DomTree = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
190 auto &CI = MFAM.getResult<MachineCycleAnalysis>(MF);
192 .getManager();
193 auto &F = MF.getFunction();
194 auto &TTI = FAM.getResult<TargetIRAnalysis>(F);
195 return computeMachineUniformityInfo(MF, CI, DomTree,
196 TTI.hasBranchDivergence(&F));
197}
198
202 auto &MUI = MFAM.getResult<MachineUniformityAnalysis>(MF);
203 OS << "MachineUniformityInfo for function: ";
204 MF.getFunction().printAsOperand(OS, /*PrintType=*/false);
205 OS << '\n';
206 MUI.print(OS);
207 return PreservedAnalyses::all();
208}
209
211
216
218 "Machine Uniformity Info Analysis", false, true)
222 "Machine Uniformity Info Analysis", false, true)
223
225 AU.setPreservesAll();
226 AU.addRequiredTransitive<MachineCycleInfoWrapperPass>();
227 AU.addRequired<MachineDominatorTreeWrapperPass>();
229}
230
232 auto &DomTree = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
233 auto &CI = getAnalysis<MachineCycleInfoWrapperPass>().getCycleInfo();
234 // FIXME: Query TTI::hasBranchDivergence. -run-pass seems to end up with a
235 // default NoTTI
236 UI = computeMachineUniformityInfo(MF, CI, DomTree, true);
237 return false;
238}
239
241 const Module *) const {
242 OS << "MachineUniformityInfo for function: ";
243 UI.getFunction().getFunction().printAsOperand(OS, /*PrintType=*/false);
244 OS << '\n';
245 UI.print(OS);
246}
247
248char MachineUniformityInfoPrinterPass::ID = 0;
249
250MachineUniformityInfoPrinterPass::MachineUniformityInfoPrinterPass()
254}
255
256INITIALIZE_PASS_BEGIN(MachineUniformityInfoPrinterPass,
257 "print-machine-uniformity",
258 "Print Machine Uniformity Info Analysis", true, true)
260INITIALIZE_PASS_END(MachineUniformityInfoPrinterPass,
261 "print-machine-uniformity",
262 "Print Machine Uniformity Info Analysis", true, true)
263
264void MachineUniformityInfoPrinterPass::getAnalysisUsage(
265 AnalysisUsage &AU) const {
266 AU.setPreservesAll();
267 AU.addRequired<MachineUniformityAnalysisPass>();
269}
270
271bool MachineUniformityInfoPrinterPass::runOnMachineFunction(
273 auto &UI = getAnalysis<MachineUniformityAnalysisPass>();
274 UI.print(errs());
275 return false;
276}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Implementation of uniformity analysis.
#define op(i)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file declares a specialization of the GenericSSAContext<X> template class for Machine IR.
Register Reg
Register const TargetRegisterInfo * TRI
Machine IR instance of the generic uniformity analysis.
FunctionAnalysisManager FAM
#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
This pass exposes codegen information to IR-level passes.
unify loop Fixup each natural loop to have a single exit block
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
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)
Mark outputs of Instr as divergent.
bool isDivergent(const InstructionT &I) const
void markDivergent(const InstructionT &I)
Examine I for divergent outputs and add to the worklist.
void addUniformOverride(const InstructionT &Instr)
Mark UniVal as a value that is always uniform.
Legacy analysis pass which computes a MachineCycleInfo.
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
Legacy analysis pass which computes a MachineUniformityInfo.
void print(raw_ostream &OS, const Module *M=nullptr) const override
print - Print out the internal state of the pass.
bool runOnMachineFunction(MachineFunction &F) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
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
Analysis pass providing the TargetTransformInfo.
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
NodeAddr< DefNode * > Def
Definition RDFGraph.h:384
NodeAddr< InstrNode * > Instr
Definition RDFGraph.h:389
This is an optimization pass for GlobalISel generic memory operations.
GenericUniformityInfo< MachineSSAContext > MachineUniformityInfo
LLVM_ABI void initializeMachineUniformityAnalysisPassPass(PassRegistry &)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
TargetTransformInfo TTI
DWARFExpression::Operation Op
MachineUniformityInfo computeMachineUniformityInfo(MachineFunction &F, const MachineCycleInfo &cycleInfo, const MachineDominatorTree &domTree, bool HasBranchDivergence)
Compute uniformity information for a Machine IR function.
@ AlwaysUniform
The result values are always uniform.
Definition Uniformity.h:23
@ NeverUniform
The result values can never be assumed to be uniform.
Definition Uniformity.h:26
@ Default
The result values are uniform if and only if all operands are uniform.
Definition Uniformity.h:20
GenericCycleInfo< MachineSSAContext > MachineCycleInfo
MachineCycleInfo::CycleT MachineCycle
LLVM_ABI void initializeMachineUniformityInfoPrinterPassPass(PassRegistry &)
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29