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(FunctionT &F, const DominatorTreeT &DT, 44 const CycleInfoT &CI, 45 const TargetTransformInfo *TTI = nullptr); 46 GenericUniformityInfo() = default; 47 GenericUniformityInfo(GenericUniformityInfo &&) = default; 48 GenericUniformityInfo &operator=(GenericUniformityInfo &&) = default; 49 50 void compute() { 51 DA->initialize(); 52 DA->compute(); 53 } 54 55 /// Whether any divergence was detected. 56 bool hasDivergence() const; 57 58 /// The GPU kernel this analysis result is for 59 const FunctionT &getFunction() const { return *F; } 60 61 /// Whether \p V is divergent at its definition. 62 bool isDivergent(ConstValueRefT V) const; 63 64 /// Whether \p V is uniform/non-divergent. 65 bool isUniform(ConstValueRefT V) const { return !isDivergent(V); } 66 67 // Similar queries for InstructionT. These accept a pointer argument so that 68 // in LLVM IR, they overload the equivalent queries for Value*. For example, 69 // if querying whether a BranchInst is divergent, it should not be treated as 70 // a Value in LLVM IR. 71 bool isUniform(const InstructionT *I) const { return !isDivergent(I); }; 72 bool isDivergent(const InstructionT *I) const; 73 74 /// \brief Whether \p U is divergent. Uses of a uniform value can be 75 /// divergent. 76 bool isDivergentUse(const UseT &U) const; 77 78 bool hasDivergentTerminator(const BlockT &B); 79 80 void print(raw_ostream &Out) const; 81 82 private: 83 using ImplT = GenericUniformityAnalysisImpl<ContextT>; 84 85 FunctionT *F; 86 std::unique_ptr<ImplT, GenericUniformityAnalysisImplDeleter<ImplT>> DA; 87 88 GenericUniformityInfo(const GenericUniformityInfo &) = delete; 89 GenericUniformityInfo &operator=(const GenericUniformityInfo &) = delete; 90 }; 91 92 } // namespace llvm 93 94 #endif // LLVM_ADT_GENERICUNIFORMITYINFO_H 95