LLVM 22.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/Dominators.h"
17
18using namespace llvm;
19
20template <>
22 const Instruction &I) const {
23 return isDivergent((const Value *)&I);
24}
25
26template <>
28 const Instruction &Instr) {
29 return markDivergent(cast<Value>(&Instr));
30}
31
33 for (auto &I : instructions(F)) {
35 markDivergent(I);
36 else if (TTI->isAlwaysUniform(&I))
37 addUniformOverride(I);
38 }
39 for (auto &Arg : F.args()) {
40 if (TTI->isSourceOfDivergence(&Arg)) {
41 markDivergent(&Arg);
42 }
43 }
44}
45
46template <>
48 const Value *V) {
49 for (const auto *User : V->users()) {
50 if (const auto *UserInstr = dyn_cast<const Instruction>(User)) {
51 markDivergent(*UserInstr);
52 }
53 }
54}
55
56template <>
58 const Instruction &Instr) {
59 assert(!isAlwaysUniform(Instr));
60 if (Instr.isTerminator())
61 return;
62 pushUsers(cast<Value>(&Instr));
63}
64
65template <>
67 const Instruction &I, const Cycle &DefCycle) const {
68 assert(!isAlwaysUniform(I));
69 for (const Use &U : I.operands()) {
70 if (auto *I = dyn_cast<Instruction>(&U)) {
71 if (DefCycle.contains(I->getParent()))
72 return true;
73 }
74 }
75 return false;
76}
77
78template <>
80 SSAContext>::propagateTemporalDivergence(const Instruction &I,
81 const Cycle &DefCycle) {
82 for (auto *User : I.users()) {
83 auto *UserInstr = cast<Instruction>(User);
84 if (DefCycle.contains(UserInstr->getParent()))
85 continue;
86 markDivergent(*UserInstr);
87 recordTemporalDivergence(&I, UserInstr, &DefCycle);
88 }
89}
90
91template <>
93 const Use &U) const {
94 const auto *V = U.get();
95 if (isDivergent(V))
96 return true;
97 if (const auto *DefInstr = dyn_cast<Instruction>(V)) {
98 const auto *UseInstr = cast<Instruction>(U.getUser());
99 return isTemporalDivergent(*UseInstr->getParent(), *DefInstr);
100 }
101 return false;
102}
103
104// This ensures explicit instantiation of
105// GenericUniformityAnalysisImpl::ImplDeleter::operator()
109
110//===----------------------------------------------------------------------===//
111// UniformityInfoAnalysis and related pass implementations
112//===----------------------------------------------------------------------===//
113
118 auto &CI = FAM.getResult<CycleAnalysis>(F);
119 UniformityInfo UI{DT, CI, &TTI};
120 // Skip computation if we can assume everything is uniform.
122 UI.compute();
123
124 return UI;
125}
126
127AnalysisKey UniformityInfoAnalysis::Key;
128
130 : OS(OS) {}
131
134 OS << "UniformityInfo for function '" << F.getName() << "':\n";
136
137 return PreservedAnalyses::all();
138}
139
140//===----------------------------------------------------------------------===//
141// UniformityInfoWrapperPass Implementation
142//===----------------------------------------------------------------------===//
143
145
147
149 "Uniformity Analysis", false, true)
154 "Uniformity Analysis", false, true)
155
156void UniformityInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
157 AU.setPreservesAll();
158 AU.addRequired<DominatorTreeWrapperPass>();
159 AU.addRequiredTransitive<CycleInfoWrapperPass>();
160 AU.addRequired<TargetTransformInfoWrapperPass>();
161}
162
164 auto &cycleInfo = getAnalysis<CycleInfoWrapperPass>().getResult();
165 auto &domTree = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
166 auto &targetTransformInfo =
167 getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
168
169 m_function = &F;
170 m_uniformityInfo = UniformityInfo{domTree, cycleInfo, &targetTransformInfo};
171
172 // Skip computation if we can assume everything is uniform.
173 if (targetTransformInfo.hasBranchDivergence(m_function))
174 m_uniformityInfo.compute();
175
176 return false;
177}
178
180 OS << "UniformityInfo for function '" << m_function->getName() << "':\n";
181 m_uniformityInfo.print(OS);
182}
183
185 m_uniformityInfo = UniformityInfo{};
186 m_function = nullptr;
187}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
block Block Frequency Analysis
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: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
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:255
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:412
Represent the analysis usage information of a pass.
Analysis pass which computes a CycleInfo.
Definition: CycleAnalysis.h:46
Legacy analysis pass which computes a CycleInfo.
Definition: CycleAnalysis.h:25
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:284
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:322
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:314
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.
void print(raw_ostream &Out) const
T helper function for printing.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
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
Analysis pass providing the TargetTransformInfo.
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
LLVM_ABI bool isAlwaysUniform(const Value *V) const
LLVM_ABI bool hasBranchDivergence(const Function *F=nullptr) const
Return true if branch divergence exists.
LLVM_ABI 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:35
LLVM Value Representation.
Definition: Value.h:75
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
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, unsigned DynamicVGPRBlockSize=0)
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: Analysis.h:29