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