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