Author: Anastasia Stulova Date: 2022-01-11T13:11:38Z New Revision: dbb8d086377ba3a81e44c471840bdbd982c00a35
URL: https://github.com/llvm/llvm-project/commit/dbb8d086377ba3a81e44c471840bdbd982c00a35 DIFF: https://github.com/llvm/llvm-project/commit/dbb8d086377ba3a81e44c471840bdbd982c00a35.diff LOG: [SPIR-V] Add linking using spirv-link. Add support of linking files compiled into SPIR-V objects using spirv-link. Command line inteface examples: clang --target=spirv64 test1.cl test2.cl clang --target=spirv64 test1.cl -o test1.o clang --target=spirv64 test1.o test2.cl -o test_app.out This works independently from the SPIR-V generation method (via an external tool or an internal backend) and applies to either approach that is being used. Differential Revision: https://reviews.llvm.org/D116266 Added: Modified: clang/docs/UsersManual.rst clang/include/clang/Basic/DiagnosticDriverKinds.td clang/lib/Driver/Driver.cpp clang/lib/Driver/ToolChains/SPIRV.cpp clang/lib/Driver/ToolChains/SPIRV.h clang/test/Driver/spirv-toolchain.cl Removed: ################################################################################ diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 5f46322f19af2..bdb9705dac637 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -3599,6 +3599,13 @@ Converting to SPIR-V produced with the optimization levels other than `-O0` is currently available as an experimental feature and it is not guaranteed to work in all cases. +Linking is done using ``spirv-link`` from `the SPIRV-Tools project +<https://github.com/KhronosGroup/SPIRV-Tools#linker>`_. Similar to other external +linkers, Clang will expect ``spirv-link`` to be installed separately and to be +present in the ``PATH`` environment variable. Please refer to `the build and +installation instructions +<https://github.com/KhronosGroup/SPIRV-Tools#build>`_. + .. _clang-cl: clang-cl diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index a7fd2f26478cf..3ea32a8876c91 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -116,10 +116,6 @@ def warn_drv_unsupported_option_for_target : Warning< "ignoring '%0' option as it is not currently supported for target '%1'">, InGroup<OptionIgnored>; -def warn_drv_spirv_linking_multiple_inputs_unsupported: Warning< - "Linking multiple input files is not supported for SPIR-V yet">, - InGroup<OptionIgnored>; - def err_drv_invalid_thread_model_for_target : Error< "invalid thread model '%0' in '%1' for this target">; def err_drv_invalid_linker_name : Error< diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 2c3b137554c0b..82d67a8b8b1ab 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3804,14 +3804,6 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, } } - // FIXME: Linking separate translation units for SPIR-V is not supported yet. - // It can be done either by LLVM IR linking before conversion of the final - // linked module to SPIR-V or external SPIR-V linkers can be used e.g. - // spirv-link. - if (C.getDefaultToolChain().getTriple().isSPIRV() && Inputs.size() > 1) { - Diag(clang::diag::warn_drv_spirv_linking_multiple_inputs_unsupported); - } - handleArguments(C, Args, Inputs, Actions); // Builder to be used to build offloading actions. @@ -3851,15 +3843,8 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, // Queue linker inputs. if (Phase == phases::Link) { assert(Phase == PL.back() && "linking must be final compilation step."); - // Compilation phases are setup per language, however for SPIR-V the - // final linking phase is meaningless since the compilation phase - // produces the final binary. - // FIXME: OpenCL - we could strip linking phase out from OpenCL - // compilation phases if we could verify it is not needed by any target. - if (!C.getDefaultToolChain().getTriple().isSPIRV()) { - LinkerInputs.push_back(Current); - Current = nullptr; - } + LinkerInputs.push_back(Current); + Current = nullptr; break; } diff --git a/clang/lib/Driver/ToolChains/SPIRV.cpp b/clang/lib/Driver/ToolChains/SPIRV.cpp index 50d03e79bbb08..ce6ce5e8998e5 100644 --- a/clang/lib/Driver/ToolChains/SPIRV.cpp +++ b/clang/lib/Driver/ToolChains/SPIRV.cpp @@ -70,3 +70,25 @@ clang::driver::Tool *SPIRVToolChain::getTool(Action::ActionClass AC) const { } return ToolChain::getTool(AC); } +clang::driver::Tool *SPIRVToolChain::buildLinker() const { + return new tools::SPIRV::Linker(*this); +} + +void SPIRV::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + const ToolChain &ToolChain = getToolChain(); + const Driver &D = ToolChain.getDriver(); + std::string Linker = ToolChain.GetProgramPath(getShortName()); + ArgStringList CmdArgs; + AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + + C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), + Args.MakeArgString(Linker), CmdArgs, + Inputs, Output)); +} diff --git a/clang/lib/Driver/ToolChains/SPIRV.h b/clang/lib/Driver/ToolChains/SPIRV.h index 229f7018e3b50..a16ae3ca51fac 100644 --- a/clang/lib/Driver/ToolChains/SPIRV.h +++ b/clang/lib/Driver/ToolChains/SPIRV.h @@ -39,6 +39,17 @@ class LLVM_LIBRARY_VISIBILITY Translator : public Tool { const char *LinkingOutput) const override; }; +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { +public: + Linker(const ToolChain &TC) : Tool("SPIRV::Linker", "spirv-link", TC) {} + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; + } // namespace SPIRV } // namespace tools @@ -68,6 +79,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRVToolChain final : public ToolChain { protected: clang::driver::Tool *getTool(Action::ActionClass AC) const override; + Tool *buildLinker() const override; private: clang::driver::Tool *getTranslator() const; diff --git a/clang/test/Driver/spirv-toolchain.cl b/clang/test/Driver/spirv-toolchain.cl index 4be08f127290f..c2fcb35772592 100644 --- a/clang/test/Driver/spirv-toolchain.cl +++ b/clang/test/Driver/spirv-toolchain.cl @@ -59,7 +59,13 @@ // TMP: {{llvm-spirv.*"}} [[S]] "-to-binary" "-o" {{".*o"}} //----------------------------------------------------------------------------- -// Check that warning occurs if multiple input files are passed. -// RUN: %clang -### --target=spirv64 %s %s 2>&1 | FileCheck --check-prefix=WARN %s +// Check linking when multiple input files are passed. +// RUN: %clang -### -target spirv64 %s %s 2>&1 | FileCheck --check-prefix=SPLINK %s -// WARN: warning: Linking multiple input files is not supported for SPIR-V yet +// SPLINK: clang{{.*}} "-cc1" "-triple" "spirv64" +// SPLINK-SAME: "-o" [[BC:".*bc"]] +// SPLINK: {{llvm-spirv.*"}} [[BC]] "-o" [[SPV1:".*o"]] +// SPLINK: clang{{.*}} "-cc1" "-triple" "spirv64" +// SPLINK-SAME: "-o" [[BC:".*bc"]] +// SPLINK: {{llvm-spirv.*"}} [[BC]] "-o" [[SPV2:".*o"]] +// SPLINK: {{"spirv-link.*"}} [[SPV1]] [[SPV2]] "-o" "a.out" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits