Skip to content

Commit

Permalink
[SYCL] Enable support for generating LLVM-BC with spir target
Browse files Browse the repository at this point in the history
Given the spir/sycldevice target, pull in the host environment to satisfy
the needed C++ headers.  Also, use of --sycl as an alias for -target
spir64-unknown-linux-sycldevice -emit-spirv.

Signed-off-by: Vladimir Lazarev <vladimir.lazarev@intel.com>
  • Loading branch information
vladimirlaz committed Jan 22, 2019
1 parent a11308a commit 76bcf3c
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 61 deletions.
1 change: 1 addition & 0 deletions clang/include/clang/Driver/Types.def
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,6 @@ TYPE("image", Image, INVALID, "out", "")
TYPE("dSYM", dSYM, INVALID, "dSYM", "A")
TYPE("dependencies", Dependencies, INVALID, "d", "")
TYPE("cuda-fatbin", CUDA_FATBIN, INVALID, "fatbin","A")
TYPE("spirv", SPIRV, INVALID, "spv", "")
TYPE("hip-fatbin", HIP_FATBIN, INVALID, "hipfb", "A")
TYPE("none", Nothing, INVALID, nullptr, "u")
14 changes: 14 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,17 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
T.setObjectFormat(llvm::Triple::COFF);
TargetTriple = T.str();
}
if (Args.hasArg(options::OPT_sycl)) {
// --sycl implies spir arch and SYCL Device
llvm::Triple T(TargetTriple);
// FIXME: defaults to spir64, should probably have a way to set spir
// possibly new -sycl-target option
T.setArch(llvm::Triple::spir64);
T.setVendor(llvm::Triple::UnknownVendor);
T.setOS(llvm::Triple(llvm::sys::getProcessTriple()).getOS());
T.setEnvironment(llvm::Triple::SYCLDevice);
TargetTriple = T.str();
}
if (const Arg *A = Args.getLastArg(options::OPT_target))
TargetTriple = A->getValue();
if (const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
Expand Down Expand Up @@ -3423,6 +3434,9 @@ Action *Driver::ConstructPhaseAction(
Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
return C.MakeAction<BackendJobAction>(Input, Output);
}
if (Args.hasArg(options::OPT_sycl)) {
return C.MakeAction<BackendJobAction>(Input, types::TY_SPIRV);
}
return C.MakeAction<BackendJobAction>(Input, types::TY_PP_Asm);
}
case phases::Assemble:
Expand Down
11 changes: 9 additions & 2 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3417,7 +3417,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
bool IsWindowsCygnus = RawTriple.isWindowsCygwinEnvironment();
bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
bool IsIAMCU = RawTriple.isOSIAMCU();
bool IsSYCL = Args.hasArg(options::OPT_sycl);
bool IsSYCLDevice = (RawTriple.getEnvironment() == llvm::Triple::SYCLDevice);

// Adjust IsWindowsXYZ for CUDA/HIP compilations. Even when compiling in
// device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not
Expand Down Expand Up @@ -3466,10 +3466,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
}

