Skip to content

Commit c52f948

Browse files
committed
[LegacyDivergenceAnalysis] Add NewPM support
Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D142161
1 parent 778a582 commit c52f948

File tree

5 files changed

+120
-54
lines changed

5 files changed

+120
-54
lines changed

llvm/include/llvm/Analysis/LegacyDivergenceAnalysis.h

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
#define LLVM_ANALYSIS_LEGACYDIVERGENCEANALYSIS_H
1717

1818
#include "llvm/ADT/DenseSet.h"
19+
#include "llvm/Analysis/LoopInfo.h"
20+
#include "llvm/Analysis/PostDominators.h"
21+
#include "llvm/IR/PassManager.h"
1922
#include "llvm/Pass.h"
2023
#include <memory>
2124

@@ -28,19 +31,8 @@ class TargetTransformInfo;
2831
class Use;
2932
class Value;
3033

31-
class LegacyDivergenceAnalysis : public FunctionPass {
34+
class LegacyDivergenceAnalysisImpl {
3235
public:
33-
static char ID;
34-
35-
LegacyDivergenceAnalysis();
36-
37-
void getAnalysisUsage(AnalysisUsage &AU) const override;
38-
39-
bool runOnFunction(Function &F) override;
40-
41-
// Print all divergent branches in the function.
42-
void print(raw_ostream &OS, const Module *) const override;
43-
4436
// Returns true if V is divergent at its definition.
4537
bool isDivergent(const Value *V) const;
4638

@@ -57,11 +49,45 @@ class LegacyDivergenceAnalysis : public FunctionPass {
5749
// Keep the analysis results uptodate by removing an erased value.
5850
void removeValue(const Value *V) { DivergentValues.erase(V); }
5951

60-
private:
52+
// Print all divergent branches in the function.
53+
void print(raw_ostream &OS, const Module *) const;
54+
6155
// Whether analysis should be performed by GPUDivergenceAnalysis.
6256
bool shouldUseGPUDivergenceAnalysis(const Function &F,
63-
const TargetTransformInfo &TTI) const;
57+
const TargetTransformInfo &TTI,
58+
const LoopInfo &LI);
59+
60+
void run(Function &F, TargetTransformInfo &TTI, DominatorTree &DT,
61+
PostDominatorTree &PDT, const LoopInfo &LI);
62+
63+
protected:
64+
// (optional) handle to new DivergenceAnalysis
65+
std::unique_ptr<DivergenceInfo> gpuDA;
66+
67+
// Stores all divergent values.
68+
DenseSet<const Value *> DivergentValues;
69+
70+
// Stores divergent uses of possibly uniform values.
71+
DenseSet<const Use *> DivergentUses;
72+
};
73+
74+
class LegacyDivergenceAnalysis : public FunctionPass,
75+
public LegacyDivergenceAnalysisImpl {
76+
public:
77+
static char ID;
6478

79+
LegacyDivergenceAnalysis();
80+
void getAnalysisUsage(AnalysisUsage &AU) const override;
81+
bool runOnFunction(Function &F) override;
82+
};
83+
84+
class LegacyDivergenceAnalysisPass
85+
: public PassInfoMixin<LegacyDivergenceAnalysisPass>,
86+
public LegacyDivergenceAnalysisImpl {
87+
public:
88+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
89+
90+
private:
6591
// (optional) handle to new DivergenceAnalysis
6692
std::unique_ptr<DivergenceInfo> gpuDA;
6793

@@ -71,6 +97,7 @@ class LegacyDivergenceAnalysis : public FunctionPass {
7197
// Stores divergent uses of possibly uniform values.
7298
DenseSet<const Use *> DivergentUses;
7399
};
74-
} // End llvm namespace
100+
101+
} // end namespace llvm
75102

76103
#endif // LLVM_ANALYSIS_LEGACYDIVERGENCEANALYSIS_H

llvm/lib/Analysis/LegacyDivergenceAnalysis.cpp

Lines changed: 65 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -299,47 +299,25 @@ FunctionPass *llvm::createLegacyDivergenceAnalysisPass() {
299299
return new LegacyDivergenceAnalysis();
300300
}
301301

