Module: Mesa
Branch: main
Commit: 75ff6ca470dcceaba317877e636968278a044ac2
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=75ff6ca470dcceaba317877e636968278a044ac2

Author: Karol Herbst <kher...@redhat.com>
Date:   Tue Jan  9 19:49:47 2024 +0100

clc: add support for the native spir-v backend

This allows us to easily test if the LLVM SPIR-V backend is viable to
replace the translator.

Signed-off-by: Karol Herbst <kher...@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26955>

---

 src/compiler/clc/clc.h                             |  1 +
 src/compiler/clc/clc_helpers.cpp                   | 45 ++++++++++++++++++++++
 .../frontends/rusticl/mesa/compiler/clc/spirv.rs   |  1 +
 3 files changed, 47 insertions(+)

diff --git a/src/compiler/clc/clc.h b/src/compiler/clc/clc.h
index 9d736b16e66..f359fd16892 100644
--- a/src/compiler/clc/clc.h
+++ b/src/compiler/clc/clc.h
@@ -78,6 +78,7 @@ struct clc_compile_args {
    /* SPIRV version to target. */
    enum clc_spirv_version spirv_version;
    struct clc_optional_features features;
+   bool use_llvm_spirv_target;
 
    /* Allowed extensions SPIRV extensions the OpenCL->SPIRV translation can
     * enable. A pointer to a NULL terminated array of strings, allow any
diff --git a/src/compiler/clc/clc_helpers.cpp b/src/compiler/clc/clc_helpers.cpp
index 93186b5775a..589feddb114 100644
--- a/src/compiler/clc/clc_helpers.cpp
+++ b/src/compiler/clc/clc_helpers.cpp
@@ -30,8 +30,11 @@
 #include <llvm/ADT/ArrayRef.h>
 #include <llvm/IR/DiagnosticPrinter.h>
 #include <llvm/IR/DiagnosticInfo.h>
+#include <llvm/IR/LegacyPassManager.h>
 #include <llvm/IR/LLVMContext.h>
 #include <llvm/IR/Type.h>
+#include <llvm/MC/TargetRegistry.h>
+#include <llvm/Target/TargetMachine.h>
 #include <llvm/Support/raw_ostream.h>
 #include <llvm/Bitcode/BitcodeWriter.h>
 #include <llvm/Bitcode/BitcodeReader.h>
@@ -74,9 +77,11 @@ constexpr spv_target_env spirv_target = 
SPV_ENV_UNIVERSAL_1_5;
 constexpr SPIRV::VersionNumber invalid_spirv_trans_version = 
static_cast<SPIRV::VersionNumber>(0);
 
 using ::llvm::Function;
+using ::llvm::legacy::PassManager;
 using ::llvm::LLVMContext;
 using ::llvm::Module;
 using ::llvm::raw_string_ostream;
+using ::llvm::TargetRegistry;
 using ::clang::driver::Driver;
 
 static void
@@ -1052,6 +1057,46 @@ llvm_mod_to_spirv(std::unique_ptr<::llvm::Module> mod,
    spirv_opts.setPreserveOCLKernelArgTypeMetadataThroughString(true);
 #endif
 
+#if LLVM_VERSION_MAJOR >= 17
+   if (args->use_llvm_spirv_target) {
+      const char *triple = args->address_bits == 32 ? "spirv-unknown-unknown" 
: "spirv64-unknown-unknown";
+      std::string error_msg("");
+      auto target = TargetRegistry::lookupTarget(triple, error_msg);
+      if (target) {
+         auto TM = target->createTargetMachine(
+            triple, "", "", {}, std::nullopt, std::nullopt,
+#if LLVM_VERSION_MAJOR >= 18
+            ::llvm::CodeGenOptLevel::None
+#else
+            ::llvm::CodeGenOpt::None
+#endif
+         );
+
+         auto PM = PassManager();
+         ::llvm::SmallVector<char> buf;
+         auto OS = ::llvm::raw_svector_ostream(buf);
+         TM->addPassesToEmitFile(
+            PM, OS, nullptr,
+#if LLVM_VERSION_MAJOR >= 18
+            ::llvm::CodeGenFileType::ObjectFile
+#else
+            ::llvm::CGFT_ObjectFile
+#endif
+         );
+
+         PM.run(*mod);
+
+         out_spirv->size = buf.size_in_bytes();
+         out_spirv->data = malloc(out_spirv->size);
+         memcpy(out_spirv->data, buf.data(), out_spirv->size);
+         return 0;
+      } else {
+         clc_error(logger, "LLVM SPIR-V target not found.\n");
+         return -1;
+      }
+   }
+#endif
+
    std::ostringstream spv_stream;
    if (!::llvm::writeSpirv(mod.get(), spirv_opts, spv_stream, log)) {
       clc_error(logger, "%sTranslation from LLVM IR to SPIR-V failed.\n",
diff --git a/src/gallium/frontends/rusticl/mesa/compiler/clc/spirv.rs 
b/src/gallium/frontends/rusticl/mesa/compiler/clc/spirv.rs
index e6d8214eaa1..e0fab75afa9 100644
--- a/src/gallium/frontends/rusticl/mesa/compiler/clc/spirv.rs
+++ b/src/gallium/frontends/rusticl/mesa/compiler/clc/spirv.rs
@@ -143,6 +143,7 @@ impl SPIRVBin {
             num_args: c_args.len() as u32,
             spirv_version: clc_spirv_version::CLC_SPIRV_VERSION_MAX,
             features: features,
+            use_llvm_spirv_target: false,
             allowed_spirv_extensions: spirv_extensions.as_ptr(),
             address_bits: address_bits,
         };

Reply via email to