LLVM: lib/Target/DirectX/DXILPostOptimizationValidation.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
18#include "llvm/IR/IntrinsicsDirectX.h"
22
23#define DEBUG_TYPE "dxil-post-optimization-validation"
24
25using namespace llvm;
27
29 using namespace dxbc;
30 switch (Type) {
31 case RootParameterType::Constants32Bit:
33 case RootParameterType::SRV:
35 case RootParameterType::UAV:
37 case RootParameterType::CBV:
39 case dxbc::RootParameterType::DescriptorTable:
40 llvm_unreachable("DescriptorTable is not convertible to ResourceClass");
41 }
43}
44
46 for (const auto &UAV : DRM.uavs()) {
48 continue;
49
50 CallInst *ResourceHandle = nullptr;
52 if (*DRM.find(MaybeHandle) == UAV) {
53 ResourceHandle = MaybeHandle;
54 break;
55 }
56 }
57
58 StringRef Message = "RWStructuredBuffers may increment or decrement their "
59 "counters, but not both.";
60 for (const auto &U : ResourceHandle->users()) {
62 if (!CI && CI->getIntrinsicID() != Intrinsic::dx_resource_updatecounter)
63 continue;
64
67 }
68 }
69}
70
75 OS << "resource " << R1.getName() << " at register "
77 << " at register " << R2.getBinding().LowerBound << " in space "
78 << R2.getBinding().Space;
80}
81
83 [[maybe_unused]] bool ErrorFound = false;
84 for (const auto &ResList :
86 if (ResList.empty())
87 continue;
88 const ResourceInfo *PrevRI = &*ResList.begin();
89 for (auto *I = ResList.begin() + 1; I != ResList.end(); ++I) {
92 while (RI != ResList.end() &&
95 ErrorFound = true;
96 RI++;
97 }
98 PrevRI = CurrentRI;
99 }
100 }
101 assert(ErrorFound && "this function should be called only when if "
102 "DXILResourceBindingInfo::hasOverlapingBinding() is "
103 "true, yet no overlapping binding was found");
104}
105
111 OS << RCName << " at register " << Binding.LowerBound << " and space "
112 << Binding.Space << " is bound to a texture or typed buffer. " << RCName
113 << " root descriptors can only be Raw or Structured buffers.";
115}
116
120
125 << " (space=" << R2.Space << ", registers=[" << R2.LowerBound << ", "
126 << R2.UpperBound << "])";
128}
129
130static void
136 << " in space " << Unbound.Space
137 << " does not have a binding in the Root Signature";
139}
140
143 switch (ET) {
145 return dxbc::ShaderVisibility::Pixel;
147 return dxbc::ShaderVisibility::Vertex;
149 return dxbc::ShaderVisibility::Geometry;
151 return dxbc::ShaderVisibility::Hull;
153 return dxbc::ShaderVisibility::Domain;
155 return dxbc::ShaderVisibility::Mesh;
157 return dxbc::ShaderVisibility::All;
158 default:
159 llvm_unreachable("Invalid triple to shader stage conversion");
160 }
161}
162
166 if ((Flags & Mask) != Mask)
167 return;
168
171 OS << "Shader has root bindings but root signature uses a DENY flag to "
172 "disallow root binding access to the shader stage.";
174}
175
176static std::optionaldxbc::RootFlags
178 switch (ShaderProfile) {
180 return dxbc::RootFlags::DenyPixelShaderRootAccess;
182 return dxbc::RootFlags::DenyVertexShaderRootAccess;
184 return dxbc::RootFlags::DenyGeometryShaderRootAccess;
186 return dxbc::RootFlags::DenyHullShaderRootAccess;
188 return dxbc::RootFlags::DenyDomainShaderRootAccess;
190 return dxbc::RootFlags::DenyMeshShaderRootAccess;
192 return dxbc::RootFlags::DenyAmplificationShaderRootAccess;
193 default:
194 return std::nullopt;
195 }
196}
197
203
206
210 if (ParamVisibility != dxbc::ShaderVisibility::All &&
211 ParamVisibility != Visibility)
212 continue;
214 switch (ParamType) {
215 case dxbc::RootParameterType::Constants32Bit: {
219 Const.ShaderRegister, Const.ShaderRegister,
220 &ParamInfo);
221 break;
222 }
223
224 case dxbc::RootParameterType::SRV:
225 case dxbc::RootParameterType::UAV:
226 case dxbc::RootParameterType::CBV: {
230 Desc.ShaderRegister, Desc.ShaderRegister,
231 &ParamInfo);
232
233 break;
234 }
235 case dxbc::RootParameterType::DescriptorTable: {
238
241 Range.NumDescriptors == ~0U
242 ? Range.BaseShaderRegister
243 : Range.BaseShaderRegister + Range.NumDescriptors - 1;
244 Builder.trackBinding(Range.RangeType, Range.RegisterSpace,
245 Range.BaseShaderRegister, UpperBound, &ParamInfo);
246 }
247 break;
248 }
249 }
250 }
251
255
256 Builder.calculateBindingInfo(
260 Builder.findOverlapping(ReportedBinding);
262 });
263
264 const hlsl::BoundRegs &BoundRegs = Builder.takeBoundRegs();
265 bool HasBindings = false;
271
275
276 if () {
278 continue;
279 }
280
281 const auto *ParamInfo =
283
285 bool IsDescriptorTable =
286 ParamInfo->Type == dxbc::RootParameterType::DescriptorTable;
287 bool IsRawOrStructuredBuffer =
289 if (IsSRVOrUAV && !IsDescriptorTable && IsRawOrStructuredBuffer) {
291 continue;
292 }
293
294 HasBindings = true;
295 }
296
297 if (!HasBindings)
298 return;
299
300 if (std::optionaldxbc::RootFlags Mask =
303}
304
312
320
323
325 "DXILResourceImplicitBinding pass");
326
329}
330
342
343namespace {
344class DXILPostOptimizationValidationLegacy : public ModulePass {
345public:
346 bool runOnModule(Module &M) override {
348 getAnalysis().getResourceMap();
350 getAnalysis().getBindingInfo();
352 getAnalysis().getRSInfo();
354 getAnalysis().getModuleMetadata();
356 getAnalysis().getResourceTypeMap();
357
359 return false;
360 }
361 StringRef getPassName() const override {
362 return "DXIL Post Optimization Validation";
363 }
364 DXILPostOptimizationValidationLegacy() : ModulePass(ID) {}
365
366 static char ID;
367 void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
368 AU.addRequired();
369 AU.addRequired();
370 AU.addRequired();
371 AU.addRequired();
372 AU.addRequired();
374 AU.addPreserved();
375 AU.addPreserved();
376 AU.addPreserved();
377 AU.addPreserved();
378 }
379};
380char DXILPostOptimizationValidationLegacy::ID = 0;
381}
382
384 "DXIL Post Optimization Validation", false, false)
392 "DXIL Post Optimization Validation", false, false)
393
395 return new DXILPostOptimizationValidationLegacy();
396}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static dxbc::ShaderVisibility tripleToVisibility(llvm::Triple::EnvironmentType ET)
Definition DXILPostOptimizationValidation.cpp:142
static void reportRegNotBound(Module &M, ResourceClass Class, const llvm::dxil::ResourceInfo::ResourceBinding &Unbound)
Definition DXILPostOptimizationValidation.cpp:131
static ResourceClass toResourceClass(dxbc::RootParameterType Type)
Definition DXILPostOptimizationValidation.cpp:28
static std::optional< dxbc::RootFlags > getEnvironmentDenyFlagMask(Triple::EnvironmentType ShaderProfile)
Definition DXILPostOptimizationValidation.cpp:177
static void reportOverlappingError(Module &M, ResourceInfo R1, ResourceInfo R2)
Definition DXILPostOptimizationValidation.cpp:71
static void reportErrors(Module &M, DXILResourceMap &DRM, DXILResourceBindingInfo &DRBI, RootSignatureBindingInfo &RSBI, dxil::ModuleMetadataInfo &MMI, DXILResourceTypeMap &DRTM)
Definition DXILPostOptimizationValidation.cpp:313
static void validateRootSignature(Module &M, const mcdxbc::RootSignatureDesc &RSD, dxil::ModuleMetadataInfo &MMI, DXILResourceMap &DRM, DXILResourceTypeMap &DRTM)
Definition DXILPostOptimizationValidation.cpp:198
static void reportIfDeniedShaderStageAccess(Module &M, const dxbc::RootFlags &Flags, const dxbc::RootFlags &Mask)
Definition DXILPostOptimizationValidation.cpp:163
static void reportInvalidHandleTyError(Module &M, ResourceClass RC, ResourceInfo::ResourceBinding Binding)
Definition DXILPostOptimizationValidation.cpp:106
static mcdxbc::RootSignatureDesc * getRootSignature(RootSignatureBindingInfo &RSBI, dxil::ModuleMetadataInfo &MMI)
Definition DXILPostOptimizationValidation.cpp:306
static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM)
Definition DXILPostOptimizationValidation.cpp:82
static void reportInvalidDirection(Module &M, DXILResourceMap &DRM)
Definition DXILPostOptimizationValidation.cpp:45
static void reportOverlappingRegisters(Module &M, const llvm::hlsl::Binding &R1, const llvm::hlsl::Binding &R2)
Definition DXILPostOptimizationValidation.cpp:117
DXIL Resource Implicit Binding
Module.h This file contains the declarations for the Module class.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
ModuleAnalysisManager MAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the SmallString class.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
This class represents a function call, abstracting a target machine's calling convention.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
Definition DXILPostOptimizationValidation.cpp:332
bool hasOverlappingBinding() const
bool hasImplicitBinding() const
iterator find(const CallInst *Key)
bool hasInvalidCounterDirection() const
iterator_range< iterator > samplers()
iterator_range< iterator > srvs()
iterator_range< iterator > cbuffers()
iterator_range< iterator > uavs()
iterator_range< call_iterator > calls()
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef - Represent a constant reference to a string, i.e.
The instances of the Type class are immutable: once they are created, they are never changed.
iterator_range< user_iterator > users()
StringRef getName() const
const ResourceBinding & getBinding() const
dxil::ResourceClass getResourceClass() const
dxil::ResourceKind getResourceKind() const
Wrapper pass for the legacy pass manager.
mcdxbc::RootSignatureDesc * getDescForFunction(const Function *F)
Builder class for creating a /c BindingInfo.
const Binding * findBoundReg(dxil::ResourceClass RC, uint32_t Space, uint32_t LowerBound, uint32_t UpperBound) const
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
LLVM_ABI StringRef getResourceClassName(ResourceClass RC)
ResourceKind
The kind of resource for an SRV or UAV resource.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
ModulePass * createDXILPostOptimizationValidationLegacyPass()
Pass to lowering LLVM intrinsic call to DXIL op function call.
Definition DXILPostOptimizationValidation.cpp:394
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
bool overlapsWith(const ResourceBinding &RHS) const
SmallVector< DescriptorRange > Ranges
dxbc::ShaderVisibility Visibility
dxbc::RootParameterType Type
const RootDescriptor & getRootDescriptor(size_t Index) const
const DescriptorTable & getDescriptorTable(size_t Index) const
const RootConstants & getConstant(size_t Index) const
SmallVector< StaticSampler > StaticSamplers
mcdxbc::RootParametersContainer ParametersContainer