[llvm] [SPIRV] Add pass to replace gethandlefromimplicitbinding (PR #146756)

Steven Perron via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 30 09:34:41 PDT 2025


================
@@ -0,0 +1,159 @@
+//===- SPIRVLegalizeImplicitBinding.cpp - Legalize implicit bindings ----*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass legalizes the @llvm.spv.resource.handlefromimplicitbinding
+// intrinsic by replacing it with a call to
+// @llvm.spv.resource.handlefrombinding.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SPIRV.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstVisitor.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include <algorithm>
+#include <vector>
+
+using namespace llvm;
+
+namespace {
+class SPIRVLegalizeImplicitBinding : public ModulePass {
+public:
+  static char ID;
+  SPIRVLegalizeImplicitBinding() : ModulePass(ID) {}
+
+  bool runOnModule(Module &M) override;
+
+private:
+  void collectBindingInfo(Module &M);
+  uint32_t getAndReserveFirstUnusedBinding(uint32_t DescSet);
+  void replaceImplicitBindingCalls(Module &M);
+
+  // A map from descriptor set to a bit vector of used binding numbers.
+  std::vector<BitVector> UsedBindings;
+  // A list of all implicit binding calls, to be sorted by order ID.
+  SmallVector<CallInst *, 16> ImplicitBindingCalls;
+};
+
+struct BindingInfoCollector : public InstVisitor<BindingInfoCollector> {
+  std::vector<BitVector> &UsedBindings;
+  SmallVector<CallInst *, 16> &ImplicitBindingCalls;
+
+  BindingInfoCollector(std::vector<BitVector> &UsedBindings,
+                       SmallVector<CallInst *, 16> &ImplicitBindingCalls)
+      : UsedBindings(UsedBindings), ImplicitBindingCalls(ImplicitBindingCalls) {
+  }
+
+  void visitCallInst(CallInst &CI) {
+    if (CI.getIntrinsicID() == Intrinsic::spv_resource_handlefrombinding) {
+      const uint32_t DescSet =
+          cast<ConstantInt>(CI.getArgOperand(0))->getZExtValue();
+      const uint32_t Binding =
+          cast<ConstantInt>(CI.getArgOperand(1))->getZExtValue();
+
+      if (UsedBindings.size() <= DescSet) {
+        UsedBindings.resize(DescSet + 1);
+        UsedBindings[DescSet].resize(64);
+      }
+      if (UsedBindings[DescSet].size() <= Binding) {
+        UsedBindings[DescSet].resize(2 * Binding);
----------------
s-perron wrote:

I could add an assert that the size is not 0.

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


More information about the llvm-commits mailing list