[clang] [llvm] [HLSL] Create HLSL legalization passes (PR #123811)

Steven Perron via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 24 08:26:10 PST 2025


https://github.com/s-perron updated https://github.com/llvm/llvm-project/pull/123811

>From 4e62f38b70c0c0ae130d0379ebee4d3f3bcb4797 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 1/2] [HLSL] Create HLSL legalization passes

The semantics of HLSL require passes some passes to be run that will
modify the llvm-ir created by clang to match what is expected by the
backend.

In this PR, wewe move the DXILFinalizeLinkage to be run for all backend.
The pass is also renamed to HLSLFinalizeLinkage. A pass of the global opt
pass is run afterwards.

Fixes #122767.
---
 clang/lib/CodeGen/BackendUtil.cpp             |  8 +++
 clang/lib/CodeGen/CMakeLists.txt              |  1 +
 clang/test/CodeGenHLSL/inline-functions.hlsl  |  2 +-
 llvm/lib/Target/DirectX/CMakeLists.txt        |  1 -
 .../Target/DirectX/DXILFinalizeLinkage.cpp    | 62 -------------------
 llvm/lib/Target/DirectX/DXILFinalizeLinkage.h | 39 ------------
 .../Target/DirectX/DirectXTargetMachine.cpp   |  2 -
 llvm/lib/Transforms/CMakeLists.txt            |  1 +
 llvm/lib/Transforms/HLSL/CMakeLists.txt       | 18 ++++++
 9 files changed, 29 insertions(+), 105 deletions(-)
 delete mode 100644 llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
 delete mode 100644 llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
 create mode 100644 llvm/lib/Transforms/HLSL/CMakeLists.txt

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 3951ad01497cca..7537f8b0e2a7b3 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -56,8 +56,10 @@
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/TargetParser/SubtargetFeature.h"
 #include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/HLSL/HLSLFinalizeLinkage.h"
 #include "llvm/Transforms/HipStdPar/HipStdPar.h"
 #include "llvm/Transforms/IPO/EmbedBitcodePass.h"
+#include "llvm/Transforms/IPO/GlobalOpt.h"
 #include "llvm/Transforms/IPO/LowerTypeTests.h"
 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/InstCombine/InstCombine.h"
@@ -1097,6 +1099,12 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
   if (CodeGenOpts.LinkBitcodePostopt)
     MPM.addPass(LinkInModulesPass(BC));
 
+  if (LangOpts.HLSL) {
+    // HLSL legalization passes
+    MPM.addPass(HLSLFinalizeLinkage());
+    MPM.addPass(GlobalOptPass());
+  }
+
   // Add a verifier pass if requested. We don't have to do this if the action
   // requires code generation because there will already be a verifier pass in
   // the code-generation pipeline.
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/clang/test/CodeGenHLSL/inline-functions.hlsl b/clang/test/CodeGenHLSL/inline-functions.hlsl
index fa9c88db26dfc2..37bd2535a5c37d 100644
--- a/clang/test/CodeGenHLSL/inline-functions.hlsl
+++ b/clang/test/CodeGenHLSL/inline-functions.hlsl
@@ -61,7 +61,7 @@ unsigned RemoveDupes(unsigned Buf[MAX], unsigned size) {
 }
 
 
-RWBuffer<unsigned> Indices;
+RWBuffer<unsigned> Indices : register(u0);
 
 // The mangled version of main only remains without inlining
 // because it has internal linkage from the start
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/DXILFinalizeLinkage.cpp b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
deleted file mode 100644
index 91ac758150fb4c..00000000000000
--- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-//===- DXILFinalizeLinkage.cpp - Finalize linkage of functions ------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "DXILFinalizeLinkage.h"
-#include "DirectX.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"
-
-using namespace llvm;
-
-static bool finalizeLinkage(Module &M) {
-  SmallPtrSet<Function *, 8> Funcs;
-
-  // Collect non-entry and non-exported functions to set to internal linkage.
-  for (Function &EF : M.functions()) {
-    if (EF.isIntrinsic())
-      continue;
-    if (EF.hasFnAttribute("hlsl.shader") || EF.hasFnAttribute("hlsl.export"))
-      continue;
-    Funcs.insert(&EF);
-  }
-
-  for (Function *F : Funcs) {
-    if (F->getLinkage() == GlobalValue::ExternalLinkage)
-      F->setLinkage(GlobalValue::InternalLinkage);
-    if (F->isDefTriviallyDead())
-      M.getFunctionList().erase(F);
-  }
-
-  return false;
-}
-
-PreservedAnalyses DXILFinalizeLinkage::run(Module &M,
-                                           ModuleAnalysisManager &AM) {
-  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();
-}
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
deleted file mode 100644
index aab1bc3f7a28e2..00000000000000
--- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===- DXILFinalizeLinkage.h - Finalize linkage of functions --------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// DXILFinalizeLinkage pass updates the linkage of functions to make sure only
-/// shader entry points and exported functions are visible from the module (have
-/// program linkage). All other functions will be updated to have internal
-/// linkage.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_DIRECTX_DXILFINALIZELINKAGE_H
-#define LLVM_TARGET_DIRECTX_DXILFINALIZELINKAGE_H
-
-#include "llvm/IR/PassManager.h"
-#include "llvm/Pass.h"
-
-namespace llvm {
-
-class DXILFinalizeLinkage : public PassInfoMixin<DXILFinalizeLinkage> {
-public:
-  PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
-  static bool isRequired() { return true; }
-};
-
-class DXILFinalizeLinkageLegacy : public ModulePass {
-public:
-  DXILFinalizeLinkageLegacy() : ModulePass(ID) {}
-  bool runOnModule(Module &M) override;
-
-  static char ID; // Pass identification.
-};
-} // namespace llvm
-
-#endif // LLVM_TARGET_DIRECTX_DXILFINALIZELINKAGE_H
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/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..df6af5a6469cbd
--- /dev/null
+++ b/llvm/lib/Transforms/HLSL/CMakeLists.txt
@@ -0,0 +1,18 @@
+add_llvm_component_library(LLVMHlsl
+  HLSLFinalizeLinkage.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms/HLSL
+
+  DEPENDS
+  intrinsics_gen
+  LLVMAnalysis
+
+  COMPONENT_NAME
+  HLSL
+
+  LINK_COMPONENTS
+  Analysis
+  Core
+  Support
+  TransformUtils)

