================
@@ -0,0 +1,108 @@
+//===- SPIRVPushConstantAccess.cpp - Translate CBuffer Loads ---------*- 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 changes the types of all the globals in the PushConstant
+// address space into a target extension type, and makes all references
+// to this global go though a custom SPIR-V intrinsic.
+//
+// This allows the backend to properly lower the push constant struct type
+// to a fully laid out type, and generate the proper OpAccessChain.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SPIRVPushConstantAccess.h"
+#include "SPIRV.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#include "SPIRVUtils.h"
+#include "llvm/Frontend/HLSL/CBuffer.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/ReplaceConstant.h"
+
+#define DEBUG_TYPE "spirv-pushconstant-access"
+using namespace llvm;
+
+static bool replacePushConstantAccesses(Module &M, SPIRVGlobalRegistry *GR) {
+  SmallVector<GlobalVariable *> PushConstants;
+  for (GlobalVariable &GV : M.globals()) {
+    if (GV.getAddressSpace() ==
+        storageClassToAddressSpace(SPIRV::StorageClass::PushConstant))
+      PushConstants.push_back(&GV);
+  }
+
+  for (GlobalVariable *GV : PushConstants) {
+    Type *PCType = llvm::TargetExtType::get(
+        M.getContext(), "spirv.PushConstant", {GV->getValueType()});
+    GlobalVariable *NewGV = new GlobalVariable(
+        M, PCType, GV->isConstant(), GV->getLinkage(),
+        /* initializer= */ nullptr, GV->getName(),
+        /* InsertBefore= */ GV, GV->getThreadLocalMode(), 
GV->getAddressSpace(),
+        GV->isExternallyInitialized());
+
+    SmallVector<User *, 4> Users(GV->user_begin(), GV->user_end());
+    for (llvm::User *U : Users) {
+      Instruction *I = dyn_cast<Instruction>(U);
+      if (!I)
+        continue;
----------------
s-perron wrote:

What are the non instruction uses, and why is it okay to leave them as is? 
Looking at the tests, I don't see any case where this happens.

https://github.com/llvm/llvm-project/pull/166793
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to