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