[clang] [llvm] handle wrapper (PR #123795)

Steven Perron via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 21 10:08:02 PST 2025


https://github.com/s-perron created https://github.com/llvm/llvm-project/pull/123795

- **[SPIRV] Expand RWBuffer load and store from HLSL**
- **Move type deduction for getpointer into `CallInst` case.**
- **Remove unused table entry.**
- **Move DXILFinalizeLinkage out of backend to clang.**
- **Modify FinalizeLinkage to chagen global variables.**
- **Add global opt pass to remove dead store to global.**


>From 639ac4c16b07f8316a7b32f9010365ea0b250f1c Mon Sep 17 00:00:00 2001
From: Steven Perron <stevenperron at google.com>
Date: Tue, 3 Dec 2024 12:42:40 -0500
Subject: [PATCH 1/6] [SPIRV] Expand RWBuffer load and store from HLSL

The code pattern that clang will generate for HLSL has changed from the
original plan. This allows the SPIR-V backend to generate code for the
current code generation.

It looks for patterns of the form:

```
%1 = @llvm.spv.resource.handlefrombinding
%2 = @llvm.spv.resource.getpointer(%1, index)
load/store %2
```

These three llvm-ir instruction are treated as a single unit that will

1. Generate or find the global variable identified by the call to
   `resource.handlefrombinding`.
2. Generate an OpLoad of the variable to get the handle to the image.
3. Generate an OpImageRead or OpImageWrite using that handle with the
   given index.

This will generate the OpLoad in the same BB as the read/write.

Note: Now that `resource.handlefrombinding` is not processed on its own,
many existing tests had to be removed. We do not have intrinsics that
are able to use handles to sampled images, input attachments, etc., so
we cannot generate the load of the handle. These tests are removed for
now, and will be added when those resource types are fully implemented.
---
 llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 702206b8e0dc56..02b3ac9803deb2 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -731,6 +731,14 @@ Type *SPIRVEmitIntrinsics::deduceElementTypeHelper(
       if (Ty)
         break;
     }
+  } else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
+    if (II->getIntrinsicID() == Intrinsic::spv_resource_getpointer) {
+      auto *ImageType = cast<TargetExtType>(II->getOperand(0)->getType());
+      assert(ImageType->getTargetExtName() == "spirv.Image");
+      Ty = ImageType->getTypeParameter(0);
+      // TODO: Need to look at the use to see if it needs to be a vector of the
+      // type.
+    }
   } else if (auto *CI = dyn_cast<CallInst>(I)) {
     static StringMap<unsigned> ResTypeByArg = {
         {"to_global", 0},

>From 3c4b8af078517f66178367b9dd2bfd2c68e28c7d Mon Sep 17 00:00:00 2001
From: Steven Perron <stevenperron at google.com>
Date: Mon, 13 Jan 2025 14:51:29 -0500
Subject: [PATCH 2/6] Move type deduction for getpointer into `CallInst` case.

---
 llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 02b3ac9803deb2..b59aa797ca3eae 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -731,14 +731,6 @@ Type *SPIRVEmitIntrinsics::deduceElementTypeHelper(
       if (Ty)
         break;
     }
-  } else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
-    if (II->getIntrinsicID() == Intrinsic::spv_resource_getpointer) {
-      auto *ImageType = cast<TargetExtType>(II->getOperand(0)->getType());
-      assert(ImageType->getTargetExtName() == "spirv.Image");
-      Ty = ImageType->getTypeParameter(0);
-      // TODO: Need to look at the use to see if it needs to be a vector of the
-      // type.
-    }
   } else if (auto *CI = dyn_cast<CallInst>(I)) {
     static StringMap<unsigned> ResTypeByArg = {
         {"to_global", 0},
@@ -749,7 +741,8 @@ Type *SPIRVEmitIntrinsics::deduceElementTypeHelper(
         {"__spirv_GenericCastToPtr_ToPrivate", 0},
         {"__spirv_GenericCastToPtrExplicit_ToGlobal", 0},
         {"__spirv_GenericCastToPtrExplicit_ToLocal", 0},
-        {"__spirv_GenericCastToPtrExplicit_ToPrivate", 0}};
+        {"__spirv_GenericCastToPtrExplicit_ToPrivate", 0},
+        {"llvm.spv.resource.getpointer", 0}};
     // TODO: maybe improve performance by caching demangled names
 
     auto *II = dyn_cast<IntrinsicInst>(I);

>From adb1306a9ec6db00ece44850ad78e5f830ff52be Mon Sep 17 00:00:00 2001
From: Steven Perron <stevenperron at google.com>
Date: Tue, 14 Jan 2025 09:50:17 -0500
Subject: [PATCH 3/6] Remove unused table entry.

---
 llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index b59aa797ca3eae..702206b8e0dc56 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -741,8 +741,7 @@ Type *SPIRVEmitIntrinsics::deduceElementTypeHelper(
         {"__spirv_GenericCastToPtr_ToPrivate", 0},
         {"__spirv_GenericCastToPtrExplicit_ToGlobal", 0},
         {"__spirv_GenericCastToPtrExplicit_ToLocal", 0},
-        {"__spirv_GenericCastToPtrExplicit_ToPrivate", 0},
-        {"llvm.spv.resource.getpointer", 0}};
+        {"__spirv_GenericCastToPtrExplicit_ToPrivate", 0}};
     // TODO: maybe improve performance by caching demangled names
 
     auto *II = dyn_cast<IntrinsicInst>(I);

