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/IR/PassManager.h" 18 #include "llvm/Pass.h" 19 #include "llvm/Support/Compiler.h" 20 #include "llvm/Support/Debug.h" 21 #include "llvm/Support/raw_ostream.h" 22 #include <cstdint> 23 24 namespace llvm { 25 class Module; 26 class GlobalVariable; 27 28 namespace dxil { 29 30 struct ComputedShaderFlags { 31 #define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \ 32 bool FlagName : 1; 33 #define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) bool FlagName : 1; 34 #include "llvm/BinaryFormat/DXContainerConstants.def" 35 36 #define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \ 37 FlagName = false; 38 #define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) FlagName = false; 39 ComputedShaderFlags() { 40 #include "llvm/BinaryFormat/DXContainerConstants.def" 41 } 42 43 constexpr uint64_t getMask(int Bit) const { 44 return Bit != -1 ? 1ull << Bit : 0; 45 } 46 operator uint64_t() const { 47 uint64_t FlagValue = 0; 48 #define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \ 49 FlagValue |= FlagName ? getMask(DxilModuleBit) : 0ull; 50 #define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) \ 51 FlagValue |= FlagName ? getMask(DxilModuleBit) : 0ull; 52 #include "llvm/BinaryFormat/DXContainerConstants.def" 53 return FlagValue; 54 } 55 uint64_t getFeatureFlags() const { 56 uint64_t FeatureFlags = 0; 57 #define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleBit, FlagName, Str) \ 58 FeatureFlags |= FlagName ? getMask(FeatureBit) : 0ull; 59 #include "llvm/BinaryFormat/DXContainerConstants.def" 60 return FeatureFlags; 61 } 62 63 static ComputedShaderFlags computeFlags(Module &M); 64 void print(raw_ostream &OS = dbgs()) const; 65 LLVM_DUMP_METHOD void dump() const { print(); } 66 }; 67 68 class ShaderFlagsAnalysis : public AnalysisInfoMixin<ShaderFlagsAnalysis> { 69 friend AnalysisInfoMixin<ShaderFlagsAnalysis>; 70 static AnalysisKey Key; 71 72 public: 73 ShaderFlagsAnalysis() = default; 74 75 using Result = ComputedShaderFlags; 76 77 ComputedShaderFlags run(Module &M, ModuleAnalysisManager &AM); 78 }; 79 80 /// Printer pass for ShaderFlagsAnalysis results. 81 class ShaderFlagsAnalysisPrinter 82 : public PassInfoMixin<ShaderFlagsAnalysisPrinter> { 83 raw_ostream &OS; 84 85 public: 86 explicit ShaderFlagsAnalysisPrinter(raw_ostream &OS) : OS(OS) {} 87 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); 88 }; 89 90 /// Wrapper pass for the legacy pass manager. 91 /// 92 /// This is required because the passes that will depend on this are codegen 93 /// passes which run through the legacy pass manager. 94 class ShaderFlagsAnalysisWrapper : public ModulePass { 95 ComputedShaderFlags Flags; 96 97 public: 98 static char ID; 99 100 ShaderFlagsAnalysisWrapper() : ModulePass(ID) {} 101 102 const ComputedShaderFlags &getShaderFlags() { return Flags; } 103 104 bool runOnModule(Module &M) override { 105 Flags = ComputedShaderFlags::computeFlags(M); 106 return false; 107 } 108 109 void getAnalysisUsage(AnalysisUsage &AU) const override { 110 AU.setPreservesAll(); 111 } 112 }; 113 114 } // namespace dxil 115 } // namespace llvm 116 117 #endif // LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H 118