xref: /freebsd/contrib/llvm-project/llvm/lib/Target/DirectX/DXILShaderFlags.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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