summaryrefslogtreecommitdiffstats
path: root/source/compiler-core/slang-metal-compiler.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-04-19 21:02:32 -0700
committerGitHub <noreply@github.com>2024-04-19 21:02:32 -0700
commitbeae3a9d219dac1e4e3da9c357b25d06370388f3 (patch)
treeca4eb2a8e9ca67a130e3894c517114709576af75 /source/compiler-core/slang-metal-compiler.cpp
parentf9bcad35562c1f08638e6d3eb397d370d7d2f8f8 (diff)
Add metal downstream compiler + metallib target. (#3990)
* Add metal downstream compiler + metallib target. * Add more comments. * Add missing override.
Diffstat (limited to 'source/compiler-core/slang-metal-compiler.cpp')
-rw-r--r--source/compiler-core/slang-metal-compiler.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/source/compiler-core/slang-metal-compiler.cpp b/source/compiler-core/slang-metal-compiler.cpp
new file mode 100644
index 000000000..04bcf0f57
--- /dev/null
+++ b/source/compiler-core/slang-metal-compiler.cpp
@@ -0,0 +1,80 @@
+#include "slang-metal-compiler.h"
+#include "slang-gcc-compiler-util.h"
+#include "slang-artifact-desc-util.h"
+#include "slang-artifact-util.h"
+#include "slang-artifact-representation.h"
+
+namespace Slang
+{
+
+ class MetalDownstreamCompiler : public DownstreamCompilerBase
+ {
+ public:
+ // Because the metal compiler shares the same commandline interface with clang,
+ // we will use GccDownstreamCompilerUtil, which implements both gcc and clang,
+ // to create the inner compiler and wrap it here.
+ //
+ ComPtr<IDownstreamCompiler> cppCompiler;
+ String executablePath;
+
+ MetalDownstreamCompiler(ComPtr<IDownstreamCompiler>& innerCompiler, String path)
+ : DownstreamCompilerBase(innerCompiler->getDesc())
+ , cppCompiler(innerCompiler)
+ , executablePath(path)
+ {
+ }
+
+ virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased() override { return true; }
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, IArtifact** outArtifact)
+ {
+ // All compile requests should be routed directly to the inner compiler.
+ return cppCompiler->compile(options, outArtifact);
+ }
+
+ virtual SLANG_NO_THROW bool SLANG_MCALL canConvert(const ArtifactDesc& from, const ArtifactDesc& to) override
+ {
+ // Report that we can convert Metal IR to disassembly.
+ return ArtifactDescUtil::isDisassembly(from, to) && from.payload == ArtifactPayload::MetalAIR;
+ }
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL convert(IArtifact* from, const ArtifactDesc& to, IArtifact** outArtifact) override
+ {
+ // Use metal-objdump to disassemble the Metal IR.
+
+ ExecutableLocation exeLocation(executablePath, "metal-objdump");
+ CommandLine cmdLine;
+ cmdLine.setExecutableLocation(exeLocation);
+ cmdLine.addArg("--disassemble");
+ ComPtr<IOSFileArtifactRepresentation> srcFile;
+ SLANG_RETURN_ON_FAIL(from->requireFile(IArtifact::Keep::No, srcFile.writeRef()));
+ cmdLine.addArg(String(srcFile->getPath()));
+
+ ExecuteResult exeRes;
+ SLANG_RETURN_ON_FAIL(ProcessUtil::execute(cmdLine, exeRes));
+ auto artifact = ArtifactUtil::createArtifact(to);
+ artifact->addRepresentationUnknown(StringBlob::create(exeRes.standardOutput));
+ *outArtifact = artifact.detach();
+ return SLANG_OK;
+ }
+ };
+
+ static SlangResult locateMetalCompiler(const String& path, DownstreamCompilerSet* set)
+ {
+ ComPtr<IDownstreamCompiler> innerCppCompiler;
+ ExecutableLocation exeLocation(path, "metal");
+ SLANG_RETURN_ON_FAIL(GCCDownstreamCompilerUtil::createCompiler(exeLocation, innerCppCompiler));
+
+ ComPtr<IDownstreamCompiler> compiler = ComPtr<IDownstreamCompiler>(
+ new MetalDownstreamCompiler(innerCppCompiler, path));
+ set->addCompiler(compiler);
+ return SLANG_OK;
+ }
+
+ SlangResult MetalDownstreamCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set)
+ {
+ SLANG_UNUSED(loader);
+ return locateMetalCompiler(path, set);
+ }
+
+}