>From 834f6be33005c6fd289e776ad5dbeeebc5509695 Mon Sep 17 00:00:00 2001
From: Steven Perron <stevenperron at google.com>
Date: Tue, 21 Jan 2025 15:25:33 -0500
Subject: [PATCH 2/2] Only run new pass if llvm passes are not disabled.

---
 clang/lib/CodeGen/BackendUtil.cpp             |  2 +-
 .../Transforms/HLSL/HLSLFinalizeLinkage.h     | 39 ++++++++++++++
 .../Transforms/HLSL/HLSLFinalizeLinkage.cpp   | 51 +++++++++++++++++++
 3 files changed, 91 insertions(+), 1 deletion(-)
 create mode 100644 llvm/include/llvm/Transforms/HLSL/HLSLFinalizeLinkage.h
 create mode 100644 llvm/lib/Transforms/HLSL/HLSLFinalizeLinkage.cpp

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 7537f8b0e2a7b3..dc71ea4c346fd7 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1099,7 +1099,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
   if (CodeGenOpts.LinkBitcodePostopt)
     MPM.addPass(LinkInModulesPass(BC));
 
-  if (LangOpts.HLSL) {
+  if (LangOpts.HLSL && !CodeGenOpts.DisableLLVMPasses) {
     // HLSL legalization passes
     MPM.addPass(HLSLFinalizeLinkage());
     MPM.addPass(GlobalOptPass());
diff --git a/llvm/include/llvm/Transforms/HLSL/HLSLFinalizeLinkage.h b/llvm/include/llvm/Transforms/HLSL/HLSLFinalizeLinkage.h
new file mode 100644
index 00000000000000..2da4a41673ef0f
--- /dev/null
+++ b/llvm/include/llvm/Transforms/HLSL/HLSLFinalizeLinkage.h
@@ -0,0 +1,39 @@
+//===- HLSLFinalizeLinkage.h - Finalize linkage of functions --------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// HLSLFinalizeLinkage pass updates the linkage of functions to make sure only
+/// shader entry points and exported functions are visible from the module (have
+/// program linkage). All other functions and variables will be updated to have
+/// internal linkage.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_HLSL_HLSLFINALIZELINKAGE_H
+#define LLVM_TRANSFORMS_HLSL_HLSLFINALIZELINKAGE_H
+
+#include "llvm/IR/PassManager.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class HLSLFinalizeLinkage : public PassInfoMixin<HLSLFinalizeLinkage> {
+public:
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+  static bool isRequired() { return true; }
+};
+
+class HLSLFinalizeLinkageLegacy : public ModulePass {
+public:
+  HLSLFinalizeLinkageLegacy() : ModulePass(ID) {}
+  bool runOnModule(Module &M) override;
+
+  static char ID; // Pass identification.
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_HLSL_HLSLFINALIZELINKAGE_H
diff --git a/llvm/lib/Transforms/HLSL/HLSLFinalizeLinkage.cpp b/llvm/lib/Transforms/HLSL/HLSLFinalizeLinkage.cpp
new file mode 100644
index 00000000000000..8b0b6ea1c1dd6f
--- /dev/null
+++ b/llvm/lib/Transforms/HLSL/HLSLFinalizeLinkage.cpp
@@ -0,0 +1,51 @@
+//===- HLSLFinalizeLinkage.cpp - Finalize linkage of functions ------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/HLSL/HLSLFinalizeLinkage.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Module.h"
+
+#define DEBUG_TYPE "dxil-finalize-linkage"
+
+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())
+      continue;
+    if (EF.hasFnAttribute("hlsl.shader") || EF.hasFnAttribute("hlsl.export"))
+      continue;
+    Funcs.insert(&EF);
+  }
+
+  for (Function *F : Funcs) {
+    if (F->getLinkage() == GlobalValue::ExternalLinkage)
+      F->setLinkage(GlobalValue::InternalLinkage);
+    if (F->isDefTriviallyDead())
+      M.getFunctionList().erase(F);
+  }
+
+  return false;
+}
+
+PreservedAnalyses HLSLFinalizeLinkage::run(Module &M,
+                                           ModuleAnalysisManager &AM) {
+  if (finalizeLinkage(M))
+    return PreservedAnalyses::none();
+  return PreservedAnalyses::all();
+}



More information about the llvm-commits mailing list