summaryrefslogtreecommitdiffstats
path: root/source/compiler-core
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
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')
-rw-r--r--source/compiler-core/slang-artifact-desc-util.cpp7
-rw-r--r--source/compiler-core/slang-downstream-compiler-util.cpp2
-rw-r--r--source/compiler-core/slang-gcc-compiler-util.cpp11
-rw-r--r--source/compiler-core/slang-metal-compiler.cpp80
-rw-r--r--source/compiler-core/slang-metal-compiler.h18
5 files changed, 116 insertions, 2 deletions
diff --git a/source/compiler-core/slang-artifact-desc-util.cpp b/source/compiler-core/slang-artifact-desc-util.cpp
index 2646555bc..7e3f61915 100644
--- a/source/compiler-core/slang-artifact-desc-util.cpp
+++ b/source/compiler-core/slang-artifact-desc-util.cpp
@@ -287,6 +287,8 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL
case SLANG_OBJECT_CODE: return Desc::make(Kind::ObjectCode, Payload::HostCPU, Style::Kernel, 0);
case SLANG_HOST_HOST_CALLABLE: return Desc::make(Kind::HostCallable, Payload::HostCPU, Style::Host, 0);
case SLANG_METAL: return Desc::make(Kind::Source, Payload::Metal, Style::Kernel, 0);
+ case SLANG_METAL_LIB: return Desc::make(Kind::Executable, Payload::MetalAIR, Style::Kernel, 0);
+ case SLANG_METAL_LIB_ASM: return Desc::make(Kind::Assembly, Payload::MetalAIR, Style::Kernel, 0);
default: break;
}
@@ -328,6 +330,7 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL
case Payload::C: return SLANG_C_SOURCE;
case Payload::Cpp: return (desc.style == Style::Host) ? SLANG_HOST_CPP_SOURCE : SLANG_CPP_SOURCE;
case Payload::CUDA: return SLANG_CUDA_SOURCE;
+ case Payload::Metal: return SLANG_METAL;
default: break;
}
break;
@@ -340,6 +343,7 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL
case Payload::DXIL: return SLANG_DXIL_ASM;
case Payload::DXBC: return SLANG_DXBC_ASM;
case Payload::PTX: return SLANG_PTX;
+ case Payload::MetalAIR: return SLANG_METAL_LIB_ASM;
default: break;
}
}
@@ -367,6 +371,7 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL
case Payload::DXIL: return SLANG_DXIL;
case Payload::DXBC: return SLANG_DXBC;
case Payload::PTX: return SLANG_PTX;
+ case Payload::MetalAIR: return SLANG_METAL_LIB_ASM;
default: break;
}
}
@@ -638,7 +643,7 @@ static UnownedStringSlice _getPayloadExtension(ArtifactPayload payload)
case Payload::SlangIR: return toSlice("slang-ir");
- case Payload::MetalAIR: return toSlice("air");
+ case Payload::MetalAIR: return toSlice("metallib");
case Payload::PdbDebugInfo: return toSlice("pdb");
case Payload::SourceMap: return toSlice("map");
diff --git a/source/compiler-core/slang-downstream-compiler-util.cpp b/source/compiler-core/slang-downstream-compiler-util.cpp
index 52bf03acc..70ecb8ad7 100644
--- a/source/compiler-core/slang-downstream-compiler-util.cpp
+++ b/source/compiler-core/slang-downstream-compiler-util.cpp
@@ -23,6 +23,7 @@
#include "slang-dxc-compiler.h"
#include "slang-glslang-compiler.h"
#include "slang-llvm-compiler.h"
+#include "slang-metal-compiler.h"
namespace Slang
{
@@ -330,6 +331,7 @@ DownstreamCompilerMatchVersion DownstreamCompilerUtil::getCompiledVersion()
outFuncs[int(SLANG_PASS_THROUGH_SPIRV_OPT)] = &SpirvOptDownstreamCompilerUtil::locateCompilers;
outFuncs[int(SLANG_PASS_THROUGH_LLVM)] = &LLVMDownstreamCompilerUtil::locateCompilers;
outFuncs[int(SLANG_PASS_THROUGH_SPIRV_DIS)] = &SpirvDisDownstreamCompilerUtil::locateCompilers;
+ outFuncs[int(SLANG_PASS_THROUGH_METAL)] = &MetalDownstreamCompilerUtil::locateCompilers;
}
static String _getParentPath(const String& path)
diff --git a/source/compiler-core/slang-gcc-compiler-util.cpp b/source/compiler-core/slang-gcc-compiler-util.cpp
index 79aefc71d..2bcdfcbfa 100644
--- a/source/compiler-core/slang-gcc-compiler-util.cpp
+++ b/source/compiler-core/slang-gcc-compiler-util.cpp
@@ -107,12 +107,15 @@ SlangResult GCCDownstreamCompilerUtil::calcVersion(const ExecutableLocation& exe
UnownedStringSlice::fromLiteral("clang version"),
UnownedStringSlice::fromLiteral("gcc version"),
UnownedStringSlice::fromLiteral("Apple LLVM version"),
+ UnownedStringSlice::fromLiteral("Apple metal version"),
+
};
const SlangPassThrough types[] =
{
SLANG_PASS_THROUGH_CLANG,
SLANG_PASS_THROUGH_GCC,
SLANG_PASS_THROUGH_CLANG,
+ SLANG_PASS_THROUGH_METAL,
};
SLANG_COMPILE_TIME_ASSERT(SLANG_COUNT_OF(prefixes) == SLANG_COUNT_OF(types));
@@ -262,8 +265,9 @@ static SlangResult _parseGCCFamilyLine(SliceAllocator& allocator, const UnownedS
const auto split1 = split[1].trim();
const auto text = split[2].trim();
- // Check for special handling for clang (Can be Clang or clang apparently)
+ // Check for special handling for clang or metal
if (split0.startsWith(UnownedStringSlice::fromLiteral("clang")) ||
+ split0.startsWith(UnownedStringSlice::fromLiteral("metal")) ||
split0.startsWith(UnownedStringSlice::fromLiteral("Clang")) ||
split0 == UnownedStringSlice::fromLiteral("g++") ||
split0 == UnownedStringSlice::fromLiteral("gcc"))
@@ -469,6 +473,11 @@ static SlangResult _parseGCCFamilyLine(SliceAllocator& allocator, const UnownedS
// C++17 since we share headers with slang itself (which uses c++17)
cmdLine.addArg("-std=c++17");
}
+
+ if (targetDesc.payload == ArtifactDesc::Payload::MetalAIR)
+ {
+ cmdLine.addArg("-std=macos-metal2.3");
+ }
// Our generated code very often casts between dissimilar types with the
// knowledge that they have the same representation. This is strictly
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);
+ }
+
+}
diff --git a/source/compiler-core/slang-metal-compiler.h b/source/compiler-core/slang-metal-compiler.h
new file mode 100644
index 000000000..7a14e5fa9
--- /dev/null
+++ b/source/compiler-core/slang-metal-compiler.h
@@ -0,0 +1,18 @@
+#ifndef SLANG_METAL_COMPILER_UTIL_H
+#define SLANG_METAL_COMPILER_UTIL_H
+
+#include "slang-downstream-compiler-util.h"
+
+#include "../core/slang-platform.h"
+
+namespace Slang
+{
+
+ struct MetalDownstreamCompilerUtil
+ {
+ static SlangResult locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set);
+ };
+
+}
+
+#endif