Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:05

0001 //===- GenericUniformityInfo.h ---------------------------*- C++ -*--------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_ADT_GENERICUNIFORMITYINFO_H
0010 #define LLVM_ADT_GENERICUNIFORMITYINFO_H
0011 
0012 #include "llvm/ADT/GenericCycleInfo.h"
0013 #include "llvm/Support/raw_ostream.h"
0014 
0015 namespace llvm {
0016 
0017 class TargetTransformInfo;
0018 
0019 template <typename ContextT> class GenericUniformityAnalysisImpl;
0020 template <typename ImplT> struct GenericUniformityAnalysisImplDeleter {
0021   // Ugly hack around the fact that recent (> 15.0) clang will run into an
0022   // is_invocable() check in some GNU libc++'s unique_ptr implementation
0023   // and reject this deleter if you just make it callable with an ImplT *,
0024   // whether or not the type of ImplT is spelled out.
0025   using pointer = ImplT *;
0026   void operator()(ImplT *Impl);
0027 };
0028 
0029 template <typename ContextT> class GenericUniformityInfo {
0030 public:
0031   using BlockT = typename ContextT::BlockT;
0032   using FunctionT = typename ContextT::FunctionT;
0033   using ValueRefT = typename ContextT::ValueRefT;
0034   using ConstValueRefT = typename ContextT::ConstValueRefT;
0035   using UseT = typename ContextT::UseT;
0036   using InstructionT = typename ContextT::InstructionT;
0037   using DominatorTreeT = typename ContextT::DominatorTreeT;
0038   using ThisT = GenericUniformityInfo<ContextT>;
0039 
0040   using CycleInfoT = GenericCycleInfo<ContextT>;
0041   using CycleT = typename CycleInfoT::CycleT;
0042 
0043   GenericUniformityInfo(const DominatorTreeT &DT, const CycleInfoT &CI,
0044                         const TargetTransformInfo *TTI = nullptr);
0045   GenericUniformityInfo() = default;
0046   GenericUniformityInfo(GenericUniformityInfo &&) = default;
0047   GenericUniformityInfo &operator=(GenericUniformityInfo &&) = default;
0048 
0049   void compute() {
0050     DA->initialize();
0051     DA->compute();
0052   }
0053 
0054   /// Whether any divergence was detected.
0055   bool hasDivergence() const;
0056 
0057   /// The GPU kernel this analysis result is for
0058   const FunctionT &getFunction() const;
0059 
0060   /// Whether \p V is divergent at its definition.
0061   bool isDivergent(ConstValueRefT V) const;
0062 
0063   /// Whether \p V is uniform/non-divergent.
0064   bool isUniform(ConstValueRefT V) const { return !isDivergent(V); }
0065 
0066   // Similar queries for InstructionT. These accept a pointer argument so that
0067   // in LLVM IR, they overload the equivalent queries for Value*. For example,
0068   // if querying whether a BranchInst is divergent, it should not be treated as
0069   // a Value in LLVM IR.
0070   bool isUniform(const InstructionT *I) const { return !isDivergent(I); };
0071   bool isDivergent(const InstructionT *I) const;
0072 
0073   /// \brief Whether \p U is divergent. Uses of a uniform value can be
0074   /// divergent.
0075   bool isDivergentUse(const UseT &U) const;
0076 
0077   bool hasDivergentTerminator(const BlockT &B);
0078 
0079   void print(raw_ostream &Out) const;
0080 
0081 private:
0082   using ImplT = GenericUniformityAnalysisImpl<ContextT>;
0083 
0084   std::unique_ptr<ImplT, GenericUniformityAnalysisImplDeleter<ImplT>> DA;
0085 
0086   GenericUniformityInfo(const GenericUniformityInfo &) = delete;
0087   GenericUniformityInfo &operator=(const GenericUniformityInfo &) = delete;
0088 };
0089 
0090 } // namespace llvm
0091 
0092 #endif // LLVM_ADT_GENERICUNIFORMITYINFO_H