83 class DivergencePropagator {
87 : F(F), TTI(TTI), DT(DT), PDT(PDT), DV(DV) {}
88 void populateWithSourcesOfDivergence();
93 void exploreDataDependency(
Value *V);
102 void findUsersOutsideInfluenceRegion(
109 std::vector<Value *> Worklist;
113 void DivergencePropagator::populateWithSourcesOfDivergence() {
117 if (TTI.isSourceOfDivergence(&
I)) {
118 Worklist.push_back(&
I);
122 for (
auto &Arg :
F.args()) {
123 if (TTI.isSourceOfDivergence(&Arg)) {
124 Worklist.push_back(&Arg);
130 void DivergencePropagator::exploreSyncDependency(
TerminatorInst *TI) {
143 if (!DT.isReachableFromEntry(ThisBB))
153 if (IPostDom ==
nullptr)
156 for (
auto I = IPostDom->
begin(); isa<PHINode>(
I); ++
I) {
159 if (!cast<PHINode>(
I)->hasConstantOrUndefValue() && DV.insert(&*
I).second)
160 Worklist.push_back(&*
I);
183 computeInfluenceRegion(ThisBB, IPostDom, InfluenceRegion);
189 while (InfluenceRegion.
count(InfluencedBB)) {
190 for (
auto &
I : *InfluencedBB)
191 findUsersOutsideInfluenceRegion(
I, InfluenceRegion);
193 if (IDomNode ==
nullptr)
195 InfluencedBB = IDomNode->
getBlock();
199 void DivergencePropagator::findUsersOutsideInfluenceRegion(
204 if (DV.insert(UserInst).second)
205 Worklist.push_back(UserInst);
215 std::vector<BasicBlock *> &InfluenceStack) {
217 if (Succ != End && InfluenceRegion.
insert(Succ).second)
218 InfluenceStack.push_back(Succ);
222 void DivergencePropagator::computeInfluenceRegion(
225 assert(PDT.properlyDominates(End, Start) &&
226 "End does not properly dominate Start");
231 std::vector<BasicBlock *> InfluenceStack;
232 addSuccessorsToInfluenceRegion(Start, End, InfluenceRegion, InfluenceStack);
233 while (!InfluenceStack.empty()) {
235 InfluenceStack.pop_back();
236 addSuccessorsToInfluenceRegion(BB, End, InfluenceRegion, InfluenceStack);
240 void DivergencePropagator::exploreDataDependency(
Value *V) {
244 if (DV.insert(UserInst).second)
245 Worklist.push_back(UserInst);
251 while (!Worklist.empty()) {
252 Value *V = Worklist.back();
258 exploreSyncDependency(TI);
260 exploreDataDependency(V);
276 return new DivergenceAnalysis();
286 auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>();
287 if (TTIWP ==
nullptr)
296 DivergentValues.clear();
297 auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
298 DivergencePropagator DP(F, TTI,
299 getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
300 PDT, DivergentValues);
301 DP.populateWithSourcesOfDivergence();
307 if (DivergentValues.empty())
309 const Value *FirstDivergentValue = *DivergentValues.begin();
311 if (
const Argument *Arg = dyn_cast<Argument>(FirstDivergentValue)) {
314 dyn_cast<Instruction>(FirstDivergentValue)) {
321 for (
auto &Arg : F->
args()) {
322 if (DivergentValues.count(&Arg))
323 OS <<
"DIVERGENT: " << Arg <<
"\n";
327 if (DivergentValues.count(&I))
328 OS <<
"DIVERGENT:" << I <<
"\n";
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
LLVM Argument representation.
const Instruction & back() const
A Module instance is used to store all the information related to an LLVM module. ...
Implements a dense probed hash-table based set.
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
const Function * getParent() const
Return the enclosing method, or null if none.
iterator begin()
Instruction iterator methods.
DomTreeNodeBase< NodeT > * getIDom() const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
FunctionPass * createDivergenceAnalysisPass()
Base class for the actual dominator tree node.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
Subclasses of this class are all able to terminate a basic block.
LLVM Basic Block Representation.
void print(raw_ostream &OS, const Module *) const override
print - Print out the internal state of the pass.
std::pair< iterator, bool > insert(const ValueT &V)
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
static const unsigned End
FunctionPass class - This class is used to implement most global optimizations.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static char ID
end namespace anonymous
void setPreservesAll()
Set by analyses that do not transform their input at all.
iterator_range< user_iterator > users()
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
static void propagate(InstantiatedValue From, InstantiatedValue To, MatchState State, ReachabilitySet &ReachSet, std::vector< WorkListItem > &WorkList)
size_type count(const ValueT &V) const
Return 1 if the specified key is in the set, 0 otherwise.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
succ_range successors(BasicBlock *BB)
This class implements an extremely fast bulk output stream that can only output to a stream...
inst_range instructions(Function *F)
INITIALIZE_PASS_BEGIN(DivergenceAnalysis,"divergence","Divergence Analysis", false, true) INITIALIZE_PASS_END(DivergenceAnalysis
Legacy analysis pass which computes a DominatorTree.
const BasicBlock * getParent() const
iterator_range< arg_iterator > args()