[clang] [DXC] Add `-metal` flag to DXC driver (PR #130173)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 6 12:35:03 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Chris B (llvm-beanz)
<details>
<summary>Changes</summary>
This adds a flag to the DXC driver to enable calling the metal shader converter if it is available to convert the final shader output for metal.
---
Full diff: https://github.com/llvm/llvm-project/pull/130173.diff
8 Files Affected:
- (modified) clang/include/clang/Driver/Action.h (+13-1)
- (modified) clang/include/clang/Driver/Options.td (+1)
- (modified) clang/lib/Driver/Action.cpp (+8)
- (modified) clang/lib/Driver/Driver.cpp (+10)
- (modified) clang/lib/Driver/ToolChain.cpp (+1)
- (modified) clang/lib/Driver/ToolChains/HLSL.cpp (+20)
- (modified) clang/lib/Driver/ToolChains/HLSL.h (+14)
- (added) clang/test/Driver/HLSL/metal-converter.hlsl (+14)
``````````diff
diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h
index e5307b0fcedd5..92bb19314e3d6 100644
--- a/clang/include/clang/Driver/Action.h
+++ b/clang/include/clang/Driver/Action.h
@@ -75,9 +75,10 @@ class Action {
LinkerWrapperJobClass,
StaticLibJobClass,
BinaryAnalyzeJobClass,
+ BinaryTranslatorJobClass,
JobClassFirst = PreprocessJobClass,
- JobClassLast = BinaryAnalyzeJobClass
+ JobClassLast = BinaryTranslatorJobClass
};
// The offloading kind determines if this action is binded to a particular
@@ -675,6 +676,17 @@ class BinaryAnalyzeJobAction : public JobAction {
}
};
+class BinaryTranslatorJobAction : public JobAction {
+ void anchor() override;
+
+public:
+ BinaryTranslatorJobAction(Action *Input, types::ID Type);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == BinaryTranslatorJobClass;
+ }
+};
+
} // namespace driver
} // namespace clang
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d0414aba35209..6ed579cb88d90 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -9085,6 +9085,7 @@ def : Option<["/", "-"], "Qembed_debug", KIND_FLAG>, Group<dxc_Group>,
HelpText<"Embed PDB in shader container (ignored)">;
def spirv : DXCFlag<"spirv">,
HelpText<"Generate SPIR-V code">;
+def metal : DXCFlag<"metal">, HelpText<"Generate Metal library">;
def fspv_target_env_EQ : Joined<["-"], "fspv-target-env=">, Group<dxc_Group>,
HelpText<"Specify the target environment">,
Values<"vulkan1.2, vulkan1.3">;
diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp
index 0899b8ef00152..ec09726044812 100644
--- a/clang/lib/Driver/Action.cpp
+++ b/clang/lib/Driver/Action.cpp
@@ -50,6 +50,8 @@ const char *Action::getClassName(ActionClass AC) {
return "static-lib-linker";
case BinaryAnalyzeJobClass:
return "binary-analyzer";
+ case BinaryTranslatorJobClass:
+ return "binary-translator";
}
llvm_unreachable("invalid class");
@@ -459,3 +461,9 @@ void BinaryAnalyzeJobAction::anchor() {}
BinaryAnalyzeJobAction::BinaryAnalyzeJobAction(Action *Input, types::ID Type)
: JobAction(BinaryAnalyzeJobClass, Input, Type) {}
+
+void BinaryTranslatorJobAction::anchor() {}
+
+BinaryTranslatorJobAction::BinaryTranslatorJobAction(Action *Input,
+ types::ID Type)
+ : JobAction(BinaryTranslatorJobClass, Input, Type) {}
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index eca96c1cce7f7..565d804aa8187 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -4672,6 +4672,16 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
Actions.push_back(C.MakeAction<BinaryAnalyzeJobAction>(
LastAction, types::TY_DX_CONTAINER));
}
+ if (Args.getLastArg(options::OPT_metal)) {
+ Action *LastAction = Actions.back();
+ // Metal shader converter runs on DXIL containers, which can either be
+ // validated (in which case they are TY_DX_CONTAINER), or unvalidated
+ // (TY_OBJECT).
+ if (LastAction->getType() == types::TY_DX_CONTAINER ||
+ LastAction->getType() == types::TY_Object)
+ Actions.push_back(C.MakeAction<BinaryTranslatorJobAction>(
+ LastAction, types::TY_DX_CONTAINER));
+ }
}
// Claim ignored clang-cl options.
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 65acbe8a9dbea..fa810457a06cd 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -639,6 +639,7 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const {
case Action::DsymutilJobClass:
case Action::VerifyDebugInfoJobClass:
case Action::BinaryAnalyzeJobClass:
+ case Action::BinaryTranslatorJobClass:
llvm_unreachable("Invalid tool kind.");
case Action::CompileJobClass:
diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp
index ad44c2cfcd811..62e4d14390b90 100644
--- a/clang/lib/Driver/ToolChains/HLSL.cpp
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -198,6 +198,22 @@ void tools::hlsl::Validator::ConstructJob(Compilation &C, const JobAction &JA,
Exec, CmdArgs, Inputs, Input));
}
+void tools::hlsl::MetalConverter::ConstructJob(
+ Compilation &C, const JobAction &JA, const InputInfo &Output,
+ const InputInfoList &Inputs, const ArgList &Args,
+ const char *LinkingOutput) const {
+ std::string MSCPath = getToolChain().GetProgramPath("metal-shaderconverter");
+ ArgStringList CmdArgs;
+ const InputInfo &Input = Inputs[0];
+ CmdArgs.push_back(Input.getFilename());
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Input.getFilename());
+
+ const char *Exec = Args.MakeArgString(MSCPath);
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ Exec, CmdArgs, Inputs, Input));
+}
+
/// DirectX Toolchain
HLSLToolChain::HLSLToolChain(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
@@ -214,6 +230,10 @@ Tool *clang::driver::toolchains::HLSLToolChain::getTool(
if (!Validator)
Validator.reset(new tools::hlsl::Validator(*this));
return Validator.get();
+ case Action::BinaryTranslatorJobClass:
+ if (!MetalConverter)
+ MetalConverter.reset(new tools::hlsl::MetalConverter(*this));
+ return MetalConverter.get();
default:
return ToolChain::getTool(AC);
}
diff --git a/clang/lib/Driver/ToolChains/HLSL.h b/clang/lib/Driver/ToolChains/HLSL.h
index b2a31aabab7dc..86dd65f0b80c6 100644
--- a/clang/lib/Driver/ToolChains/HLSL.h
+++ b/clang/lib/Driver/ToolChains/HLSL.h
@@ -29,6 +29,19 @@ class LLVM_LIBRARY_VISIBILITY Validator : public Tool {
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const override;
};
+
+class LLVM_LIBRARY_VISIBILITY MetalConverter : public Tool {
+public:
+ MetalConverter(const ToolChain &TC)
+ : Tool("hlsl::MetalConverter", "metal-shaderconverter", TC) {}
+
+ bool hasIntegratedCPP() const override { return false; }
+
+ void ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output, const InputInfoList &Inputs,
+ const llvm::opt::ArgList &TCArgs,
+ const char *LinkingOutput) const override;
+};
} // namespace hlsl
} // namespace tools
@@ -57,6 +70,7 @@ class LLVM_LIBRARY_VISIBILITY HLSLToolChain : public ToolChain {
private:
mutable std::unique_ptr<tools::hlsl::Validator> Validator;
+ mutable std::unique_ptr<tools::hlsl::MetalConverter> MetalConverter;
};
} // end namespace toolchains
diff --git a/clang/test/Driver/HLSL/metal-converter.hlsl b/clang/test/Driver/HLSL/metal-converter.hlsl
new file mode 100644
index 0000000000000..4402e5044dc7b
--- /dev/null
+++ b/clang/test/Driver/HLSL/metal-converter.hlsl
@@ -0,0 +1,14 @@
+// RUN: %clang_dxc -T cs_6_0 %s -metal -Fo tmp.mtl -### 2>&1 | FileCheck %s
+// RUN: %clang_dxc -T cs_6_0 %s -metal -Vd -Fo tmp.mtl -### 2>&1 | FileCheck %s
+// CHECK: "{{.*}}metal-shaderconverter{{(.exe)?}}" "tmp.mtl" "-o" "tmp.mtl"
+
+// RUN: %clang_dxc -T cs_6_0 %s -metal -### 2>&1 | FileCheck --check-prefix=NO_MTL %s
+// NO_MTL-NOT: metal-shaderconverter
+
+RWBuffer<float4> In : register(u0, space0);
+RWBuffer<float4> Out : register(u1, space4);
+
+[numthreads(1,1,1)]
+void main(uint GI : SV_GroupIndex) {
+ Out[GI] = In[GI] * In[GI];
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/130173
More information about the cfe-commits
mailing list