[llvm-branch-commits] [llvm] Reapply "[SPIRV] Emit intrinsics for globals only in function that references them (#178143 (#179268)) (PR #182552)

Konrad Kleine via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Feb 23 05:57:58 PST 2026


================
@@ -62,6 +62,94 @@ namespace llvm::SPIRV {
 } // namespace llvm::SPIRV
 
 namespace {
+// This class keeps track of which functions reference which global variables.
+class GlobalVariableUsers {
+  template <typename T1, typename T2>
+  using OneToManyMapTy = DenseMap<T1, SmallPtrSet<T2, 4>>;
+
+  OneToManyMapTy<const GlobalVariable *, const Function *> GlobalIsUsedByFun;
+
+  void collectGlobalUsers(
+      const GlobalVariable *GV,
+      OneToManyMapTy<const GlobalVariable *, const GlobalVariable *>
+          &GlobalIsUsedByGlobal) {
+    SmallVector<const Value *> Stack = {GV->user_begin(), GV->user_end()};
+    while (!Stack.empty()) {
+      const Value *V = Stack.pop_back_val();
+
+      if (const Instruction *I = dyn_cast<Instruction>(V)) {
+        GlobalIsUsedByFun[GV].insert(I->getFunction());
+        continue;
+      }
+
+      if (const GlobalVariable *UserGV = dyn_cast<GlobalVariable>(V)) {
+        GlobalIsUsedByGlobal[GV].insert(UserGV);
+        continue;
+      }
+
+      if (const Constant *C = dyn_cast<Constant>(V))
+        Stack.append(C->user_begin(), C->user_end());
+    }
+  }
+
+  bool propagateGlobalToGlobalUsers(
+      OneToManyMapTy<const GlobalVariable *, const GlobalVariable *>
+          &GlobalIsUsedByGlobal) {
+    SmallVector<const GlobalVariable *> OldUsersGlobals;
+    bool Changed = false;
+    for (auto &[GV, UserGlobals] : GlobalIsUsedByGlobal) {
+      OldUsersGlobals.assign(UserGlobals.begin(), UserGlobals.end());
+      for (const GlobalVariable *UserGV : OldUsersGlobals) {
+        auto It = GlobalIsUsedByGlobal.find(UserGV);
+        if (It == GlobalIsUsedByGlobal.end())
+          continue;
+        Changed |= set_union(UserGlobals, It->second);
+      }
+    }
+    return Changed;
+  }
+
+  void propagateGlobalToFunctionReferences(
+      OneToManyMapTy<const GlobalVariable *, const GlobalVariable *>
+          &GlobalIsUsedByGlobal) {
+    for (auto &[GV, UserGlobals] : GlobalIsUsedByGlobal) {
+      auto &UserFunctions = GlobalIsUsedByFun[GV];
+      for (const GlobalVariable *UserGV : UserGlobals) {
+        auto It = GlobalIsUsedByFun.find(UserGV);
+        if (It == GlobalIsUsedByFun.end())
+          continue;
+        set_union(UserFunctions, It->second);
+      }
+    }
+  }
+
+public:
+  void init(Module &M) {
+    // Collect which global variables are referenced by which global variables
+    // and which functions reference each global variables.
+    OneToManyMapTy<const GlobalVariable *, const GlobalVariable *>
+        GlobalIsUsedByGlobal;
+    GlobalIsUsedByFun.clear();
+    for (GlobalVariable &GV : M.globals())
+      collectGlobalUsers(&GV, GlobalIsUsedByGlobal);
+
+    // Compute indirect references by iterating until a fixed point is reached.
+    while (propagateGlobalToGlobalUsers(GlobalIsUsedByGlobal))
+      (void)0;
+
+    propagateGlobalToFunctionReferences(GlobalIsUsedByGlobal);
+  }
+
+  const auto &getTransitiveUserFunctions(const GlobalVariable &GV) const {
+    auto It = GlobalIsUsedByFun.find(&GV);
+    if (It != GlobalIsUsedByFun.end())
+      return It->second;
+
+    using FunctionSetType = typename decltype(GlobalIsUsedByFun)::mapped_type;
+    const static FunctionSetType Empty;
+    return Empty;
+  }
----------------
kwk wrote:

Hey, this turned out to be a more constructive outcome than I anticipated. Thank you.

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


More information about the llvm-branch-commits mailing list