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/slang-metal-compiler.cpp | |
| 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/slang-metal-compiler.cpp')
| -rw-r--r-- | source/compiler-core/slang-metal-compiler.cpp | 80 |
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); + } + +} |
