diff options
| author | Yong He <yonghe@outlook.com> | 2024-04-19 21:02:32 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-19 21:02:32 -0700 |
| commit | beae3a9d219dac1e4e3da9c357b25d06370388f3 (patch) | |
| tree | ca4eb2a8e9ca67a130e3894c517114709576af75 /source/compiler-core | |
| parent | f9bcad35562c1f08638e6d3eb397d370d7d2f8f8 (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.cpp | 7 | ||||
| -rw-r--r-- | source/compiler-core/slang-downstream-compiler-util.cpp | 2 | ||||
| -rw-r--r-- | source/compiler-core/slang-gcc-compiler-util.cpp | 11 | ||||
| -rw-r--r-- | source/compiler-core/slang-metal-compiler.cpp | 80 | ||||
| -rw-r--r-- | source/compiler-core/slang-metal-compiler.h | 18 |
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 |
