xref: /freebsd/contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.cpp (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
1 //===--- SPIRV.cpp - SPIR-V Tool Implementations ----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "SPIRV.h"
9 #include "CommonArgs.h"
10 #include "clang/Basic/Version.h"
11 #include "clang/Driver/Compilation.h"
12 #include "clang/Driver/Driver.h"
13 #include "clang/Driver/InputInfo.h"
14 #include "clang/Driver/Options.h"
15 
16 using namespace clang::driver;
17 using namespace clang::driver::toolchains;
18 using namespace clang::driver::tools;
19 using namespace llvm::opt;
20 
21 void SPIRV::constructTranslateCommand(Compilation &C, const Tool &T,
22                                       const JobAction &JA,
23                                       const InputInfo &Output,
24                                       const InputInfo &Input,
25                                       const llvm::opt::ArgStringList &Args) {
26   llvm::opt::ArgStringList CmdArgs(Args);
27   CmdArgs.push_back(Input.getFilename());
28 
29   if (Input.getType() == types::TY_PP_Asm)
30     CmdArgs.push_back("-to-binary");
31   if (Output.getType() == types::TY_PP_Asm)
32     CmdArgs.push_back("--spirv-tools-dis");
33 
34   CmdArgs.append({"-o", Output.getFilename()});
35 
36   // Try to find "llvm-spirv-<LLVM_VERSION_MAJOR>". Otherwise, fall back to
37   // plain "llvm-spirv".
38   using namespace std::string_literals;
39   auto VersionedTool = "llvm-spirv-"s + std::to_string(LLVM_VERSION_MAJOR);
40   std::string ExeCand = T.getToolChain().GetProgramPath(VersionedTool.c_str());
41   if (!llvm::sys::fs::can_execute(ExeCand))
42     ExeCand = T.getToolChain().GetProgramPath("llvm-spirv");
43 
44   const char *Exec = C.getArgs().MakeArgString(ExeCand);
45   C.addCommand(std::make_unique<Command>(JA, T, ResponseFileSupport::None(),
46                                          Exec, CmdArgs, Input, Output));
47 }
48 
49 void SPIRV::Translator::ConstructJob(Compilation &C, const JobAction &JA,
50                                      const InputInfo &Output,
51                                      const InputInfoList &Inputs,
52                                      const ArgList &Args,
53                                      const char *LinkingOutput) const {
54   claimNoWarnArgs(Args);
55   if (Inputs.size() != 1)
56     llvm_unreachable("Invalid number of input files.");
57   constructTranslateCommand(C, *this, JA, Output, Inputs[0], {});
58 }
59 
60 clang::driver::Tool *SPIRVToolChain::getTranslator() const {
61   if (!Translator)
62     Translator = std::make_unique<SPIRV::Translator>(*this);
63   return Translator.get();
64 }
65 
66 clang::driver::Tool *SPIRVToolChain::SelectTool(const JobAction &JA) const {
67   Action::ActionClass AC = JA.getKind();
68   return SPIRVToolChain::getTool(AC);
69 }
70 
71 clang::driver::Tool *SPIRVToolChain::getTool(Action::ActionClass AC) const {
72   switch (AC) {
73   default:
74     break;
75   case Action::BackendJobClass:
76   case Action::AssembleJobClass:
77     return SPIRVToolChain::getTranslator();
78   }
79   return ToolChain::getTool(AC);
80 }
81 clang::driver::Tool *SPIRVToolChain::buildLinker() const {
82   return new tools::SPIRV::Linker(*this);
83 }
84 
85 void SPIRV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
86                                  const InputInfo &Output,
87                                  const InputInfoList &Inputs,
88                                  const ArgList &Args,
89                                  const char *LinkingOutput) const {
90   const ToolChain &ToolChain = getToolChain();
91   std::string Linker = ToolChain.GetProgramPath(getShortName());
92   ArgStringList CmdArgs;
93   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
94 
95   CmdArgs.push_back("-o");
96   CmdArgs.push_back(Output.getFilename());
97 
98   C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
99                                          Args.MakeArgString(Linker), CmdArgs,
100                                          Inputs, Output));
101 }
102