LLVM 19.0.0git
UniformityAnalysis.cpp
Go to the documentation of this file.
1//===- UniformityAnalysis.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
13#include "llvm/IR/Constants.h"
14#include "llvm/IR/Dominators.h"
18
19using namespace llvm;
20
21template <>
23 const Instruction &I) const {
24 return isDivergent((const Value *)&I);
25}
26
27template <>
29 const Instruction &Instr) {
30 return markDivergent(cast<Value>(&Instr));
31}
32
34 for (auto &I : instructions(F)) {
36 markDivergent(I);
37 else if (TTI->isAlwaysUniform(&I))
38 addUniformOverride(I);
39 }
40 for (auto &Arg : F.args()) {
41 if (TTI->isSourceOfDivergence(&Arg)) {
42 markDivergent(&Arg);
43 }
44 }
45}
46
47template <>
49 const Value *V) {
50 for (const auto *User : V->users()) {
51 if (const auto *UserInstr = dyn_cast<const Instruction>(User)) {
52 markDivergent(*UserInstr);
53 }
54 }
55}
56
57template <>
59 const Instruction &Instr) {
60 assert(!isAlwaysUniform(Instr));
61 if (Instr.isTerminator())
62 return;
63 pushUsers(cast<Value>(&Instr));
64}
65
66template <>
68 const Instruction &I, const Cycle &DefCycle) const {
69 assert(!isAlwaysUniform(I));
70 for (const Use &U : I.operands()) {
71 if (auto *I = dyn_cast<Instruction>(&U)) {
72 if (DefCycle.contains(I->getParent()))
73 return true;
74 }
75 }
76 return false;
77}
78
79template <>
81 SSAContext>::propagateTemporalDivergence(const Instruction &I,
82 const Cycle &DefCycle) {
83 if (isDivergent(I))
84 return;
85 for (auto *User : I.users()) {
86 auto *UserInstr = cast<Instruction>(User);
87 if (DefCycle.contains(UserInstr->getParent()))
88 continue;
89 markDivergent(*UserInstr);
90 }
91}
92
93template <>
95 const Use &U) const {
96 const auto *V = U.get();
97 if (isDivergent(V))
98 return true;
99 if (const auto *DefInstr = dyn_cast<Instruction>(V)) {
100 const auto *UseInstr = cast<Instruction>(U.getUser());
101 return isTemporalDivergent(*UseInstr->getParent(), *DefInstr);
102 }
103 return false;
104}
105
106// This ensures explicit instantiation of
107// GenericUniformityAnalysisImpl::ImplDeleter::operator()
111
112//===----------------------------------------------------------------------===//
113// UniformityInfoAnalysis and related pass implementations
114//===----------------------------------------------------------------------===//
115
120 auto &CI = FAM.getResult<CycleAnalysis>(F);
121 UniformityInfo UI{DT, CI, &TTI};
122 // Skip computation if we can assume everything is uniform.
124 UI.compute();
125
126 return UI;
127}
128
129AnalysisKey UniformityInfoAnalysis::Key;
130
132 : OS(OS) {}
133
136 OS << "UniformityInfo for function '" << F.getName() << "':\n";
138
139 return PreservedAnalyses::all();
140}
141
142//===----------------------------------------------------------------------===//
143// UniformityInfoWrapperPass Implementation
144//===----------------------------------------------------------------------===//
145
147
150}
151
153 "Uniformity Analysis", true, true)
158 "Uniformity Analysis", true, true)
159
160void UniformityInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
161 AU.setPreservesAll();
162 AU.addRequired<DominatorTreeWrapperPass>();
163 AU.addRequiredTransitive<CycleInfoWrapperPass>();
164 AU.addRequired<TargetTransformInfoWrapperPass>();
165}
166
168 auto &cycleInfo = getAnalysis<CycleInfoWrapperPass>().getResult();
169 auto &domTree = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
170 auto &targetTransformInfo =
171 getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
172
173 m_function = &F;
174 m_uniformityInfo = UniformityInfo{domTree, cycleInfo, &targetTransformInfo};
175
176 // Skip computation if we can assume everything is uniform.
177 if (targetTransformInfo.hasBranchDivergence(m_function))
178 m_uniformityInfo.compute();
179
180 return false;
181}
182
184 OS << "UniformityInfo for function '" << m_function->getName() << "':\n";
185}
186
188 m_uniformityInfo = UniformityInfo{};
189 m_function = nullptr;
190}
Expand Atomic instructions
basic Basic Alias true
block Block Frequency Analysis
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
Implementation of uniformity analysis.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
FunctionAnalysisManager FAM
#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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This pass exposes codegen information to IR-level passes.
LLVM IR instance of the generic uniformity analysis.
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:348
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:500
Represent the analysis usage information of a pass.
Analysis pass which computes a CycleInfo.
Definition: CycleAnalysis.h:47
Legacy analysis pass which computes a CycleInfo.
Definition: CycleAnalysis.h:26
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:279
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:317
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:311
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)
Mark outputs of Instr as divergent.
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...
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:109
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:115
Analysis pass providing the TargetTransformInfo.
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
bool isAlwaysUniform(const Value *V) const
bool hasBranchDivergence(const Function *F=nullptr) const
Return true if branch divergence exists.
bool isSourceOfDivergence(const Value *V) const
Returns whether V is a source of divergence.
Analysis pass which computes UniformityInfo.
UniformityInfo run(Function &F, FunctionAnalysisManager &)
Run the analysis pass over a function and produce a dominator tree.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Legacy analysis pass which computes a CycleInfo.
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
void print(raw_ostream &OS, const Module *M=nullptr) const override
print - Print out the internal state of the pass.
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
LLVM Value Representation.
Definition: Value.h:74
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
NodeAddr< InstrNode * > Instr
Definition: RDFGraph.h:389
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
void initializeUniformityInfoWrapperPassPass(PassRegistry &)
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: Analysis.h:26