1139823Simp//===- llvm/Analysis/LegacyDivergenceAnalysis.h - KernelDivergence Analysis -*- C++ -*-===// 234649Swollman// 334649Swollman// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 434649Swollman// See https://llvm.org/LICENSE.txt for license information. 534649Swollman// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 634649Swollman// 734649Swollman//===----------------------------------------------------------------------===// 834649Swollman// 934649Swollman// The kernel divergence analysis is an LLVM pass which can be used to find out 1034649Swollman// if a branch instruction in a GPU program (kernel) is divergent or not. It can help 1134649Swollman// branch optimizations such as jump threading and loop unswitching to make 1234649Swollman// better decisions. 1334649Swollman// 1434649Swollman//===----------------------------------------------------------------------===// 1534649Swollman#ifndef LLVM_ANALYSIS_LEGACYDIVERGENCEANALYSIS_H 1634649Swollman#define LLVM_ANALYSIS_LEGACYDIVERGENCEANALYSIS_H 1734649Swollman 1834649Swollman#include "llvm/ADT/DenseSet.h" 1934649Swollman#include "llvm/Pass.h" 2034649Swollman#include <memory> 2134649Swollman 2234649Swollmannamespace llvm { 2334649Swollmanclass DivergenceInfo; 2434649Swollmanclass Function; 2534649Swollmanclass Module; 2634649Swollmanclass raw_ostream; 2734649Swollmanclass TargetTransformInfo; 2834649Swollmanclass Use; 2950477Speterclass Value; 3034649Swollman 3134649Swollmanclass LegacyDivergenceAnalysis : public FunctionPass { 3234649Swollmanpublic: 3334649Swollman static char ID; 3434649Swollman 3534649Swollman LegacyDivergenceAnalysis(); 3634649Swollman 3734649Swollman void getAnalysisUsage(AnalysisUsage &AU) const override; 3834649Swollman 3934649Swollman bool runOnFunction(Function &F) override; 4034649Swollman 4134649Swollman // Print all divergent branches in the function. 4234649Swollman void print(raw_ostream &OS, const Module *) const override; 43167126Sbms 44167126Sbms // Returns true if V is divergent at its definition. 45167126Sbms bool isDivergent(const Value *V) const; 46167126Sbms 47167126Sbms // Returns true if U is divergent. Uses of a uniform value can be divergent. 48167126Sbms bool isDivergentUse(const Use *U) const; 49167126Sbms 5034649Swollman // Returns true if V is uniform/non-divergent. 51167126Sbms bool isUniform(const Value *V) const { return !isDivergent(V); } 52167126Sbms 53167126Sbms // Returns true if U is uniform/non-divergent. Uses of a uniform value can be 54167126Sbms // divergent. 55167126Sbms bool isUniformUse(const Use *U) const { return !isDivergentUse(U); } 56167126Sbms 57167126Sbms // Keep the analysis results uptodate by removing an erased value. 58167126Sbms void removeValue(const Value *V) { DivergentValues.erase(V); } 59167126Sbms 60167126Sbmsprivate: 61167126Sbms // Whether analysis should be performed by GPUDivergenceAnalysis. 62167126Sbms bool shouldUseGPUDivergenceAnalysis(const Function &F, 63167126Sbms const TargetTransformInfo &TTI) const; 64167126Sbms 65167126Sbms // (optional) handle to new DivergenceAnalysis 66167126Sbms std::unique_ptr<DivergenceInfo> gpuDA; 67167126Sbms 68167126Sbms // Stores all divergent values. 69167126Sbms DenseSet<const Value *> DivergentValues; 70167126Sbms 71167126Sbms // Stores divergent uses of possibly uniform values. 72167126Sbms DenseSet<const Use *> DivergentUses; 73167126Sbms}; 74167126Sbms} // End llvm namespace 75167126Sbms 76167126Sbms#endif // LLVM_ANALYSIS_LEGACYDIVERGENCEANALYSIS_H 77167126Sbms