@@ -59,8 +59,10 @@ class DivergenceAnalysis {
59
59
// / \brief Mark \p UniVal as a value that is always uniform.
60
60
void addUniformOverride (const Value &UniVal);
61
61
62
- // / \brief Mark \p DivVal as a value that is always divergent.
63
- void markDivergent (const Value &DivVal);
62
+ // / \brief Mark \p DivVal as a value that is always divergent. Will not do so
63
+ // / if `isAlwaysUniform(DivVal)`.
64
+ // / \returns Whether the tracked divergence state of \p DivVal changed.
65
+ bool markDivergent (const Value &DivVal);
64
66
65
67
// / \brief Propagate divergence to all instructions in the region.
66
68
// / Divergence is seeded by calls to \p markDivergent.
@@ -76,45 +78,38 @@ class DivergenceAnalysis {
76
78
// / \brief Whether \p Val is divergent at its definition.
77
79
bool isDivergent (const Value &Val) const ;
78
80
79
- // / \brief Whether \p U is divergent. Uses of a uniform value can be divergent.
81
+ // / \brief Whether \p U is divergent. Uses of a uniform value can be
82
+ // / divergent.
80
83
bool isDivergentUse (const Use &U) const ;
81
84
82
85
void print (raw_ostream &OS, const Module *) const ;
83
86
84
87
private:
85
- bool updateTerminator (const Instruction &Term) const ;
86
- bool updatePHINode (const PHINode &Phi) const ;
87
-
88
- // / \brief Computes whether \p Inst is divergent based on the
89
- // / divergence of its operands.
90
- // /
91
- // / \returns Whether \p Inst is divergent.
92
- // /
93
- // / This should only be called for non-phi, non-terminator instructions.
94
- bool updateNormalInstruction (const Instruction &Inst) const ;
95
-
96
- // / \brief Mark users of live-out users as divergent.
97
- // /
98
- // / \param LoopHeader the header of the divergent loop.
99
- // /
100
- // / Marks all users of live-out values of the loop headed by \p LoopHeader
101
- // / as divergent and puts them on the worklist.
102
- void taintLoopLiveOuts (const BasicBlock &LoopHeader);
103
-
104
- // / \brief Push all users of \p Val (in the region) to the worklist
88
+ // / \brief Mark \p Term as divergent and push all Instructions that become
89
+ // / divergent as a result on the worklist.
90
+ void analyzeControlDivergence (const Instruction &Term);
91
+ // / \brief Mark all phi nodes in \p JoinBlock as divergent and push them on
92
+ // / the worklist.
93
+ void taintAndPushPhiNodes (const BasicBlock &JoinBlock);
94
+
95
+ // / \brief Identify all Instructions that become divergent because \p DivExit
96
+ // / is a divergent loop exit of \p DivLoop. Mark those instructions as
97
+ // / divergent and push them on the worklist.
98
+ void propagateLoopExitDivergence (const BasicBlock &DivExit,
99
+ const Loop &DivLoop);
100
+
101
+ // / \brief Internal implementation function for propagateLoopExitDivergence.
102
+ void analyzeLoopExitDivergence (const BasicBlock &DivExit,
103
+ const Loop &OuterDivLoop);
104
+
105
+ // / \brief Mark all instruction as divergent that use a value defined in \p
106
+ // / OuterDivLoop. Push their users on the worklist.
107
+ void analyzeTemporalDivergence (const Instruction &I,
108
+ const Loop &OuterDivLoop);
109
+
110
+ // / \brief Push all users of \p Val (in the region) to the worklist.
105
111
void pushUsers (const Value &I);
106
112
107
- // / \brief Push all phi nodes in @block to the worklist
108
- void pushPHINodes (const BasicBlock &Block);
109
-
110
- // / \brief Mark \p Block as join divergent
111
- // /
112
- // / A block is join divergent if two threads may reach it from different
113
- // / incoming blocks at the same time.
114
- void markBlockJoinDivergent (const BasicBlock &Block) {
115
- DivergentJoinBlocks.insert (&Block);
116
- }
117
-
118
113
// / \brief Whether \p Val is divergent when read in \p ObservingBlock.
119
114
bool isTemporalDivergent (const BasicBlock &ObservingBlock,
120
115
const Value &Val) const ;
@@ -126,24 +121,6 @@ class DivergenceAnalysis {
126
121
return DivergentJoinBlocks.find (&Block) != DivergentJoinBlocks.end ();
127
122
}
128
123
129
- // / \brief Propagate control-induced divergence to users (phi nodes and
130
- // / instructions).
131
- //
132
- // \param JoinBlock is a divergent loop exit or join point of two disjoint
133
- // paths.
134
- // \returns Whether \p JoinBlock is a divergent loop exit of \p TermLoop.
135
- bool propagateJoinDivergence (const BasicBlock &JoinBlock,
136
- const Loop *TermLoop);
137
-
138
- // / \brief Propagate induced value divergence due to control divergence in \p
139
- // / Term.
140
- void propagateBranchDivergence (const Instruction &Term);
141
-
142
- // / \brief Propagate divergent caused by a divergent loop exit.
143
- // /
144
- // / \param ExitingLoop is a divergent loop.
145
- void propagateLoopDivergence (const Loop &ExitingLoop);
146
-
147
124
private:
148
125
const Function &F;
149
126
// If regionLoop != nullptr, analysis is only performed within \p RegionLoop.
@@ -166,7 +143,7 @@ class DivergenceAnalysis {
166
143
DenseSet<const Value *> UniformOverrides;
167
144
168
145
// Blocks with joining divergent control from different predecessors.
169
- DenseSet<const BasicBlock *> DivergentJoinBlocks;
146
+ DenseSet<const BasicBlock *> DivergentJoinBlocks; // FIXME Deprecated
170
147
171
148
// Detected/marked divergent values.
172
149
DenseSet<const Value *> DivergentValues;
0 commit comments