1
- // ===- LegacyDivergenceAnalysis.cpp --------- Legacy Divergence Analysis Implementation -==//
1
+ // ===- LegacyDivergenceAnalysis.cpp --------- Legacy Divergence Analysis
2
+ // Implementation -==//
2
3
//
3
4
// The LLVM Compiler Infrastructure
4
5
//
64
65
//
65
66
// ===----------------------------------------------------------------------===//
66
67
68
+ #include " llvm/ADT/PostOrderIterator.h"
69
+ #include " llvm/Analysis/CFG.h"
70
+ #include " llvm/Analysis/DivergenceAnalysis.h"
67
71
#include " llvm/Analysis/LegacyDivergenceAnalysis.h"
68
72
#include " llvm/Analysis/Passes.h"
69
73
#include " llvm/Analysis/PostDominators.h"
@@ -79,6 +83,12 @@ using namespace llvm;
79
83
80
84
#define DEBUG_TYPE " divergence"
81
85
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
+
82
92
namespace {
83
93
84
94
class DivergencePropagator {
@@ -262,16 +272,17 @@ void DivergencePropagator::propagate() {
262
272
}
263
273
}
264
274
265
- } // / end namespace anonymous
275
+ } // namespace
266
276
267
277
// Register this pass.
268
278
char 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 )
271
281
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
272
282
INITIALIZE_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 )
275
286
276
287
FunctionPass *llvm::createLegacyDivergenceAnalysisPass() {
277
288
return new LegacyDivergenceAnalysis ();
@@ -280,9 +291,24 @@ FunctionPass *llvm::createLegacyDivergenceAnalysisPass() {
280
291
void LegacyDivergenceAnalysis::getAnalysisUsage (AnalysisUsage &AU) const {
281
292
AU.addRequired <DominatorTreeWrapperPass>();
282
293
AU.addRequired <PostDominatorTreeWrapperPass>();
294
+ if (UseGPUDA)
295
+ AU.addRequired <LoopInfoWrapperPass>();
283
296
AU.setPreservesAll ();
284
297
}
285
298
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
+
286
312
bool LegacyDivergenceAnalysis::runOnFunction (Function &F) {
287
313
auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>();
288
314
if (TTIWP == nullptr )
@@ -295,44 +321,67 @@ bool LegacyDivergenceAnalysis::runOnFunction(Function &F) {
295
321
return false ;
296
322
297
323
DivergentValues.clear ();
324
+ gpuDA = nullptr ;
325
+
326
+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
298
327
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
+
308
345
return false ;
309
346
}
310
347
348
+ bool LegacyDivergenceAnalysis::isDivergent (const Value *V) const {
349
+ if (gpuDA) {
350
+ return gpuDA->isDivergent (*V);
351
+ }
352
+ return DivergentValues.count (V);
353
+ }
354
+
311
355
void LegacyDivergenceAnalysis::print (raw_ostream &OS, const Module *) const {
312
- if (DivergentValues.empty ())
356
+ if ((!gpuDA || !gpuDA-> hasDivergence ()) && DivergentValues.empty ())
313
357
return ;
314
- const Value *FirstDivergentValue = *DivergentValues. begin ();
358
+
315
359
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 ();
323
372
}
324
373
325
374
// Dumps all divergent values in F, arguments and then instructions.
326
375
for (auto &Arg : F->args ()) {
327
- OS << (DivergentValues. count (&Arg) ? " DIVERGENT: " : " " );
376
+ OS << (isDivergent (&Arg) ? " DIVERGENT: " : " " );
328
377
OS << Arg << " \n " ;
329
378
}
330
379
// Iterate instructions using instructions() to ensure a deterministic order.
331
380
for (auto BI = F->begin (), BE = F->end (); BI != BE; ++BI) {
332
381
auto &BB = *BI;
333
382
OS << " \n " << BB.getName () << " :\n " ;
334
383
for (auto &I : BB.instructionsWithoutDebug ()) {
335
- OS << (DivergentValues. count (&I) ? " DIVERGENT: " : " " );
384
+ OS << (isDivergent (&I) ? " DIVERGENT: " : " " );
336
385
OS << I << " \n " ;
337
386
}
338
387
}
0 commit comments