302-
void LegacyDivergenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
303-
AU.addRequiredTransitive<DominatorTreeWrapperPass>();
304-
AU.addRequiredTransitive<PostDominatorTreeWrapperPass>();
305-
AU.addRequiredTransitive<LoopInfoWrapperPass>();
306-
AU.setPreservesAll();
307-
}
308-
309-
bool LegacyDivergenceAnalysis::shouldUseGPUDivergenceAnalysis(
310-
const Function &F, const TargetTransformInfo &TTI) const {
302+
bool LegacyDivergenceAnalysisImpl::shouldUseGPUDivergenceAnalysis(
303+
const Function &F, const TargetTransformInfo &TTI, const LoopInfo &LI) {
311304
if (!(UseGPUDA || TTI.useGPUDivergenceAnalysis()))
312305
return false;
313306

314307
// GPUDivergenceAnalysis requires a reducible CFG.
315-
auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
316308
using RPOTraversal = ReversePostOrderTraversal<const Function *>;
317309
RPOTraversal FuncRPOT(&F);
318310
return !containsIrreducibleCFG<const BasicBlock *, const RPOTraversal,
319311
const LoopInfo>(FuncRPOT, LI);
320312
}
321313

322-
bool LegacyDivergenceAnalysis::runOnFunction(Function &F) {
323-
auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>();
324-
if (TTIWP == nullptr)
325-
return false;
326-
327-
TargetTransformInfo &TTI = TTIWP->getTTI(F);
328-
// Fast path: if the target does not have branch divergence, we do not mark
329-
// any branch as divergent.
330-
if (!TTI.hasBranchDivergence())
331-
return false;
332-
333-
DivergentValues.clear();
334-
DivergentUses.clear();
335-
gpuDA = nullptr;
336-
337-
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
338-
auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
339-
340-
if (shouldUseGPUDivergenceAnalysis(F, TTI)) {
314+
void LegacyDivergenceAnalysisImpl::run(Function &F,
315+
llvm::TargetTransformInfo &TTI,
316+
llvm::DominatorTree &DT,
317+
llvm::PostDominatorTree &PDT,
318+
const llvm::LoopInfo &LI) {
319+
if (shouldUseGPUDivergenceAnalysis(F, TTI, LI)) {
341320
// run the new GPU divergence analysis
342-
auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
343321
gpuDA = std::make_unique<DivergenceInfo>(F, DT, PDT, LI, TTI,
344322
/* KnownReducible = */ true);
345323

@@ -349,29 +327,24 @@ bool LegacyDivergenceAnalysis::runOnFunction(Function &F) {
349327
DP.populateWithSourcesOfDivergence();
350328
DP.propagate();
351329
}
352-
353-
LLVM_DEBUG(dbgs() << "\nAfter divergence analysis on " << F.getName()
354-
<< ":\n";
355-
print(dbgs(), F.getParent()));
356-
357-
return false;
358330
}
359331

360-
bool LegacyDivergenceAnalysis::isDivergent(const Value *V) const {
332+
bool LegacyDivergenceAnalysisImpl::isDivergent(const Value *V) const {
361333
if (gpuDA) {
362334
return gpuDA->isDivergent(*V);
363335
}
364336
return DivergentValues.count(V);
365337
}
366338

367-
bool LegacyDivergenceAnalysis::isDivergentUse(const Use *U) const {
339+
bool LegacyDivergenceAnalysisImpl::isDivergentUse(const Use *U) const {
368340
if (gpuDA) {
369341
return gpuDA->isDivergentUse(*U);
370342
}
371343
return DivergentValues.count(U->get()) || DivergentUses.count(U);
372344
}
373345

374-
void LegacyDivergenceAnalysis::print(raw_ostream &OS, const Module *) const {
346+
void LegacyDivergenceAnalysisImpl::print(raw_ostream &OS,
347+
const Module *) const {
375348
if ((!gpuDA || !gpuDA->hasDivergence()) && DivergentValues.empty())
376349
return;
377350

@@ -407,3 +380,56 @@ void LegacyDivergenceAnalysis::print(raw_ostream &OS, const Module *) const {
407380
}
408381
OS << "\n";
409382
}
383+
384+
void LegacyDivergenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
385+
AU.addRequiredTransitive<DominatorTreeWrapperPass>();
386+
AU.addRequiredTransitive<PostDominatorTreeWrapperPass>();
387+
AU.addRequiredTransitive<LoopInfoWrapperPass>();
388+
AU.setPreservesAll();
389+
}
390+
391+
bool LegacyDivergenceAnalysis::runOnFunction(Function &F) {
392+
auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>();
393+
if (TTIWP == nullptr)
394+
return false;
395+
396+
TargetTransformInfo &TTI = TTIWP->getTTI(F);
397+
// Fast path: if the target does not have branch divergence, we do not mark
398+
// any branch as divergent.
399+
if (!TTI.hasBranchDivergence())
400+
return false;
401+
402+
DivergentValues.clear();
403+
DivergentUses.clear();
404+
gpuDA = nullptr;
405+
406+
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
407+
auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
408+
auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
409+
LegacyDivergenceAnalysisImpl::run(F, TTI, DT, PDT, LI);
410+
LLVM_DEBUG(dbgs() << "\nAfter divergence analysis on " << F.getName()
411+
<< ":\n";
412+
LegacyDivergenceAnalysisImpl::print(dbgs(), F.getParent()));
413+
414+
return false;
415+
}
416+
417+
PreservedAnalyses
418+
LegacyDivergenceAnalysisPass::run(Function &F, FunctionAnalysisManager &AM) {
419+
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
420+
if (!TTI.hasBranchDivergence())
421+
return PreservedAnalyses::all();
422+
423+
DivergentValues.clear();
424+
DivergentUses.clear();
425+
gpuDA = nullptr;
426+
427+
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
428+
auto &PDT = AM.getResult<PostDominatorTreeAnalysis>(F);
429+
auto &LI = AM.getResult<LoopAnalysis>(F);
430+
LegacyDivergenceAnalysisImpl::run(F, TTI, DT, PDT, LI);
431+
LLVM_DEBUG(dbgs() << "\nAfter divergence analysis on " << F.getName()
432+
<< ":\n";
433+
LegacyDivergenceAnalysisImpl::print(dbgs(), F.getParent()));
434+
return PreservedAnalyses::all();
435+
}

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "llvm/Analysis/InstCount.h"
4747
#include "llvm/Analysis/LazyCallGraph.h"
4848
#include "llvm/Analysis/LazyValueInfo.h"
49+
#include "llvm/Analysis/LegacyDivergenceAnalysis.h"
4950
#include "llvm/Analysis/Lint.h"
5051
#include "llvm/Analysis/LoopAccessAnalysis.h"
5152
#include "llvm/Analysis/LoopCacheAnalysis.h"

llvm/lib/Passes/PassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ FUNCTION_PASS("libcalls-shrinkwrap", LibCallsShrinkWrapPass())
308308
FUNCTION_PASS("lint", LintPass())
309309
FUNCTION_PASS("inject-tli-mappings", InjectTLIMappings())
310310
FUNCTION_PASS("instnamer", InstructionNamerPass())
311+
FUNCTION_PASS("legacy-divergence-analysis", LegacyDivergenceAnalysisPass())
311312
FUNCTION_PASS("loweratomic", LowerAtomicPass())
312313
FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass())
313314
FUNCTION_PASS("lower-guard-intrinsic", LowerGuardIntrinsicPass())

llvm/test/CodeGen/AMDGPU/always-uniform.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1+
; RUN: opt -mtriple amdgcn-amdhsa -mcpu=gfx90a -passes=legacy-divergence-analysis < %s -S 2>&1 | FileCheck -check-prefix=OPT %s
12
; RUN: llc -mtriple amdgcn-amdhsa -mcpu=fiji -amdgpu-scalarize-global-loads -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
23

34
declare i32 @llvm.amdgcn.workitem.id.x()
45
declare i32 @llvm.amdgcn.readfirstlane(i32)
56

7+
; OPT-LABEL: define amdgpu_kernel void @readfirstlane_uniform(
8+
; OPT-NEXT: %tid = tail call i32 @llvm.amdgcn.workitem.id.x()
9+
; OPT-NEXT: %scalar = tail call i32 @llvm.amdgcn.readfirstlane(i32 %tid)
10+
; OPT-NEXT: %idx = zext i32 %scalar to i64
11+
; OPT-NEXT: %gep0 = getelementptr inbounds float, ptr addrspace(1) %0, i64 %idx
12+
; OPT-NEXT: %val = load float, ptr addrspace(1) %gep0, align 4
13+
; OPT-NEXT: %gep1 = getelementptr inbounds float, ptr addrspace(1) %1, i64 10
14+
; OPT-NEXT: store float %val, ptr addrspace(1) %gep1, align 4
15+
; OPT-NEXT: ret void
16+
;
617
; GCN-LABEL: readfirstlane_uniform
718
; GCN: s_load_dwordx4 s[[[IN_ADDR:[0-9]+]]:3], s[4:5], 0x0
819
; GCN: v_readfirstlane_b32 s[[SCALAR:[0-9]+]], v0

0 commit comments

Comments
 (0)