LLVM 20.0.0git
DXILShaderFlags.cpp
Go to the documentation of this file.
1//===- DXILShaderFlags.cpp - 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#include "DXILShaderFlags.h"
15#include "DirectX.h"
16#include "llvm/ADT/STLExtras.h"
18#include "llvm/IR/Instruction.h"
20#include "llvm/IR/Intrinsics.h"
21#include "llvm/IR/IntrinsicsDirectX.h"
22#include "llvm/IR/Module.h"
26
27using namespace llvm;
28using namespace llvm::dxil;
29
31 DXILResourceTypeMap &DRTM) {
32 if (!CSF.Doubles)
33 CSF.Doubles = I.getType()->isDoubleTy();
34
35 if (!CSF.Doubles) {
36 for (Value *Op : I.operands())
37 CSF.Doubles |= Op->getType()->isDoubleTy();
38 }
39 if (CSF.Doubles) {
40 switch (I.getOpcode()) {
41 case Instruction::FDiv:
42 case Instruction::UIToFP:
43 case Instruction::SIToFP:
44 case Instruction::FPToUI:
45 case Instruction::FPToSI:
46 // TODO: To be set if I is a call to DXIL intrinsic DXIL::Opcode::Fma
47 // https://github.com/llvm/llvm-project/issues/114554
48 CSF.DX11_1_DoubleExtensions = true;
49 break;
50 }
51 }
52
53 if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
54 switch (II->getIntrinsicID()) {
55 default:
56 break;
57 case Intrinsic::dx_resource_load_typedbuffer: {
59 DRTM[cast<TargetExtType>(II->getArgOperand(0)->getType())];
60 if (RTI.isTyped())
61 CSF.TypedUAVLoadAdditionalFormats |= RTI.getTyped().ElementCount > 1;
62 }
63 }
64 }
65}
66
68
69 // Collect shader flags for each of the functions
70 for (const auto &F : M.getFunctionList()) {
71 if (F.isDeclaration()) {
72 assert(!F.getName().starts_with("dx.op.") &&
73 "DXIL Shader Flag analysis should not be run post-lowering.");
74 continue;
75 }
77 for (const auto &BB : F)
78 for (const auto &I : BB)
79 updateFunctionFlags(CSF, I, DRTM);
80 // Insert shader flag mask for function F
81 FunctionFlags.push_back({&F, CSF});
82 // Update combined shader flags mask
83 CombinedSFMask.merge(CSF);
84 }
85 llvm::sort(FunctionFlags);
86}
87
89 uint64_t FlagVal = (uint64_t) * this;
90 OS << formatv("; Shader Flags Value: {0:x8}\n;\n", FlagVal);
91 if (FlagVal == 0)
92 return;
93 OS << "; Note: shader requires additional functionality:\n";
94#define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleNum, FlagName, Str) \
95 if (FlagName) \
96 (OS << ";").indent(7) << Str << "\n";
97#include "llvm/BinaryFormat/DXContainerConstants.def"
98 OS << "; Note: extra DXIL module flags:\n";
99#define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) \
100 if (FlagName) \
101 (OS << ";").indent(7) << Str << "\n";
102#include "llvm/BinaryFormat/DXContainerConstants.def"
103 OS << ";\n";
104}
105
106/// Return the shader flags mask of the specified function Func.
109 const auto Iter = llvm::lower_bound(
110 FunctionFlags, Func,
111 [](const std::pair<const Function *, ComputedShaderFlags> FSM,
112 const Function *FindFunc) { return (FSM.first < FindFunc); });
113 assert((Iter != FunctionFlags.end() && Iter->first == Func) &&
114 "No Shader Flags Mask exists for function");
115 return Iter->second;
116}
117
118//===----------------------------------------------------------------------===//
119// ShaderFlagsAnalysis and ShaderFlagsAnalysisPrinterPass
120
121// Provide an explicit template instantiation for the static ID.
122AnalysisKey ShaderFlagsAnalysis::Key;
123
127
129 MSFI.initialize(M, DRTM);
130
131 return MSFI;
132}
133
136 const ModuleShaderFlags &FlagsInfo = AM.getResult<ShaderFlagsAnalysis>(M);
137 // Print description of combined shader flags for all module functions
138 OS << "; Combined Shader Flags for Module\n";
139 FlagsInfo.getCombinedFlags().print(OS);
140 // Print shader flags mask for each of the module functions
141 OS << "; Shader Flags for Module Functions\n";
142 for (const auto &F : M.getFunctionList()) {
143 if (F.isDeclaration())
144 continue;
145 auto SFMask = FlagsInfo.getFunctionFlags(&F);
146 OS << formatv("; Function {0} : {1:x8}\n;\n", F.getName(),
147 (uint64_t)(SFMask));
148 }
149
150 return PreservedAnalyses::all();
151}
152
153//===----------------------------------------------------------------------===//
154// ShaderFlagsAnalysis and ShaderFlagsAnalysisPrinterPass
155
157 DXILResourceTypeMap &DRTM =
158 getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
159
160 MSFI.initialize(M, DRTM);
161 return false;
162}
163
165 AU.setPreservesAll();
167}
168
170
172 "DXIL Shader Flag Analysis", true, true)
175 "DXIL Shader Flag Analysis", true, true)
basic Basic Alias true
block Block Frequency Analysis
static void updateFunctionFlags(ComputedShaderFlags &CSF, const Instruction &I, DXILResourceTypeMap &DRTM)
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
module summary analysis
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:55
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:57
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:52
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:410
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
AnalysisUsage & addRequiredTransitive()
This class represents an Operation in the Expression.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
LLVM Value Representation.
Definition: Value.h:74
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Wrapper pass for the legacy pass manager.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
ModuleShaderFlags run(Module &M, ModuleAnalysisManager &AM)
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1664
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1978
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: Analysis.h:28
void merge(const uint64_t IVal)
void print(raw_ostream &OS=dbgs()) const
const ComputedShaderFlags & getFunctionFlags(const Function *) const
Return the shader flags mask of the specified function Func.
const ComputedShaderFlags & getCombinedFlags() const
void initialize(const Module &, DXILResourceTypeMap &DRTM)