[llvm] [DirectX] Implement DXILResourceBindingAnalysis (PR #137258)

Helena Kotas via llvm-commits llvm-commits at lists.llvm.org
Thu May 8 23:10:52 PDT 2025


================
@@ -879,8 +883,122 @@ SmallVector<dxil::ResourceInfo *> DXILResourceMap::findByUse(const Value *Key) {
 
 //===----------------------------------------------------------------------===//
 
+void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
+  struct Binding {
+    ResourceClass ResClass;
+    uint32_t Space;
+    uint32_t LowerBound;
+    uint32_t UpperBound;
+    Binding(ResourceClass RC, uint32_t Sp, uint32_t LB, uint32_t UB)
+        : ResClass(RC), Space(Sp), LowerBound(LB), UpperBound(UB) {}
+  };
+  SmallVector<Binding> Bindings;
+
+  // collect all of the llvm.dx.resource.handlefrombinding calls;
+  // make a note if there is llvm.dx.resource.handlefromimplicitbinding
+  for (Function &F : M.functions()) {
+    if (!F.isDeclaration())
+      continue;
+
+    switch (F.getIntrinsicID()) {
+    default:
+      continue;
+    case Intrinsic::dx_resource_handlefrombinding: {
+      auto *HandleTy = cast<TargetExtType>(F.getReturnType());
+      ResourceTypeInfo &RTI = DRTM[HandleTy];
+
+      for (User *U : F.users())
+        if (CallInst *CI = dyn_cast<CallInst>(U)) {
+          uint32_t Space =
+              cast<ConstantInt>(CI->getArgOperand(0))->getZExtValue();
+          uint32_t LowerBound =
+              cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
+          int32_t Size =
+              cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
+
+          // negative size means unbounded resource array;
+          // upper bound register overflow should be detected in Sema
+          assert((Size < 0 || (unsigned)LowerBound + Size - 1 <= UINT32_MAX) &&
+                 "upper bound register overflow");
+          uint32_t UpperBound = Size < 0 ? UINT32_MAX : LowerBound + Size - 1;
+          Bindings.emplace_back(RTI.getResourceClass(), Space, LowerBound,
+                                UpperBound);
+        }
+      break;
+    }
+    case Intrinsic::dx_resource_handlefromimplicitbinding: {
+      ImplicitBinding = true;
+      break;
+    }
+    }
+  }
+
+  // sort all the collected bindings
+  llvm::stable_sort(Bindings, [](auto &LHS, auto &RHS) {
+    return std::tie(LHS.ResClass, LHS.Space, LHS.LowerBound) <
+           std::tie(RHS.ResClass, RHS.Space, RHS.LowerBound);
+  });
+
+  // remove duplicates
+  llvm::unique(Bindings, [](auto &LHS, auto &RHS) {
+    return std::tie(LHS.ResClass, LHS.Space, LHS.LowerBound, LHS.UpperBound) ==
+           std::tie(RHS.ResClass, RHS.Space, RHS.LowerBound, RHS.UpperBound);
+  });
+
+  // Go over the sorted bindings and build up lists of free register ranges
+  // for each binding type and used spaces. Bindings are sorted by resource
+  // class, space, and lower bound register slot.
+  BindingSpaces *BS = &SRVSpaces;
+  for (unsigned I = 0, E = Bindings.size(); I != E; ++I) {
+    Binding &B = Bindings[I];
+
+    if (BS->ResClass != B.ResClass)
+      // move to the next resource class spaces
+      BS = &getBindingSpaces(B.ResClass);
+
+    RegisterSpace *S = BS->Spaces.empty() ? &BS->Spaces.emplace_back(B.Space)
+                                          : &BS->Spaces.back();
+    assert(S->Space <= B.Space && "bindings not sorted correctly?");
+    if (B.Space != S->Space)
+      // add new space
+      S = &BS->Spaces.emplace_back(B.Space);
+
+    // the space is full - set flag to report overlapping binding later
+    if (S->FreeRanges.empty()) {
+      OverlappingBinding = true;
----------------
hekota wrote:

Actually, for resources with explicit binding the error message is always the same, and the analysis only maps space occupied by explicit bindings: https://godbolt.org/z/eGsfcEG35

The error message `resource A could not be allocated` is going to be raised during `DXILResourceImplicitBinding` pass when it cannot find a space for a resource. 

https://github.com/llvm/llvm-project/pull/137258


More information about the llvm-commits mailing list