.. code-block:: console
- $ clang -target spirv32 test.cl
- $ clang -target spirv64 test.cl
+ $ clang -target spirv32 -c test.cl
+ $ clang -target spirv64 -c test.cl
More details can be found in :ref:`the SPIR-V support section <spir-v>`.
.. code-block:: console
- $ clang -target spirv32 test.cl
- $ clang -target spirv64 test.cl
+ $ clang -target spirv32 -c test.cl
+ $ clang -target spirv64 -c test.cl
Both invocations of Clang will result in the generation of a SPIR-V binary file
`test.o` for 32 bit and 64 bit respectively. This file can be imported
currently available as an experimental feature and it is not guaranteed to work
in all cases.
+Clang also supports integrated generation of SPIR-V without use of ``llvm-spirv``
+tool as an experimental feature when ``-fintegrated-objemitter`` flag is passed in
+the command line.
+
+ .. code-block:: console
+
+ $ clang -target spirv32 -fintegrated-objemitter -c test.cl
+
+Note that only very basic functionality is supported at this point and therefore
+it is not suitable for arbitrary use cases. This feature is only enabled when clang
+build is configured with ``-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=SPIRV`` option.
+
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
installation instructions
<https://github.com/KhronosGroup/SPIRV-Tools#build>`_.
+ .. code-block:: console
+
+ $ clang -target spirv64 test1.cl test2.cl
+
.. _clang-cl:
clang-cl
Flags<[CoreOption, NoXarchOption]>, Group<f_Group>,
HelpText<"Spawn a separate process for each cc1">;
+def fintegrated_objemitter : Flag<["-"], "fintegrated-objemitter">,
+ Flags<[CoreOption, NoXarchOption]>, Group<f_Group>,
+ HelpText<"Use internal machine object code emitter.">;
+def fno_integrated_objemitter : Flag<["-"], "fno-integrated-objemitter">,
+ Flags<[CoreOption, NoXarchOption]>, Group<f_Group>,
+ HelpText<"Use external machine object code emitter.">;
+
def : Flag<["-"], "integrated-as">, Alias<fintegrated_as>, Flags<[NoXarchOption]>;
def : Flag<["-"], "no-integrated-as">, Alias<fno_integrated_as>,
Flags<[CC1Option, FlangOption, NoXarchOption]>;
/// by default.
virtual bool IsIntegratedAssemblerDefault() const { return false; }
+ /// IsIntegratedBackendDefault - Does this tool chain enable
+ /// -fintegrated-objemitter by default.
+ virtual bool IsIntegratedBackendDefault() const { return true; }
+
+ /// IsIntegratedBackendSupported - Does this tool chain support
+ /// -fintegrated-objemitter.
+ virtual bool IsIntegratedBackendSupported() const { return true; }
+
+ /// IsNonIntegratedBackendSupported - Does this tool chain support
+ /// -fno-integrated-objemitter.
+ virtual bool IsNonIntegratedBackendSupported() const { return false; }
+
/// Check if the toolchain should use the integrated assembler.
virtual bool useIntegratedAs() const;
/// Check if the toolchain should use the integrated backend.
- virtual bool useIntegratedBackend() const { return true; }
+ virtual bool useIntegratedBackend() const;
/// Check if the toolchain should use AsmParser to parse inlineAsm when
/// integrated assembler is not default.
IsIntegratedAssemblerDefault());
}
+bool ToolChain::useIntegratedBackend() const {
+ assert(
+ ((IsIntegratedBackendDefault() && IsIntegratedBackendSupported()) ||
+ (!IsIntegratedBackendDefault() || IsNonIntegratedBackendSupported())) &&
+ "(Non-)integrated backend set incorrectly!");
+
+ bool IBackend = Args.hasFlag(options::OPT_fintegrated_objemitter,
+ options::OPT_fno_integrated_objemitter,
+ IsIntegratedBackendDefault());
+
+ // Diagnose when integrated-objemitter options are not supported by this
+ // toolchain.
+ unsigned DiagID;
+ if ((IBackend && !IsIntegratedBackendSupported()) ||
+ (!IBackend && !IsNonIntegratedBackendSupported()))
+ DiagID = clang::diag::err_drv_unsupported_opt_for_target;
+ else
+ DiagID = clang::diag::warn_drv_unsupported_opt_for_target;
+ Arg *A = Args.getLastArg(options::OPT_fno_integrated_objemitter);
+ if (A && !IsNonIntegratedBackendSupported())
+ D.Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
+ A = Args.getLastArg(options::OPT_fintegrated_objemitter);
+ if (A && !IsIntegratedBackendSupported())
+ D.Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
+
+ return IBackend;
+}
+
bool ToolChain::useRelaxRelocations() const {
return ENABLE_X86_RELAX_RELOCATIONS;
}
: ToolChain(D, Triple, Args) {}
bool useIntegratedAs() const override { return true; }
- bool useIntegratedBackend() const override { return false; }
+ bool IsIntegratedBackendDefault() const override { return false; }
+ bool IsNonIntegratedBackendSupported() const override { return true; }
bool IsMathErrnoDefault() const override { return false; }
bool isCrossCompiling() const override { return true; }
bool isPICDefault() const override { return false; }
// CHECK_JMC_WARN_NOT_ELF: -fjmc works only for ELF; option ignored
// CHECK_NOJMC-NOT: -fjmc
// CHECK_JMC: -fjmc
+
+// RUN: %clang -### -fintegrated-objemitter -target x86_64 %s 2>&1 | FileCheck -check-prefix=CHECK-INT-OBJEMITTER %s
+// CHECK-INT-OBJEMITTER-NOT: unsupported option '-fintegrated-objemitter' for target
+// RUN: %clang -### -fno-integrated-objemitter -target x86_64 %s 2>&1 | FileCheck -check-prefix=CHECK-NOINT-OBJEMITTER %s
+// CHECK-NOINT-OBJEMITTER: unsupported option '-fno-integrated-objemitter' for target
// SPLINK-SAME: "-o" [[BC:".*bc"]]
// SPLINK: {{llvm-spirv.*"}} [[BC]] "-o" [[SPV2:".*o"]]
// SPLINK: {{spirv-link.*"}} [[SPV1]] [[SPV2]] "-o" "a.out"
+
+//-----------------------------------------------------------------------------
+// Check external vs internal object emission.
+// RUN: %clang -### --target=spirv64 -fno-integrated-objemitter %s 2>&1 | FileCheck --check-prefix=XTOR %s
+// RUN: %clang -### --target=spirv64 -fintegrated-objemitter %s 2>&1 | FileCheck --check-prefix=BACKEND %s
+
+// XTOR: {{llvm-spirv.*"}}
+// BACKEND-NOT: {{llvm-spirv.*"}}