if (IsSYCL) {
if (IsSYCLDevice) {
// We want to compile sycl kernels.
CmdArgs.push_back("-std=c++11");
CmdArgs.push_back("-fsycl-is-device");
// Pass the triple of host when doing SYCL
std::string NormalizedTriple =
llvm::Triple(llvm::sys::getProcessTriple()).normalize();
CmdArgs.push_back("-aux-triple");
CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
}

if (IsOpenMPDevice) {
Expand Down Expand Up @@ -3555,6 +3560,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
} else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
CmdArgs.push_back("-rewrite-objc");
rewriteKind = RK_Fragile;
} else if (JA.getType() == types::TY_SPIRV) {
CmdArgs.push_back("-emit-spirv");
} else {
assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!");
}
Expand Down
14 changes: 13 additions & 1 deletion clang/lib/Driver/ToolChains/Linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,12 @@ static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,

Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
: Generic_ELF(D, Triple, Args) {
GCCInstallation.init(Triple, Args);
// for SYCL device targets, we rely on the host GCC for proper compilation
if (Triple.getEnvironment() == llvm::Triple::SYCLDevice) {
GCCInstallation.init(llvm::Triple(llvm::sys::getProcessTriple()), Args);
} else {
GCCInstallation.init(Triple, Args);
}
Multilibs = GCCInstallation.getMultilibs();
SelectedMultilib = GCCInstallation.getMultilib();
llvm::Triple::ArchType Arch = Triple.getArch();
Expand Down Expand Up @@ -840,6 +845,13 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
if (getTriple().isAndroid())
MultiarchIncludeDirs = AndroidMultiarchIncludeDirs;

// SYCL Device uses Host includes
if (getTriple().getEnvironment() == llvm::Triple::SYCLDevice) {
llvm::Triple HostTriple = llvm::Triple(llvm::sys::getProcessTriple());
if (HostTriple.getArch() == llvm::Triple::x86_64)
MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
}

for (StringRef Dir : MultiarchIncludeDirs) {
if (D.getVFS().exists(SysRoot + Dir)) {
addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir);
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Frontend/CompilerInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -911,8 +911,9 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
if (!hasTarget())
return false;

// Create TargetInfo for the other side of CUDA and OpenMP compilation.
if ((getLangOpts().CUDA || getLangOpts().OpenMPIsDevice) &&
// Create TargetInfo for the other side of CUDA, SYCL and OpenMP compilation.
if ((getLangOpts().CUDA || getLangOpts().OpenMPIsDevice ||
getLangOpts().SYCL) &&
!getFrontendOpts().AuxTriple.empty()) {
auto TO = std::make_shared<TargetOptions>();
TO->Triple = llvm::Triple::normalize(getFrontendOpts().AuxTriple);
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Frontend/InitPreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,8 @@ void clang::InitializePreprocessor(
if (InitOpts.UsePredefines) {
// FIXME: This will create multiple definitions for most of the predefined
// macros. This is not the right way to handle this.
if ((LangOpts.CUDA || LangOpts.OpenMPIsDevice) && PP.getAuxTargetInfo())
if ((LangOpts.CUDA || LangOpts.OpenMPIsDevice || LangOpts.SYCL) &&
PP.getAuxTargetInfo())
InitializePredefinedMacros(*PP.getAuxTargetInfo(), LangOpts, FEOpts,
Builder);

Expand Down
24 changes: 7 additions & 17 deletions clang/test/CodeGenSYCL/kernel-metadata.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
// RUN: %clang -cc1 -DCL_TARGET_OPENCL_VERSION=220 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -I /sycl_include_path -I /opencl_include_path -I /usr/include/c++/4.8.5 -I /usr/include/c++/4.8.5/x86_64-redhat-linux -I /usr/include/c++/4.8.5/backward -I /include -I /usr/include -fcxx-exceptions -fexceptions -emit-llvm -x c++ %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -emit-llvm -x c++ %s -o - | FileCheck %s

// CHECK: define {{.*}}spir_kernel void @kernel_function() {{[^{]+}} !kernel_arg_addr_space ![[MD:[0-9]+]] !kernel_arg_access_qual ![[MD]] !kernel_arg_type ![[MD]] !kernel_arg_base_type ![[MD]] !kernel_arg_type_qual ![[MD]] {
// CHECK: ![[MD]] = !{}

// XFAIL:*

#include <CL/sycl.hpp>


using namespace cl::sycl;
template <typename name, typename Func>
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
kernelFunc();
}

int main() {

queue myQueue;

myQueue.submit([&](handler &cgh) {

cgh.single_task<class kernel_function>([=]() {
});
});

myQueue.wait();
kernel_single_task<class kernel_function>([]() {});
return 0;
}
3 changes: 1 addition & 2 deletions clang/test/CodeGenSYCL/kernel-with-id.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// RUN: %clang -cc1 -DCL_TARGET_OPENCL_VERSION=220 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -I /sycl_include_path -I /opencl_include_path -I /usr/include/c++/4.8.5 -I /usr/include/c++/4.8.5/x86_64-redhat-linux -I /usr/include/c++/4.8.5/backward -I /include -I /usr/include -fcxx-exceptions -fexceptions -emit-llvm -x c++ %s -o - | FileCheck %s

// RUN: %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -emit-llvm -x c++ %s -o - | FileCheck %s
// XFAIL:*

#include <CL/sycl.hpp>
Expand Down
29 changes: 10 additions & 19 deletions clang/test/CodeGenSYCL/spir-calling-conv.cpp
Original file line number Diff line number Diff line change
@@ -1,27 +1,18 @@
// RUN: %clang -cc1 -DCL_TARGET_OPENCL_VERSION=220 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -I /sycl_include_path -I /opencl_include_path -I /usr/include/c++/4.8.5 -I /usr/include/c++/4.8.5/x86_64-redhat-linux -I /usr/include/c++/4.8.5/backward -I /include -I /usr/include -fcxx-exceptions -fexceptions -emit-llvm -x c++ %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -emit-llvm -x c++ %s -o - | FileCheck %s

// XFAIL:*

#include <CL/sycl.hpp>


using namespace cl::sycl;
template <typename name, typename Func>
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
kernelFunc();
}

int main() {

queue myQueue;

myQueue.submit([&](handler &cgh) {

// CHECK: define spir_kernel void @kernel_function()

// CHECK: call spir_func void @"_ZZZ4mainENK3$_0clERN2cl4sycl7handlerEENKUlvE_clEv"(%class.anon* %0)
// CHECK: define spir_kernel void @kernel_function()

// CHECK: define internal spir_func void @"_ZZZ4mainENK3$_0clERN2cl4sycl7handlerEENKUlvE_clEv"(%class.anon* %this)
// CHECK: call spir_func void @"_ZZ4mainENK3$_0clEv"(%class.anon* %0)

cgh.single_task<class kernel_function>([=]() {
});
});
// CHECK: define internal spir_func void @"_ZZ4mainENK3$_0clEv"(%class.anon* %this)

myQueue.wait();
kernel_single_task<class kernel_function>([]() {});
return 0;
}
24 changes: 7 additions & 17 deletions clang/test/CodeGenSYCL/spir-opencl-version.cpp
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
// RUN: %clang -cc1 -DCL_TARGET_OPENCL_VERSION=220 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -I /sycl_include_path -I /opencl_include_path -I /usr/include/c++/4.8.5 -I /usr/include/c++/4.8.5/x86_64-redhat-linux -I /usr/include/c++/4.8.5/backward -I /include -I /usr/include -fcxx-exceptions -fexceptions -emit-llvm -x c++ %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -emit-llvm -x c++ %s -o - | FileCheck %s

// XFAIL:*

#include <CL/sycl.hpp>

using namespace cl::sycl;
template <typename name, typename Func>
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
kernelFunc();
}

int main() {

queue myQueue;

myQueue.submit([&](handler &cgh) {

cgh.single_task<class kernel_function>([=]() {
});
});

myQueue.wait();
kernel_single_task<class kernel_function>([]() {});
return 0;
}


// CHECK: !opencl.spir.version = !{[[SPIR:![0-9]+]]}
// CHECK: !spirv.Source = !{[[LANG:![0-9]+]]}
// CHECK: [[SPIR]] = !{i32 1, i32 2}
Expand Down
7 changes: 7 additions & 0 deletions clang/test/Driver/sycl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// RUN: %clang -### --sycl -c %s 2>&1 | FileCheck %s --check-prefix=DEFAULT
// RUN: %clang -### -target spir64-unknown-linux-sycldevice -c -emit-llvm %s 2>&1 | FileCheck %s --check-prefix=TARGET
// RUN: %clang -### --sycl -c -emit-llvm %s 2>&1 | FileCheck %s --check-prefix=COMBINED

// DEFAULT: "-triple" "spir64-unknown-{{.*}}-sycldevice"{{.*}} "-fsycl-is-device"{{.*}} "-emit-spirv"
// TARGET: "-triple" "spir64-unknown-linux-sycldevice"{{.*}} "-fsycl-is-device"{{.*}} "-emit-llvm-bc"
// COMBINED: "-triple" "spir64-unknown-{{.*}}-sycldevice"{{.*}} "-fsycl-is-device"{{.*}} "-emit-llvm-bc"

0 comments on commit 76bcf3c

Please sign in to comment.