>From 466738cd9a896d14e96766005405f20e08cdae2a Mon Sep 17 00:00:00 2001
From: Steven Perron <stevenperron at google.com>
Date: Thu, 16 Jan 2025 11:32:16 -0500
Subject: [PATCH 4/6] Move DXILFinalizeLinkage out of backend to clang.

---
 clang/lib/CodeGen/BackendUtil.cpp             |  6 ++++++
 clang/lib/CodeGen/CMakeLists.txt              |  1 +
 .../Transforms/HLSL}/DXILFinalizeLinkage.h    |  0
 llvm/lib/Target/DirectX/CMakeLists.txt        |  1 -
 .../Target/DirectX/DirectXTargetMachine.cpp   |  2 --
 llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp  |  2 ++
 llvm/lib/Transforms/CMakeLists.txt            |  1 +
 llvm/lib/Transforms/HLSL/CMakeLists.txt       | 18 +++++++++++++++++
 .../HLSL}/DXILFinalizeLinkage.cpp             | 20 ++-----------------
 9 files changed, 30 insertions(+), 21 deletions(-)
 rename llvm/{lib/Target/DirectX => include/llvm/Transforms/HLSL}/DXILFinalizeLinkage.h (100%)
 create mode 100644 llvm/lib/Transforms/HLSL/CMakeLists.txt
 rename llvm/lib/{Target/DirectX => Transforms/HLSL}/DXILFinalizeLinkage.cpp (72%)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 3951ad01497cca..b43689f3c0f13e 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -57,6 +57,7 @@
 #include "llvm/TargetParser/SubtargetFeature.h"
 #include "llvm/TargetParser/Triple.h"
 #include "llvm/Transforms/HipStdPar/HipStdPar.h"
+#include "llvm/Transforms/HLSL/DXILFinalizeLinkage.h"
 #include "llvm/Transforms/IPO/EmbedBitcodePass.h"
 #include "llvm/Transforms/IPO/LowerTypeTests.h"
 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
@@ -1164,6 +1165,11 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
       LangOpts.HIPStdParInterposeAlloc)
     MPM.addPass(HipStdParAllocationInterpositionPass());
 
