Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion buildbot/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def do_configure(args):
xptifw_dir = os.path.join(abs_src_dir, "xptifw")
libdevice_dir = os.path.join(abs_src_dir, "libdevice")
jit_dir = os.path.join(abs_src_dir, "sycl-jit")
llvm_targets_to_build = args.host_target
llvm_targets_to_build = "SPIRV;" + args.host_target
llvm_enable_projects = "clang;" + llvm_external_projects
libclc_build_native = "OFF"
libclc_targets_to_build = ""
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -6919,6 +6919,10 @@ def fsycl_host_only : Flag<["-"], "fsycl-host-only">,
def sycl_link : Flag<["--"], "sycl-link">, Flags<[HelpHidden]>,
HelpText<"Perform link through clang-sycl-linker via the target "
"offloading toolchain.">;
def sycl_use_spirv_backend
: Flag<["--"], "sycl-use-spirv-backend">,
Flags<[HelpHidden]>,
HelpText<"Use SPIR-V backend for LLVM to SPIR-V translation.">;
defm sycl_early_optimizations :
OptOutCC1FFlag<"sycl-early-optimizations", "Enable", "Disable", " standard "
"optimization pipeline for SYCL device compiler",
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Driver/ToolChains/SPIRV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ void SPIRV::Linker::ConstructJob(Compilation &C, const JobAction &JA,

CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
if (Args.hasArg(options::OPT_sycl_use_spirv_backend))
CmdArgs.push_back("-use-spirv-backend");

// Use of --sycl-link will call the clang-sycl-linker instead of
// the default linker (spirv-link).
Expand Down
5 changes: 5 additions & 0 deletions clang/test/Driver/clang-sycl-linker-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,8 @@
// RUN: clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=LLVMOPTSLIN
// LLVMOPTSLIN: -spirv-debug-info-version=nonsemantic-shader-200 -spirv-allow-unknown-intrinsics=llvm.genx. -spirv-ext=

// Test if SPIR-V backend is called when -use-spirv-backend is specified.
// RUN: clang-sycl-linker --dry-run -use-spirv-backend %t_1.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=SPV-BACKEND
// SPV-BACKEND: LLVM-SPIRV-Backend: input: {{.*}}, output: {{.*}}
5 changes: 5 additions & 0 deletions clang/test/Driver/sycl-link-spirv-target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@
// RUN: -Xlinker --library-path=/tmp -Xlinker --device-libs=lib1.bc,lib2.bc %t.bc 2>&1 \
// RUN: | FileCheck %s -check-prefix=XLINKEROPTS
// XLINKEROPTS: "{{.*}}clang-sycl-linker{{.*}}" "--llvm-spirv-path=/tmp" "--library-path=/tmp" "--device-libs=lib1.bc,lib2.bc" "{{.*}}.bc" "-o" "a.out"

// Test that -use-spirv-backend option is being passed to clang-sycl-linker, when -sycl-use-spirv-backend is specified.
// RUN: %clangxx -### --target=spirv64 --sycl-link --sycl-use-spirv-backend %t.bc 2>&1 \
// RUN: | FileCheck %s -check-prefix=SPIRV_BACKEND
// SPIRV_BACKEND: "{{.*}}clang-sycl-linker{{.*}}" "{{.*}}.bc" "-o" "a.out" "-use-spirv-backend"
62 changes: 61 additions & 1 deletion clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "clang/Basic/Version.h"

#include "../../llvm/lib/Target/SPIRV/SPIRVAPI.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Bitcode/BitcodeWriter.h"
Expand Down Expand Up @@ -423,6 +424,63 @@ static Expected<StringRef> runLLVMToSPIRVTranslation(StringRef File,
return OutputFile;
}

/// Run LLVM to SPIR-V translation.
/// Converts 'File' from LLVM bitcode to SPIR-V format using SPIR-V backend,
/// 'Args' encompasses all arguments required for linking device code and will
/// be parsed to generate options required to be passed into the backend.
static Expected<StringRef> runLLVMSPIRVBackend(StringRef File,
const ArgList &Args) {
llvm::TimeTraceScope TimeScope("LLVMToSPIRVTranslationViaSPIRVBackend");
std::vector<std::string> ExtNames, Opts;
if (Verbose || DryRun) {
errs() << formatv("LLVM-SPIRV-Backend: input: {0}, output: {1}\n", File,
OutputFile);
if (DryRun)
return OutputFile;
}
SMDiagnostic Err;
LLVMContext C;
std::unique_ptr<Module> M = parseIRFile(File, Err, C);
if (!M)
return createStringError(inconvertibleErrorCode(), Err.getMessage());

static const std::string DefaultTriple = "spirv64v1.6-unknown-unknown";

// Correct the Triple value if needed
// TODO: Remove this correction once we start using spirv64/spirv32 triples
// everywhere.
Triple TargetTriple(M->getTargetTriple());
if (TargetTriple.isSPIR()) {
TargetTriple.setArch(TargetTriple.getArch() == Triple::spir64
? Triple::spirv64
: Triple::spirv32,
TargetTriple.getSubArch());
M->setTargetTriple(TargetTriple.str());
// We need to reset Data Layout to conform with the TargetMachine
M->setDataLayout("");
}
if (TargetTriple.getTriple().empty())
TargetTriple.setTriple(DefaultTriple);
TargetTriple.setArch(TargetTriple.getArch(), Triple::SPIRVSubArch_v16);
M->setTargetTriple(TargetTriple.str());

int FD = -1;
if (std::error_code EC = sys::fs::openFileForWrite(OutputFile, FD))
return errorCodeToError(EC);
auto OS = std::make_unique<llvm::raw_fd_ostream>(FD, true);

std::string Result, ErrMsg;
// List of allowed extensions. Currently, all extensions are allowed.
// TODO: Update list of allowed extensions for SYCL compilation flow.
static const std::vector<std::string> AllowExtNames{"all"};
// Translate the Module into SPIR-V
if (!SPIRVTranslateModule(M.release(), Result, ErrMsg, AllowExtNames, {}))
return createStringError(
"SPIRVTranslation: SPIRV translation failed with " + ErrMsg);
*OS << Result;
return OutputFile;
}

Error runSYCLLink(ArrayRef<std::string> Files, const ArgList &Args) {
llvm::TimeTraceScope TimeScope("SYCLDeviceLink");
// First llvm-link step
Expand All @@ -436,7 +494,9 @@ Error runSYCLLink(ArrayRef<std::string> Files, const ArgList &Args) {
reportError(DeviceLinkedFile.takeError());

// LLVM to SPIR-V translation step
auto SPVFile = runLLVMToSPIRVTranslation(*DeviceLinkedFile, Args);
auto SPVFile = Args.hasArg(OPT_use_spirv_backend)
? runLLVMSPIRVBackend(*DeviceLinkedFile, Args)
: runLLVMToSPIRVTranslation(*DeviceLinkedFile, Args);
if (!SPVFile)
return SPVFile.takeError();
return Error::success();
Expand Down
6 changes: 6 additions & 0 deletions clang/tools/clang-sycl-linker/SYCLLinkOpts.td
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,9 @@ def llvm_spirv_path_EQ : Joined<["--"], "llvm-spirv-path=">,
def llvm_spirv_options_EQ : Joined<["--", "-"], "llvm-spirv-options=">,
Flags<[LinkerOnlyOption]>,
HelpText<"Options that will control llvm-spirv step">;

// TODO: Option will be removed when llvm-spirv translator is removed
def use_spirv_backend : Flag<["--", "-"], "use-spirv-backend">,
Flags<[LinkerOnlyOption]>,
HelpText<"Use the SPIR-V backend for LLVM to SPIR-V "
"translation. Off by default">;
2 changes: 2 additions & 0 deletions sycl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ add_custom_target(sycl-compiler
clang-offload-extract
clang-offload-packager
clang-linker-wrapper
clang-sycl-linker
file-table-tform
llc
llvm-ar
Expand Down Expand Up @@ -461,6 +462,7 @@ set( SYCL_TOOLCHAIN_DEPLOY_COMPONENTS
clang-offload-extract
clang-offload-packager
clang-linker-wrapper
clang-sycl-linker
file-table-tform
llc
llvm-ar
Expand Down
Loading