[llvm] [DirectX] Implement DXILResourceBindingAnalysis (PR #137258)
Helena Kotas via llvm-commits
llvm-commits at lists.llvm.org
Thu May 8 23:02:51 PDT 2025
================
@@ -586,6 +589,125 @@ class DXILResourceWrapperPass : public ModulePass {
ModulePass *createDXILResourceWrapperPassPass();
+//===----------------------------------------------------------------------===//
+
+// DXILResourceBindingInfo stores the results of DXILResourceBindingAnalysis
+// which analyses all llvm.dx.resource.handlefrombinding calls in the module
+// and puts together lists of used virtual register spaces and available
+// virtual register slot ranges for each binding type.
+// It also stores additional information found during the analysis such as
+// whether the module uses implicit bindings or if any of the bindings overlap.
+//
+// This information will be used in DXILResourceImplicitBindings pass to assign
+// register slots to resources with implicit bindings, and in a
+// post-optimization validation pass that will raise diagnostic about
+// overlapping bindings.
+//
+// For example for these resource bindings:
+//
+// RWBuffer<float> A[10] : register(u3);
+// RWBuffer<float> B[] : register(u5, space2)
+//
+// The analysis result for UAV binding type will look like this:
+//
+// UAVSpaces {
+// ResClass = ResourceClass::UAV,
+// Spaces = {
+// { Space = 0, FreeRanges = {{ 0, 2 }, { 13, UINT32_MAX }} },
+// { Space = 2, FreeRanges = {{ 0, 4 }} }
+// }
+// }
+//
+class DXILResourceBindingInfo {
+public:
+ struct BindingRange {
+ uint32_t LowerBound;
+ uint32_t UpperBound;
+ BindingRange(uint32_t LB, uint32_t UB) : LowerBound(LB), UpperBound(UB) {}
+ };
+
+ struct RegisterSpace {
+ uint32_t Space;
+ SmallVector<BindingRange> FreeRanges;
+ RegisterSpace(uint32_t Space) : Space(Space) {
+ FreeRanges.emplace_back(0, UINT32_MAX);
+ }
+ };
+
+ struct BindingSpaces {
+ dxil::ResourceClass ResClass;
+ llvm::SmallVector<RegisterSpace> Spaces;
+ BindingSpaces(dxil::ResourceClass ResClass) : ResClass(ResClass) {}
+ };
+
+private:
+ BindingSpaces SRVSpaces, UAVSpaces, CBufferSpaces, SamplerSpaces;
+ bool ImplicitBinding;
+ bool OverlappingBinding;
----------------
hekota wrote:
The OverlappingBinding flag will be used in a post-optimization validation pass introduced [here](https://github.com/llvm/llvm-project/pull/137697/files#diff-d554069d1aa8e3ce9ffd70f5eb434481b69809b9a31ec32af1365c0f16e8f338). If the flag is true, the pass will do a deep dive to gather information about which resources are overlapping and report it. Since this is an error path, it does not have to be optimal. If the flag is false, the pass does not have to do any of that.
The idea is that while the DXILResourceBindingAnalysis is building a map of available register spaces, it can quickly detect that there is something wrong (=an overlap). However, it does not keep track of which resources occupy which spaces, which is needed for proper error reporting. That is an unnecessary overhead since in 99.99+% cases is not going to be needed.
This is similar to what Ashley is doing in the PR mentioned above and that is described in the proposal [here](https://github.com/llvm/wg-hlsl/blob/main/proposals/0022-resource-instance-analysis.md).
> Certain generated DXIL can create an illegal state for an instance's properties such as an instance with both an incremented and decremented counter. When this occurs the analysis pass should prioritize performance for the common case and defer detailed error message calculation for the uncommon failure code path.
> To achieve that goal, a step in DXILResourceAnalysis may set a terminal or invalid value in the ResourceInfo that a later pass DXILPostOptimizationValidationPass (newly introduced by this proposal) will detect and do more expensive processing to raise useful Diagnostics.
> It's important to note that in general Diagnostics should not be raised in LLVM analyses or passes. Analyses may be invalidated and re-ran several times increasing performance impact and raising repeated diagnostics. Diagnostics raised after transformations passes also lose source context resulting in less useful error messages. However the shader compiler requires certain validations to be done after code optimizations which requires the Diagnostic to be raised from a pass. Impact is minimized by raising the Diagnostic only in one pass and minimizing computation in the common case.
I will update the resource binding design proposal to include this information as well.
https://github.com/llvm/llvm-project/pull/137258
More information about the llvm-commits
mailing list