+  if (LangOpts.HLSL) {
+    // HLSL legalization passes
+    MPM.addPass(DXILFinalizeLinkage());
+  }
+
   // Now that we have all of the passes ready, run them.
   {
     PrettyStackTraceString CrashInfo("Optimizer");
diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt
index 868ec847b9634b..1c7929219fcfcf 100644
--- a/clang/lib/CodeGen/CMakeLists.txt
+++ b/clang/lib/CodeGen/CMakeLists.txt
@@ -14,6 +14,7 @@ set(LLVM_LINK_COMPONENTS
   FrontendOpenMP
   FrontendOffloading
   HIPStdPar
+  HLSL
   IPO
   IRPrinter
   IRReader
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h b/llvm/include/llvm/Transforms/HLSL/DXILFinalizeLinkage.h
similarity index 100%
rename from llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
rename to llvm/include/llvm/Transforms/HLSL/DXILFinalizeLinkage.h
diff --git a/llvm/lib/Target/DirectX/CMakeLists.txt b/llvm/lib/Target/DirectX/CMakeLists.txt
index 26315db891b577..b7d2034fbdadb7 100644
--- a/llvm/lib/Target/DirectX/CMakeLists.txt
+++ b/llvm/lib/Target/DirectX/CMakeLists.txt
@@ -21,7 +21,6 @@ add_llvm_target(DirectXCodeGen
   DirectXTargetTransformInfo.cpp
   DXContainerGlobals.cpp
   DXILDataScalarization.cpp
-  DXILFinalizeLinkage.cpp
   DXILFlattenArrays.cpp
   DXILIntrinsicExpansion.cpp
   DXILOpBuilder.cpp
diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
index ecb1bf775f8578..c969abb43f858b 100644
--- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
+++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
@@ -61,7 +61,6 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
   initializeDXILTranslateMetadataLegacyPass(*PR);
   initializeDXILResourceMDWrapperPass(*PR);
   initializeShaderFlagsAnalysisWrapperPass(*PR);
-  initializeDXILFinalizeLinkageLegacyPass(*PR);
 }
 
 class DXILTargetObjectFile : public TargetLoweringObjectFile {
@@ -91,7 +90,6 @@ class DirectXPassConfig : public TargetPassConfig {
 
   FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; }
   void addCodeGenPrepare() override {
-    addPass(createDXILFinalizeLinkageLegacyPass());
     addPass(createDXILIntrinsicExpansionLegacyPass());
     addPass(createDXILDataScalarizationLegacyPass());
     addPass(createDXILFlattenArraysLegacyPass());
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index 098c7a6fba50ed..026384a6e71c88 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "SPIRVTargetMachine.h"
+#include "../DirectX/DirectX.h"
 #include "SPIRV.h"
 #include "SPIRVCallLowering.h"
 #include "SPIRVGlobalRegistry.h"
@@ -224,6 +225,7 @@ void SPIRVPassConfig::addPreLegalizeMachineIR() {
 
 // Use the default legalizer.
 bool SPIRVPassConfig::addLegalizeMachineIR() {
+
   addPass(new Legalizer());
   addPass(createSPIRVPostLegalizerPass());
   return false;
diff --git a/llvm/lib/Transforms/CMakeLists.txt b/llvm/lib/Transforms/CMakeLists.txt
index 7046f2f4b1d2c1..e3c13a19f6de17 100644
--- a/llvm/lib/Transforms/CMakeLists.txt
+++ b/llvm/lib/Transforms/CMakeLists.txt
@@ -9,3 +9,4 @@ add_subdirectory(ObjCARC)
 add_subdirectory(Coroutines)
 add_subdirectory(CFGuard)
 add_subdirectory(HipStdPar)
+add_subdirectory(HLSL)
diff --git a/llvm/lib/Transforms/HLSL/CMakeLists.txt b/llvm/lib/Transforms/HLSL/CMakeLists.txt
new file mode 100644
index 00000000000000..886a1737ab495b
--- /dev/null
+++ b/llvm/lib/Transforms/HLSL/CMakeLists.txt
@@ -0,0 +1,18 @@
+add_llvm_component_library(LLVMHlsl
+  DXILFinalizeLinkage.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms/HLSL
+
+  DEPENDS
+  intrinsics_gen
+  LLVMAnalysis
+
+  COMPONENT_NAME
+  HLSL
+
+  LINK_COMPONENTS
+  Analysis
+  Core
+  Support
+  TransformUtils)
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp b/llvm/lib/Transforms/HLSL/DXILFinalizeLinkage.cpp
similarity index 72%
rename from llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
rename to llvm/lib/Transforms/HLSL/DXILFinalizeLinkage.cpp
index 91ac758150fb4c..2ac24f6a26b37a 100644
--- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
+++ b/llvm/lib/Transforms/HLSL/DXILFinalizeLinkage.cpp
@@ -6,8 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "DXILFinalizeLinkage.h"
-#include "DirectX.h"
+#include "llvm/Transforms/HLSL/DXILFinalizeLinkage.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/Metadata.h"
@@ -44,19 +43,4 @@ PreservedAnalyses DXILFinalizeLinkage::run(Module &M,
   if (finalizeLinkage(M))
     return PreservedAnalyses::none();
   return PreservedAnalyses::all();
-}
-
-bool DXILFinalizeLinkageLegacy::runOnModule(Module &M) {
-  return finalizeLinkage(M);
-}
-
-char DXILFinalizeLinkageLegacy::ID = 0;
-
-INITIALIZE_PASS_BEGIN(DXILFinalizeLinkageLegacy, DEBUG_TYPE,
-                      "DXIL Finalize Linkage", false, false)
-INITIALIZE_PASS_END(DXILFinalizeLinkageLegacy, DEBUG_TYPE,
-                    "DXIL Finalize Linkage", false, false)
-
-ModulePass *llvm::createDXILFinalizeLinkageLegacyPass() {
-  return new DXILFinalizeLinkageLegacy();
-}
+}
\ No newline at end of file

>From 7f971fa1e89956441e73949a786d262bff8ddabe Mon Sep 17 00:00:00 2001
From: Steven Perron <stevenperron at google.com>
Date: Thu, 16 Jan 2025 11:48:38 -0500
Subject: [PATCH 5/6] Modify FinalizeLinkage to chagen global variables.

---
 llvm/lib/Transforms/HLSL/DXILFinalizeLinkage.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/HLSL/DXILFinalizeLinkage.cpp b/llvm/lib/Transforms/HLSL/DXILFinalizeLinkage.cpp
index 2ac24f6a26b37a..c0dc4a6aa79c5d 100644
--- a/llvm/lib/Transforms/HLSL/DXILFinalizeLinkage.cpp
+++ b/llvm/lib/Transforms/HLSL/DXILFinalizeLinkage.cpp
@@ -9,7 +9,6 @@
 #include "llvm/Transforms/HLSL/DXILFinalizeLinkage.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GlobalValue.h"
-#include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
 
 #define DEBUG_TYPE "dxil-finalize-linkage"
@@ -19,6 +18,12 @@ using namespace llvm;
 static bool finalizeLinkage(Module &M) {
   SmallPtrSet<Function *, 8> Funcs;
 
+  for(auto &Var : M.globals()) {
+    if (Var.getLinkage() == GlobalValue::ExternalLinkage) {
+      Var.setLinkage(GlobalValue::InternalLinkage);
+    }
+  }
+
   // Collect non-entry and non-exported functions to set to internal linkage.
   for (Function &EF : M.functions()) {
     if (EF.isIntrinsic())

>From 64265ebd451b09a0703d360aa8dbe822382eda60 Mon Sep 17 00:00:00 2001
From: Steven Perron <stevenperron at google.com>
Date: Thu, 16 Jan 2025 14:06:41 -0500
Subject: [PATCH 6/6] Add global opt pass to remove dead store to global.

---
 clang/lib/CodeGen/BackendUtil.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index b43689f3c0f13e..23445ebc369fe7 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -83,6 +83,7 @@
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar/EarlyCSE.h"
 #include "llvm/Transforms/Scalar/GVN.h"
+#include "llvm/Transforms/IPO/GlobalOpt.h"
 #include "llvm/Transforms/Scalar/JumpThreading.h"
 #include "llvm/Transforms/Utils/Debugify.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -1168,6 +1169,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
   if (LangOpts.HLSL) {
     // HLSL legalization passes
     MPM.addPass(DXILFinalizeLinkage());
+    MPM.addPass(GlobalOptPass());
   }
 
   // Now that we have all of the passes ready, run them.



More information about the llvm-commits mailing list