aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Driver/Driver.cpp36
-rw-r--r--clang/lib/Driver/ToolChain.cpp2
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp4
-rw-r--r--clang/lib/Driver/ToolChains/Clang.h7
-rw-r--r--clang/lib/Driver/ToolChains/SPIRV.cpp25
-rw-r--r--clang/lib/Driver/ToolChains/SPIRV.h33
6 files changed, 100 insertions, 7 deletions
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 45bfcef..3b551ea 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -43,6 +43,7 @@
#include "ToolChains/PPCLinux.h"
#include "ToolChains/PS4CPU.h"
#include "ToolChains/RISCVToolchain.h"
+#include "ToolChains/SPIRV.h"
#include "ToolChains/Solaris.h"
#include "ToolChains/TCE.h"
#include "ToolChains/VEToolchain.h"
@@ -3774,6 +3775,14 @@ 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.
@@ -3813,8 +3822,15 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
// Queue linker inputs.
if (Phase == phases::Link) {
assert(Phase == PL.back() && "linking must be final compilation step.");
- LinkerInputs.push_back(Current);
- Current = nullptr;
+ // 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;
+ }
break;
}
@@ -4387,6 +4403,12 @@ class ToolSelector final {
if (!T)
return nullptr;
+ // Can't collapse if we don't have codegen support unless we are
+ // emitting LLVM IR.
+ bool OutputIsLLVM = types::isLLVMIR(ActionInfo[0].JA->getType());
+ if (!T->hasIntegratedBackend() && !(OutputIsLLVM && T->canEmitIR()))
+ return nullptr;
+
// When using -fembed-bitcode, it is required to have the same tool (clang)
// for both CompilerJA and BackendJA. Otherwise, combine two stages.
if (EmbedBitcode) {
@@ -4456,6 +4478,12 @@ class ToolSelector final {
if (!T)
return nullptr;
+ // Can't collapse if we don't have codegen support unless we are
+ // emitting LLVM IR.
+ bool OutputIsLLVM = types::isLLVMIR(ActionInfo[0].JA->getType());
+ if (!T->hasIntegratedBackend() && !(OutputIsLLVM && T->canEmitIR()))
+ return nullptr;
+
if (T->canEmitIR() && ((SaveTemps && !InputIsBitcode) || EmbedBitcode))
return nullptr;
@@ -5479,6 +5507,10 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
case llvm::Triple::ve:
TC = std::make_unique<toolchains::VEToolChain>(*this, Target, Args);
break;
+ case llvm::Triple::spirv32:
+ case llvm::Triple::spirv64:
+ TC = std::make_unique<toolchains::SPIRVToolChain>(*this, Target, Args);
+ break;
default:
if (Target.getVendor() == llvm::Triple::Myriad)
TC = std::make_unique<toolchains::MyriadToolChain>(*this, Target,
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index ac033dd..50c89aa 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -260,7 +260,7 @@ bool ToolChain::IsUnwindTablesDefault(const ArgList &Args) const {
Tool *ToolChain::getClang() const {
if (!Clang)
- Clang.reset(new tools::Clang(*this));
+ Clang.reset(new tools::Clang(*this, useIntegratedBackend()));
return Clang.get();
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 2a37239..ca62229 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7126,11 +7126,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.ClaimAllArgs(options::OPT_emit_llvm);
}
-Clang::Clang(const ToolChain &TC)
+Clang::Clang(const ToolChain &TC, bool HasIntegratedBackend)
// CAUTION! The first constructor argument ("clang") is not arbitrary,
// as it is for other tools. Some operations on a Tool actually test
// whether that tool is Clang based on the Tool's Name as a string.
- : Tool("clang", "clang frontend", TC) {}
+ : Tool("clang", "clang frontend", TC), HasBackend(HasIntegratedBackend) {}
Clang::~Clang() {}
diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h
index d4b4988..00e0490 100644
--- a/clang/lib/Driver/ToolChains/Clang.h
+++ b/clang/lib/Driver/ToolChains/Clang.h
@@ -26,6 +26,10 @@ namespace tools {
/// Clang compiler tool.
class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
+ // Indicates whether this instance has integrated backend using
+ // internal LLVM infrastructure.
+ bool HasBackend;
+
public:
static const char *getBaseInputName(const llvm::opt::ArgList &Args,
const InputInfo &Input);
@@ -99,11 +103,12 @@ private:
const InputInfo &Input, const llvm::opt::ArgList &Args) const;
public:
- Clang(const ToolChain &TC);
+ Clang(const ToolChain &TC, bool HasIntegratedBackend = true);
~Clang() override;
bool hasGoodDiagnostics() const override { return true; }
bool hasIntegratedAssembler() const override { return true; }
+ bool hasIntegratedBackend() const override { return HasBackend; }
bool hasIntegratedCPP() const override { return true; }
bool canEmitIR() const override { return true; }
diff --git a/clang/lib/Driver/ToolChains/SPIRV.cpp b/clang/lib/Driver/ToolChains/SPIRV.cpp
index 16e72d3..50d03e7 100644
--- a/clang/lib/Driver/ToolChains/SPIRV.cpp
+++ b/clang/lib/Driver/ToolChains/SPIRV.cpp
@@ -13,6 +13,7 @@
#include "clang/Driver/Options.h"
using namespace clang::driver;
+using namespace clang::driver::toolchains;
using namespace clang::driver::tools;
using namespace llvm::opt;
@@ -27,7 +28,7 @@ void SPIRV::constructTranslateCommand(Compilation &C, const Tool &T,
if (Input.getType() == types::TY_PP_Asm)
CmdArgs.push_back("-to-binary");
if (Output.getType() == types::TY_PP_Asm)
- CmdArgs.push_back("-spirv-text");
+ CmdArgs.push_back("--spirv-tools-dis");
CmdArgs.append({"-o", Output.getFilename()});
@@ -47,3 +48,25 @@ void SPIRV::Translator::ConstructJob(Compilation &C, const JobAction &JA,
llvm_unreachable("Invalid number of input files.");
constructTranslateCommand(C, *this, JA, Output, Inputs[0], {});
}
+
+clang::driver::Tool *SPIRVToolChain::getTranslator() const {
+ if (!Translator)
+ Translator = std::make_unique<SPIRV::Translator>(*this);
+ return Translator.get();
+}
+
+clang::driver::Tool *SPIRVToolChain::SelectTool(const JobAction &JA) const {
+ Action::ActionClass AC = JA.getKind();
+ return SPIRVToolChain::getTool(AC);
+}
+
+clang::driver::Tool *SPIRVToolChain::getTool(Action::ActionClass AC) const {
+ switch (AC) {
+ default:
+ break;
+ case Action::BackendJobClass:
+ case Action::AssembleJobClass:
+ return SPIRVToolChain::getTranslator();
+ }
+ return ToolChain::getTool(AC);
+}
diff --git a/clang/lib/Driver/ToolChains/SPIRV.h b/clang/lib/Driver/ToolChains/SPIRV.h
index 35d0446..229f701 100644
--- a/clang/lib/Driver/ToolChains/SPIRV.h
+++ b/clang/lib/Driver/ToolChains/SPIRV.h
@@ -41,6 +41,39 @@ public:
} // namespace SPIRV
} // namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY SPIRVToolChain final : public ToolChain {
+ mutable std::unique_ptr<Tool> Translator;
+
+public:
+ SPIRVToolChain(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args)
+ : ToolChain(D, Triple, Args) {}
+
+ bool useIntegratedAs() const override { return true; }
+ bool useIntegratedBackend() const override { return false; }
+
+ bool IsMathErrnoDefault() const override { return false; }
+ bool isCrossCompiling() const override { return true; }
+ bool isPICDefault() const override { return false; }
+ bool isPIEDefault(const llvm::opt::ArgList &Args) const override {
+ return false;
+ }
+ bool isPICDefaultForced() const override { return false; }
+ bool SupportsProfiling() const override { return false; }
+
+ clang::driver::Tool *SelectTool(const JobAction &JA) const override;
+
+protected:
+ clang::driver::Tool *getTool(Action::ActionClass AC) const override;
+
+private:
+ clang::driver::Tool *getTranslator() const;
+};
+
+} // namespace toolchains
} // namespace driver
} // namespace clang
#endif