1//===- llvm/Analysis/LegacyDivergenceAnalysis.h - KernelDivergence Analysis -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// The kernel divergence analysis is an LLVM pass which can be used to find out
10// if a branch instruction in a GPU program (kernel) is divergent or not. It can help
11// branch optimizations such as jump threading and loop unswitching to make
12// better decisions.
13//
14//===----------------------------------------------------------------------===//
15#ifndef LLVM_ANALYSIS_LEGACYDIVERGENCEANALYSIS_H
16#define LLVM_ANALYSIS_LEGACYDIVERGENCEANALYSIS_H
17
18#include "llvm/ADT/DenseSet.h"
19#include "llvm/Pass.h"
20#include <memory>
21
22namespace llvm {
23class DivergenceInfo;
24class Function;
25class Module;
26class raw_ostream;
27class TargetTransformInfo;
28class Use;
29class Value;
30
31class LegacyDivergenceAnalysis : public FunctionPass {
32public:
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
44  // Returns true if V is divergent at its definition.
45  bool isDivergent(const Value *V) const;
46
47  // Returns true if U is divergent. Uses of a uniform value can be divergent.
48  bool isDivergentUse(const Use *U) const;
49
50  // Returns true if V is uniform/non-divergent.
51  bool isUniform(const Value *V) const { return !isDivergent(V); }
52
53  // Returns true if U is uniform/non-divergent. Uses of a uniform value can be
54  // divergent.
55  bool isUniformUse(const Use *U) const { return !isDivergentUse(U); }
56
57  // Keep the analysis results uptodate by removing an erased value.
58  void removeValue(const Value *V) { DivergentValues.erase(V); }
59
60private:
61  // Whether analysis should be performed by GPUDivergenceAnalysis.
62  bool shouldUseGPUDivergenceAnalysis(const Function &F,
63                                      const TargetTransformInfo &TTI) const;
64
65  // (optional) handle to new DivergenceAnalysis
66  std::unique_ptr<DivergenceInfo> gpuDA;
67
68  // Stores all divergent values.
69  DenseSet<const Value *> DivergentValues;
70
71  // Stores divergent uses of possibly uniform values.
72  DenseSet<const Use *> DivergentUses;
73};
74} // End llvm namespace
75
76#endif // LLVM_ANALYSIS_LEGACYDIVERGENCEANALYSIS_H
77