================ @@ -994,6 +994,61 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) { } } +// returns false if binding could not be found in given space +bool DXILResourceBindingInfo::findAvailableBinding(dxil::ResourceClass RC, + uint32_t Space, int32_t Size, + uint32_t *RegSlot) { + BindingSpaces &BS = getBindingSpaces(RC); + RegisterSpace &RS = BS.getOrInsertSpace(Space); + return RS.findAvailableBinding(Size, RegSlot); +} + +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); +} + +bool DXILResourceBindingInfo::RegisterSpace::findAvailableBinding( + int32_t Size, uint32_t *RegSlot) { + assert((Size == -1 || Size > 0) && "invalid size"); + + if (FreeRanges.empty()) + return false; + + // unbounded array + if (Size == -1) { + BindingRange &Last = FreeRanges.back(); + if (Last.UpperBound != UINT32_MAX) + // this space is already occupied by an unbounded array + return false; + *RegSlot = Last.LowerBound; + FreeRanges.pop_back(); + return true; + } + + // 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; ---------------- hekota wrote:
It's because the ranges are inclusive. For range `{0, UINT32_MAX}` (when the whole register space is free) we have `UpperBound == UINT32_MAX` and `LowerBound == 0`, and then `R.UpperBound - R.LowerBound + 1` is `UINT32_MAX - 0 + 1` -> overflow. https://github.com/llvm/llvm-project/pull/138043 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits