Anastasia created this revision.
Anastasia added reviewers: svenvh, linjamaki, azabaznov.
Herald added subscribers: ThomasRaoux, ebevhan.
Anastasia requested review of this revision.

Add support of linking files compiled into SPIR-V object files using spirv-link 
(https://github.com/KhronosGroup/SPIRV-Tools#linker).

Examples:

  clang --target=spirv64 test1.cl test2.cl



  clang  --target=spirv64 test1.cl -o test1.o
  clang  --target=spirv64 test1.o test2.cl




https://reviews.llvm.org/D116266

Files:
  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

Index: clang/test/Driver/spirv-toolchain.cl
===================================================================
--- clang/test/Driver/spirv-toolchain.cl
+++ clang/test/Driver/spirv-toolchain.cl
@@ -59,7 +59,12 @@
 // 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
-
-// WARN: warning: Linking multiple input files is not supported for SPIR-V yet
+// Check linking when multiple input files are passed.
+// RUN: %clang -### -target spirv64 %s %s 2>&1 | FileCheck --check-prefix=SPLINK %s
+// 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"
Index: clang/lib/Driver/ToolChains/SPIRV.h
===================================================================
--- clang/lib/Driver/ToolChains/SPIRV.h
+++ clang/lib/Driver/ToolChains/SPIRV.h
@@ -39,6 +39,17 @@
                     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 @@
 
 protected:
   clang::driver::Tool *getTool(Action::ActionClass AC) const override;
+  Tool *buildLinker() const override;
 
 private:
   clang::driver::Tool *getTranslator() const;
Index: clang/lib/Driver/ToolChains/SPIRV.cpp
===================================================================
--- clang/lib/Driver/ToolChains/SPIRV.cpp
+++ clang/lib/Driver/ToolChains/SPIRV.cpp
@@ -70,3 +70,25 @@
   }
   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));
+}
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -3725,14 +3725,6 @@
     }
   }
 
-  // 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.
@@ -3772,15 +3764,8 @@
       // 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;
       }
 
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -108,10 +108,6 @@
   "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<
Index: clang/docs/UsersManual.rst
===================================================================
--- clang/docs/UsersManual.rst
+++ clang/docs/UsersManual.rst
@@ -3564,6 +3564,13 @@
 currently available as an experimental feature and it is not guaranteed to work
 in all cases.
 
+Linking is done using `spirv-link` linker from `the SPIRV-Tools project
+<https://github.com/KhronosGroup/SPIRV-Tools#linker>`_. Similar to other
+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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to