1- // ===- LegacyDivergenceAnalysis.cpp --------- Legacy Divergence Analysis Implementation -==//
1+ // ===- LegacyDivergenceAnalysis.cpp --------- Legacy Divergence Analysis
2+ // Implementation -==//
23//
34// The LLVM Compiler Infrastructure
45//
6465//
6566// ===----------------------------------------------------------------------===//
6667
68+ #include " llvm/ADT/PostOrderIterator.h"
69+ #include " llvm/Analysis/CFG.h"
70+ #include " llvm/Analysis/DivergenceAnalysis.h"
6771#include " llvm/Analysis/LegacyDivergenceAnalysis.h"
6872#include " llvm/Analysis/Passes.h"
6973#include " llvm/Analysis/PostDominators.h"
@@ -79,6 +83,12 @@ using namespace llvm;
7983
8084#define DEBUG_TYPE " divergence"
8185
86+ // transparently use the GPUDivergenceAnalysis
87+ static cl::opt<bool > UseGPUDA (" use-gpu-divergence-analysis" , cl::init(false ),
88+ cl::Hidden,
89+ cl::desc(" turn the LegacyDivergenceAnalysis into "
90+ " a wrapper for GPUDivergenceAnalysis" ));
91+
8292namespace {
8393
8494class DivergencePropagator {
@@ -262,16 +272,17 @@ void DivergencePropagator::propagate() {
262272 }
263273}
264274
265- } // / end namespace anonymous
275+ } // namespace
266276
267277// Register this pass.
268278char LegacyDivergenceAnalysis::ID = 0 ;
269- INITIALIZE_PASS_BEGIN (LegacyDivergenceAnalysis, " divergence" , " Legacy Divergence Analysis " ,
270- false , true )
279+ INITIALIZE_PASS_BEGIN (LegacyDivergenceAnalysis, " divergence" ,
280+ " Legacy Divergence Analysis " , false , true )
271281INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
272282INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
273- INITIALIZE_PASS_END(LegacyDivergenceAnalysis, " divergence" , " Legacy Divergence Analysis" ,
274- false , true )
283+ INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
284+ INITIALIZE_PASS_END(LegacyDivergenceAnalysis, " divergence" ,
285+ " Legacy Divergence Analysis" , false , true )
275286
276287FunctionPass *llvm::createLegacyDivergenceAnalysisPass() {
277288 return new LegacyDivergenceAnalysis ();
@@ -280,9 +291,24 @@ FunctionPass *llvm::createLegacyDivergenceAnalysisPass() {
280291void LegacyDivergenceAnalysis::getAnalysisUsage (AnalysisUsage &AU) const {
281292 AU.addRequired <DominatorTreeWrapperPass>();
282293 AU.addRequired <PostDominatorTreeWrapperPass>();
294+ if (UseGPUDA)
295+ AU.addRequired <LoopInfoWrapperPass>();
283296 AU.setPreservesAll ();
284297}
285298
299+ bool LegacyDivergenceAnalysis::shouldUseGPUDivergenceAnalysis (
300+ const Function &F) const {
301+ if (!UseGPUDA)
302+ return false ;
303+
304+ // GPUDivergenceAnalysis requires a reducible CFG.
305+ auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo ();
306+ using RPOTraversal = ReversePostOrderTraversal<const Function *>;
307+ RPOTraversal FuncRPOT (&F);
308+ return !containsIrreducibleCFG<const BasicBlock *, const RPOTraversal,
309+ const LoopInfo>(FuncRPOT, LI);
310+ }
311+
286312bool LegacyDivergenceAnalysis::runOnFunction (Function &F) {
287313 auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>();
288314 if (TTIWP == nullptr )
@@ -295,44 +321,67 @@ bool LegacyDivergenceAnalysis::runOnFunction(Function &F) {
295321 return false ;
296322
297323 DivergentValues.clear ();
324+ gpuDA = nullptr ;
325+
326+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
298327 auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree ();
299- DivergencePropagator DP (F, TTI,
300- getAnalysis<DominatorTreeWrapperPass>().getDomTree (),
301- PDT, DivergentValues);
302- DP.populateWithSourcesOfDivergence ();
303- DP.propagate ();
304- LLVM_DEBUG (
305- dbgs () << " \n After divergence analysis on " << F.getName () << " :\n " ;
306- print (dbgs (), F.getParent ())
307- );
328+
329+ if (shouldUseGPUDivergenceAnalysis (F)) {
330+ // run the new GPU divergence analysis
331+ auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo ();
332+ gpuDA = llvm::make_unique<GPUDivergenceAnalysis>(F, DT, PDT, LI, TTI);
333+
334+ } else {
335+ // run LLVM's existing DivergenceAnalysis
336+ DivergencePropagator DP (F, TTI, DT, PDT, DivergentValues);
337+ DP.populateWithSourcesOfDivergence ();
338+ DP.propagate ();
339+ }
340+
341+ LLVM_DEBUG (dbgs () << " \n After divergence analysis on " << F.getName ()
342+ << " :\n " ;
343+ print (dbgs (), F.getParent ()));
344+
308345 return false ;
309346}
310347
348+ bool LegacyDivergenceAnalysis::isDivergent (const Value *V) const {
349+ if (gpuDA) {
350+ return gpuDA->isDivergent (*V);
351+ }
352+ return DivergentValues.count (V);
353+ }
354+
311355void LegacyDivergenceAnalysis::print (raw_ostream &OS, const Module *) const {
312- if (DivergentValues.empty ())
356+ if ((!gpuDA || !gpuDA-> hasDivergence ()) && DivergentValues.empty ())
313357 return ;
314- const Value *FirstDivergentValue = *DivergentValues. begin ();
358+
315359 const Function *F;
316- if (const Argument *Arg = dyn_cast<Argument>(FirstDivergentValue)) {
317- F = Arg->getParent ();
318- } else if (const Instruction *I =
319- dyn_cast<Instruction>(FirstDivergentValue)) {
320- F = I->getParent ()->getParent ();
321- } else {
322- llvm_unreachable (" Only arguments and instructions can be divergent" );
360+ if (!DivergentValues.empty ()) {
361+ const Value *FirstDivergentValue = *DivergentValues.begin ();
362+ if (const Argument *Arg = dyn_cast<Argument>(FirstDivergentValue)) {
363+ F = Arg->getParent ();
364+ } else if (const Instruction *I =
365+ dyn_cast<Instruction>(FirstDivergentValue)) {
366+ F = I->getParent ()->getParent ();
367+ } else {
368+ llvm_unreachable (" Only arguments and instructions can be divergent" );
369+ }
370+ } else if (gpuDA) {
371+ F = &gpuDA->getFunction ();
323372 }
324373
325374 // Dumps all divergent values in F, arguments and then instructions.
326375 for (auto &Arg : F->args ()) {
327- OS << (DivergentValues. count (&Arg) ? " DIVERGENT: " : " " );
376+ OS << (isDivergent (&Arg) ? " DIVERGENT: " : " " );
328377 OS << Arg << " \n " ;
329378 }
330379 // Iterate instructions using instructions() to ensure a deterministic order.
331380 for (auto BI = F->begin (), BE = F->end (); BI != BE; ++BI) {
332381 auto &BB = *BI;
333382 OS << " \n " << BB.getName () << " :\n " ;
334383 for (auto &I : BB.instructionsWithoutDebug ()) {
335- OS << (DivergentValues. count (&I) ? " DIVERGENT: " : " " );
384+ OS << (isDivergent (&I) ? " DIVERGENT: " : " " );
336385 OS << I << " \n " ;
337386 }
338387 }
0 commit comments