[llvm] [DirectX] Implement DXILResourceImplicitBinding pass (PR #138043)

Ashley Coleman via llvm-commits llvm-commits at lists.llvm.org
Fri May 9 16:09:49 PDT 2025


================
@@ -998,6 +998,61 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
   }
 }
 
+// returns false if binding could not be found in given space
+std::optional<uint32_t>
+DXILResourceBindingInfo::findAvailableBinding(dxil::ResourceClass RC,
+                                              uint32_t Space, int32_t Size) {
+  BindingSpaces &BS = getBindingSpaces(RC);
+  RegisterSpace &RS = BS.getOrInsertSpace(Space);
+  return RS.findAvailableBinding(Size);
+}
+
+DXILResourceBindingInfo::RegisterSpace &
+DXILResourceBindingInfo::BindingSpaces::getOrInsertSpace(uint32_t Space) {
+  for (auto *I = Spaces.begin(); I != Spaces.end(); ++I) {
+    if (I->Space == Space)
+      return *I;
+    if (I->Space < Space)
+      continue;
+    return *Spaces.insert(I, Space);
+  }
+  return Spaces.emplace_back(Space);
+}
+
+std::optional<uint32_t>
+DXILResourceBindingInfo::RegisterSpace::findAvailableBinding(int32_t Size) {
+  assert((Size == -1 || Size > 0) && "invalid size");
+
+  std::optional<uint32_t> RegSlot;
+  if (FreeRanges.empty())
+    return RegSlot;
+
+  // unbounded array
+  if (Size == -1) {
----------------
V-FEXrt wrote:

imo `if (Size  == -1)` here is a special of the algorithm so it should early exit instead of `if/else`.  The function below should be identical (assuming my understanding is correct) while also being simplier/easier to read


```c++
std::optional<uint32_t>
DXILResourceBindingInfo::RegisterSpace::findAvailableBinding(int32_t Size) {
  assert((Size == -1 || Size > 0) && "invalid size");

  if (FreeRanges.empty())
    return std::nullopt

  // unbounded array
  if (Size == -1) {
    BindingRange &Last = FreeRanges.back();
    if (Last.UpperBound != UINT32_MAX)
      // this space is already occupied by an unbounded array
      return std::nullopt;
    auto RegSlot = Last.LowerBound;
    FreeRanges.pop_back();
    return RegSlot;
  }

  // single resource or fixed-size array
  for (BindingRange &R : FreeRanges) {
    // compare the size as uint64_t to prevent overflow for range (0,
    // UINT32_MAX)
    if ((uint64_t)R.UpperBound - R.LowerBound + 1 < (uint64_t)Size)
      continue;
    
    auto RegSlot = R.LowerBound;
    // This might create a range where (LowerBound == UpperBound + 1). When
    // that happens, the next time this function is called the range will
    // skipped over by the check above (at this point Size is always > 0).
    R.LowerBound += Size;
    return RegSlot;
  }
  
  return std::nullopt;
}

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


More information about the llvm-commits mailing list