155 lines · c
1//===- DXILShaderFlags.h - DXIL Shader Flags helper objects ---------------===//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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file This file contains helper objects and APIs for working with DXIL10/// Shader Flags.11///12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H15#define LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H16 17#include "llvm/Analysis/DXILMetadataAnalysis.h"18#include "llvm/IR/Function.h"19#include "llvm/IR/PassManager.h"20#include "llvm/Pass.h"21#include "llvm/Support/Compiler.h"22#include "llvm/Support/Debug.h"23#include "llvm/Support/raw_ostream.h"24#include <cstdint>25 26namespace llvm {27class Module;28class GlobalVariable;29class DXILResourceTypeMap;30class DXILResourceMap;31 32namespace dxil {33 34struct ComputedShaderFlags {35#define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \36 bool FlagName : 1;37#define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) bool FlagName : 1;38#include "llvm/BinaryFormat/DXContainerConstants.def"39 40#define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \41 FlagName = false;42#define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) FlagName = false;43 ComputedShaderFlags() {44#include "llvm/BinaryFormat/DXContainerConstants.def"45 }46 47 constexpr uint64_t getMask(int Bit) const {48 return Bit != -1 ? 1ull << Bit : 0;49 }50 51 uint64_t getModuleFlags() const {52 uint64_t ModuleFlags = 0;53#define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) \54 ModuleFlags |= FlagName ? getMask(DxilModuleBit) : 0ull;55#include "llvm/BinaryFormat/DXContainerConstants.def"56 return ModuleFlags;57 }58 59 operator uint64_t() const {60 uint64_t FlagValue = getModuleFlags();61#define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \62 FlagValue |= FlagName ? getMask(DxilModuleBit) : 0ull;63#include "llvm/BinaryFormat/DXContainerConstants.def"64 return FlagValue;65 }66 67 uint64_t getFeatureFlags() const {68 uint64_t FeatureFlags = 0;69#define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \70 FeatureFlags |= FlagName ? getMask(FeatureBit) : 0ull;71#include "llvm/BinaryFormat/DXContainerConstants.def"72 return FeatureFlags;73 }74 75 void merge(const ComputedShaderFlags CSF) {76#define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \77 FlagName |= CSF.FlagName;78#define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) FlagName |= CSF.FlagName;79#include "llvm/BinaryFormat/DXContainerConstants.def"80 }81 82 void print(raw_ostream &OS = dbgs()) const;83 LLVM_DUMP_METHOD void dump() const { print(); }84};85 86struct ModuleShaderFlags {87 void initialize(Module &, DXILResourceTypeMap &DRTM,88 const DXILResourceMap &DRM, const ModuleMetadataInfo &MMDI);89 const ComputedShaderFlags &getFunctionFlags(const Function *) const;90 const ComputedShaderFlags &getCombinedFlags() const { return CombinedSFMask; }91 92private:93 // This boolean is inversely set by the LLVM module flag dx.resmayalias to94 // determine whether or not the ResMayNotAlias DXIL module flag can be set95 bool CanSetResMayNotAlias;96 97 /// Map of Function-Shader Flag Mask pairs representing properties of each of98 /// the functions in the module. Shader Flags of each function represent both99 /// module-level and function-level flags100 DenseMap<const Function *, ComputedShaderFlags> FunctionFlags;101 /// Combined Shader Flag Mask of all functions of the module102 ComputedShaderFlags CombinedSFMask{};103 ComputedShaderFlags gatherGlobalModuleFlags(const Module &M,104 const DXILResourceMap &,105 const ModuleMetadataInfo &);106 void updateFunctionFlags(ComputedShaderFlags &, const Instruction &,107 DXILResourceTypeMap &, const ModuleMetadataInfo &);108};109 110class ShaderFlagsAnalysis : public AnalysisInfoMixin<ShaderFlagsAnalysis> {111 friend AnalysisInfoMixin<ShaderFlagsAnalysis>;112 static AnalysisKey Key;113 114public:115 ShaderFlagsAnalysis() = default;116 117 using Result = ModuleShaderFlags;118 119 ModuleShaderFlags run(Module &M, ModuleAnalysisManager &AM);120};121 122/// Printer pass for ShaderFlagsAnalysis results.123class ShaderFlagsAnalysisPrinter124 : public PassInfoMixin<ShaderFlagsAnalysisPrinter> {125 raw_ostream &OS;126 127public:128 explicit ShaderFlagsAnalysisPrinter(raw_ostream &OS) : OS(OS) {}129 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);130};131 132/// Wrapper pass for the legacy pass manager.133///134/// This is required because the passes that will depend on this are codegen135/// passes which run through the legacy pass manager.136class ShaderFlagsAnalysisWrapper : public ModulePass {137 ModuleShaderFlags MSFI;138 139public:140 static char ID;141 142 ShaderFlagsAnalysisWrapper() : ModulePass(ID) {}143 144 const ModuleShaderFlags &getShaderFlags() { return MSFI; }145 146 bool runOnModule(Module &M) override;147 148 void getAnalysisUsage(AnalysisUsage &AU) const override;149};150 151} // namespace dxil152} // namespace llvm153 154#endif // LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H155