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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file This file contains helper objects and APIs for working with DXIL 10 /// Shader Flags. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H 15 #define LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H 16 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 #include <memory> 26 27 namespace llvm { 28 class Module; 29 class GlobalVariable; 30 class DXILResourceTypeMap; 31 class DXILResourceMap; 32 33 namespace dxil { 34 35 struct ComputedShaderFlags { 36 #define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \ 37 bool FlagName : 1; 38 #define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) bool FlagName : 1; 39 #include "llvm/BinaryFormat/DXContainerConstants.def" 40 41 #define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \ 42 FlagName = false; 43 #define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) FlagName = false; ComputedShaderFlagsComputedShaderFlags44 ComputedShaderFlags() { 45 #include "llvm/BinaryFormat/DXContainerConstants.def" 46 } 47 getMaskComputedShaderFlags48 constexpr uint64_t getMask(int Bit) const { 49 return Bit != -1 ? 1ull << Bit : 0; 50 } 51 getModuleFlagsComputedShaderFlags52 uint64_t getModuleFlags() const { 53 uint64_t ModuleFlags = 0; 54 #define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) \ 55 ModuleFlags |= FlagName ? getMask(DxilModuleBit) : 0ull; 56 #include "llvm/BinaryFormat/DXContainerConstants.def" 57 return ModuleFlags; 58 } 59 uint64_tComputedShaderFlags60 operator uint64_t() const { 61 uint64_t FlagValue = getModuleFlags(); 62 #define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \ 63 FlagValue |= FlagName ? getMask(DxilModuleBit) : 0ull; 64 #include "llvm/BinaryFormat/DXContainerConstants.def" 65 return FlagValue; 66 } 67 getFeatureFlagsComputedShaderFlags68 uint64_t getFeatureFlags() const { 69 uint64_t FeatureFlags = 0; 70 #define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \ 71 FeatureFlags |= FlagName ? getMask(FeatureBit) : 0ull; 72 #include "llvm/BinaryFormat/DXContainerConstants.def" 73 return FeatureFlags; 74 } 75 mergeComputedShaderFlags76 void merge(const ComputedShaderFlags CSF) { 77 #define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \ 78 FlagName |= CSF.FlagName; 79 #define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) FlagName |= CSF.FlagName; 80 #include "llvm/BinaryFormat/DXContainerConstants.def" 81 } 82 83 void print(raw_ostream &OS = dbgs()) const; dumpComputedShaderFlags84 LLVM_DUMP_METHOD void dump() const { print(); } 85 }; 86 87 struct ModuleShaderFlags { 88 void initialize(Module &, DXILResourceTypeMap &DRTM, 89 const DXILResourceMap &DRM, const ModuleMetadataInfo &MMDI); 90 const ComputedShaderFlags &getFunctionFlags(const Function *) const; getCombinedFlagsModuleShaderFlags91 const ComputedShaderFlags &getCombinedFlags() const { return CombinedSFMask; } 92 93 private: 94 // This boolean is inversely set by the LLVM module flag dx.resmayalias to 95 // determine whether or not the ResMayNotAlias DXIL module flag can be set 96 bool CanSetResMayNotAlias; 97 98 /// Map of Function-Shader Flag Mask pairs representing properties of each of 99 /// the functions in the module. Shader Flags of each function represent both 100 /// module-level and function-level flags 101 DenseMap<const Function *, ComputedShaderFlags> FunctionFlags; 102 /// Combined Shader Flag Mask of all functions of the module 103 ComputedShaderFlags CombinedSFMask{}; 104 ComputedShaderFlags gatherGlobalModuleFlags(const Module &M, 105 const DXILResourceMap &, 106 const ModuleMetadataInfo &); 107 void updateFunctionFlags(ComputedShaderFlags &, const Instruction &, 108 DXILResourceTypeMap &, const ModuleMetadataInfo &); 109 }; 110 111 class ShaderFlagsAnalysis : public AnalysisInfoMixin<ShaderFlagsAnalysis> { 112 friend AnalysisInfoMixin<ShaderFlagsAnalysis>; 113 static AnalysisKey Key; 114 115 public: 116 ShaderFlagsAnalysis() = default; 117 118 using Result = ModuleShaderFlags; 119 120 ModuleShaderFlags run(Module &M, ModuleAnalysisManager &AM); 121 }; 122 123 /// Printer pass for ShaderFlagsAnalysis results. 124 class ShaderFlagsAnalysisPrinter 125 : public PassInfoMixin<ShaderFlagsAnalysisPrinter> { 126 raw_ostream &OS; 127 128 public: ShaderFlagsAnalysisPrinter(raw_ostream & OS)129 explicit ShaderFlagsAnalysisPrinter(raw_ostream &OS) : OS(OS) {} 130 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); 131 }; 132 133 /// Wrapper pass for the legacy pass manager. 134 /// 135 /// This is required because the passes that will depend on this are codegen 136 /// passes which run through the legacy pass manager. 137 class ShaderFlagsAnalysisWrapper : public ModulePass { 138 ModuleShaderFlags MSFI; 139 140 public: 141 static char ID; 142 ShaderFlagsAnalysisWrapper()143 ShaderFlagsAnalysisWrapper() : ModulePass(ID) {} 144 getShaderFlags()145 const ModuleShaderFlags &getShaderFlags() { return MSFI; } 146 147 bool runOnModule(Module &M) override; 148 149 void getAnalysisUsage(AnalysisUsage &AU) const override; 150 }; 151 152 } // namespace dxil 153 } // namespace llvm 154 155 #endif // LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H 156