clang 20.0.0 (based on r547379) from build 12806354. Bug: http://b/379133546 Test: N/A Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
93 lines
3.3 KiB
C++
93 lines
3.3 KiB
C++
//===- GenericUniformityInfo.h ---------------------------*- C++ -*--------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_ADT_GENERICUNIFORMITYINFO_H
|
|
#define LLVM_ADT_GENERICUNIFORMITYINFO_H
|
|
|
|
#include "llvm/ADT/GenericCycleInfo.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
namespace llvm {
|
|
|
|
class TargetTransformInfo;
|
|
|
|
template <typename ContextT> class GenericUniformityAnalysisImpl;
|
|
template <typename ImplT> struct GenericUniformityAnalysisImplDeleter {
|
|
// Ugly hack around the fact that recent (> 15.0) clang will run into an
|
|
// is_invocable() check in some GNU libc++'s unique_ptr implementation
|
|
// and reject this deleter if you just make it callable with an ImplT *,
|
|
// whether or not the type of ImplT is spelled out.
|
|
using pointer = ImplT *;
|
|
void operator()(ImplT *Impl);
|
|
};
|
|
|
|
template <typename ContextT> class GenericUniformityInfo {
|
|
public:
|
|
using BlockT = typename ContextT::BlockT;
|
|
using FunctionT = typename ContextT::FunctionT;
|
|
using ValueRefT = typename ContextT::ValueRefT;
|
|
using ConstValueRefT = typename ContextT::ConstValueRefT;
|
|
using UseT = typename ContextT::UseT;
|
|
using InstructionT = typename ContextT::InstructionT;
|
|
using DominatorTreeT = typename ContextT::DominatorTreeT;
|
|
using ThisT = GenericUniformityInfo<ContextT>;
|
|
|
|
using CycleInfoT = GenericCycleInfo<ContextT>;
|
|
using CycleT = typename CycleInfoT::CycleT;
|
|
|
|
GenericUniformityInfo(const DominatorTreeT &DT, const CycleInfoT &CI,
|
|
const TargetTransformInfo *TTI = nullptr);
|
|
GenericUniformityInfo() = default;
|
|
GenericUniformityInfo(GenericUniformityInfo &&) = default;
|
|
GenericUniformityInfo &operator=(GenericUniformityInfo &&) = default;
|
|
|
|
void compute() {
|
|
DA->initialize();
|
|
DA->compute();
|
|
}
|
|
|
|
/// Whether any divergence was detected.
|
|
bool hasDivergence() const;
|
|
|
|
/// The GPU kernel this analysis result is for
|
|
const FunctionT &getFunction() const;
|
|
|
|
/// Whether \p V is divergent at its definition.
|
|
bool isDivergent(ConstValueRefT V) const;
|
|
|
|
/// Whether \p V is uniform/non-divergent.
|
|
bool isUniform(ConstValueRefT V) const { return !isDivergent(V); }
|
|
|
|
// Similar queries for InstructionT. These accept a pointer argument so that
|
|
// in LLVM IR, they overload the equivalent queries for Value*. For example,
|
|
// if querying whether a BranchInst is divergent, it should not be treated as
|
|
// a Value in LLVM IR.
|
|
bool isUniform(const InstructionT *I) const { return !isDivergent(I); };
|
|
bool isDivergent(const InstructionT *I) const;
|
|
|
|
/// \brief Whether \p U is divergent. Uses of a uniform value can be
|
|
/// divergent.
|
|
bool isDivergentUse(const UseT &U) const;
|
|
|
|
bool hasDivergentTerminator(const BlockT &B);
|
|
|
|
void print(raw_ostream &Out) const;
|
|
|
|
private:
|
|
using ImplT = GenericUniformityAnalysisImpl<ContextT>;
|
|
|
|
std::unique_ptr<ImplT, GenericUniformityAnalysisImplDeleter<ImplT>> DA;
|
|
|
|
GenericUniformityInfo(const GenericUniformityInfo &) = delete;
|
|
GenericUniformityInfo &operator=(const GenericUniformityInfo &) = delete;
|
|
};
|
|
|
|
} // namespace llvm
|
|
|
|
#endif // LLVM_ADT_GENERICUNIFORMITYINFO_H
|