xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ADT/GenericUniformityInfo.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1 //===- GenericUniformityInfo.h ---------------------------*- 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 #ifndef LLVM_ADT_GENERICUNIFORMITYINFO_H
10 #define LLVM_ADT_GENERICUNIFORMITYINFO_H
11 
12 #include "llvm/ADT/GenericCycleInfo.h"
13 #include "llvm/Support/raw_ostream.h"
14 
15 namespace llvm {
16 
17 class TargetTransformInfo;
18 
19 template <typename ContextT> class GenericUniformityAnalysisImpl;
20 template <typename ImplT> struct GenericUniformityAnalysisImplDeleter {
21   // Ugly hack around the fact that recent (> 15.0) clang will run into an
22   // is_invocable() check in some GNU libc++'s unique_ptr implementation
23   // and reject this deleter if you just make it callable with an ImplT *,
24   // whether or not the type of ImplT is spelled out.
25   using pointer = ImplT *;
26   void operator()(ImplT *Impl);
27 };
28 
29 template <typename ContextT> class GenericUniformityInfo {
30 public:
31   using BlockT = typename ContextT::BlockT;
32   using FunctionT = typename ContextT::FunctionT;
33   using ValueRefT = typename ContextT::ValueRefT;
34   using ConstValueRefT = typename ContextT::ConstValueRefT;
35   using UseT = typename ContextT::UseT;
36   using InstructionT = typename ContextT::InstructionT;
37   using DominatorTreeT = typename ContextT::DominatorTreeT;
38   using ThisT = GenericUniformityInfo<ContextT>;
39 
40   using CycleInfoT = GenericCycleInfo<ContextT>;
41   using CycleT = typename CycleInfoT::CycleT;
42 
43   GenericUniformityInfo(const DominatorTreeT &DT, const CycleInfoT &CI,
44                         const TargetTransformInfo *TTI = nullptr);
45   GenericUniformityInfo() = default;
46   GenericUniformityInfo(GenericUniformityInfo &&) = default;
47   GenericUniformityInfo &operator=(GenericUniformityInfo &&) = default;
48 
49   void compute() {
50     DA->initialize();
51     DA->compute();
52   }
53 
54   /// Whether any divergence was detected.
55   bool hasDivergence() const;
56 
57   /// The GPU kernel this analysis result is for
58   const FunctionT &getFunction() const;
59 
60   /// Whether \p V is divergent at its definition.
61   bool isDivergent(ConstValueRefT V) const;
62 
63   /// Whether \p V is uniform/non-divergent.
64   bool isUniform(ConstValueRefT V) const { return !isDivergent(V); }
65 
66   // Similar queries for InstructionT. These accept a pointer argument so that
67   // in LLVM IR, they overload the equivalent queries for Value*. For example,
68   // if querying whether a BranchInst is divergent, it should not be treated as
69   // a Value in LLVM IR.
70   bool isUniform(const InstructionT *I) const { return !isDivergent(I); };
71   bool isDivergent(const InstructionT *I) const;
72 
73   /// \brief Whether \p U is divergent. Uses of a uniform value can be
74   /// divergent.
75   bool isDivergentUse(const UseT &U) const;
76 
77   bool hasDivergentTerminator(const BlockT &B);
78 
79   void print(raw_ostream &Out) const;
80 
81 private:
82   using ImplT = GenericUniformityAnalysisImpl<ContextT>;
83 
84   std::unique_ptr<ImplT, GenericUniformityAnalysisImplDeleter<ImplT>> DA;
85 
86   GenericUniformityInfo(const GenericUniformityInfo &) = delete;
87   GenericUniformityInfo &operator=(const GenericUniformityInfo &) = delete;
88 };
89 
90 } // namespace llvm
91 
92 #endif // LLVM_ADT_GENERICUNIFORMITYINFO_H
93