Skip to content

Commit 4eca6f1

Browse files
Merge branch 'sycl' into visitor-impl-diag
2 parents d1c53d1 + 3833943 commit 4eca6f1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1223
-955
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10982,6 +10982,7 @@ def err_sycl_kernel_incorrectly_named : Error<
1098210982
"kernel %select{name is missing"
1098310983
"|needs to have a globally-visible name"
1098410984
"|name is invalid. Unscoped enum requires fixed underlying type"
10985+
"|name cannot be a type in the \"std\" namespace"
1098510986
"}0">;
1098610987
def err_sycl_kernel_not_function_object
1098710988
: Error<"kernel parameter must be a lambda or function object">;

clang/include/clang/Driver/Options.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3561,6 +3561,15 @@ def fsycl_dead_args_optimization : Flag<["-"], "fsycl-dead-args-optimization">,
35613561
def fno_sycl_dead_args_optimization : Flag<["-"], "fno-sycl-dead-args-optimization">,
35623562
Group<sycl_Group>, Flags<[NoArgumentUnused, CoreOption]>, HelpText<"Disables "
35633563
"elimination of DPC++ dead kernel arguments">;
3564+
def fsycl_device_lib_EQ : CommaJoined<["-"], "fsycl-device-lib=">, Group<sycl_Group>, Flags<[DriverOption, CoreOption]>,
3565+
Values<"libc, libm-fp32, libm-fp64, all">, HelpText<"Control inclusion of "
3566+
"device libraries into device binary linkage. Valid arguments "
3567+
"are libc, libm-fp32, libm-fp64, all">;
3568+
def fno_sycl_device_lib_EQ : CommaJoined<["-"], "fno-sycl-device-lib=">, Group<sycl_Group>, Flags<[DriverOption, CoreOption]>,
3569+
Values<"libc, libm-fp32, libm-fp64, all">, HelpText<"Control exclusion of "
3570+
"device libraries from device binary linkage. Valid arguments "
3571+
"are libc, libm-fp32, libm-fp64, all">;
3572+
35643573
//===----------------------------------------------------------------------===//
35653574
// CC1 Options
35663575
//===----------------------------------------------------------------------===//

clang/lib/Driver/Driver.cpp

Lines changed: 129 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8-
98
#include "clang/Driver/Driver.h"
109
#include "InputInfo.h"
1110
#include "ToolChains/AIX.h"
@@ -1788,20 +1787,21 @@ llvm::Triple Driver::MakeSYCLDeviceTriple(StringRef TargetArch) const {
17881787
// Print the help from any of the given tools which are used for AOT
17891788
// compilation for SYCL
17901789
void Driver::PrintSYCLToolHelp(const Compilation &C) const {
1791-
SmallVector<std::tuple<llvm::Triple, StringRef, StringRef>, 4> HelpArgs;
1790+
SmallVector<std::tuple<llvm::Triple, StringRef, StringRef, StringRef>, 4>
1791+
HelpArgs;
17921792
// Populate the vector with the tools and help options
17931793
if (Arg *A = C.getArgs().getLastArg(options::OPT_fsycl_help_EQ)) {
17941794
StringRef AV(A->getValue());
17951795
llvm::Triple T;
17961796
if (AV == "gen" || AV == "all")
17971797
HelpArgs.push_back(std::make_tuple(MakeSYCLDeviceTriple("spir64_gen"),
1798-
"ocloc", "--help"));
1798+
"ocloc", "--help", ""));
17991799
if (AV == "fpga" || AV == "all")
1800-
HelpArgs.push_back(
1801-
std::make_tuple(MakeSYCLDeviceTriple("spir64_fpga"), "aoc", "-help"));
1800+
HelpArgs.push_back(std::make_tuple(MakeSYCLDeviceTriple("spir64_fpga"),
1801+
"aoc", "-help", "-sycl"));
18021802
if (AV == "x86_64" || AV == "all")
18031803
HelpArgs.push_back(std::make_tuple(MakeSYCLDeviceTriple("spir64_x86_64"),
1804-
"opencl-aot", "--help"));
1804+
"opencl-aot", "--help", ""));
18051805
if (HelpArgs.empty()) {
18061806
C.getDriver().Diag(diag::err_drv_unsupported_option_argument)
18071807
<< A->getOption().getName() << AV;
@@ -1814,7 +1814,8 @@ void Driver::PrintSYCLToolHelp(const Compilation &C) const {
18141814
llvm::outs() << "Emitting help information for " << std::get<1>(HA) << '\n'
18151815
<< "Use triple of '" << std::get<0>(HA).normalize() <<
18161816
"' to enable ahead of time compilation\n";
1817-
std::vector<StringRef> ToolArgs = { std::get<1>(HA), std::get<2>(HA) };
1817+
std::vector<StringRef> ToolArgs = {std::get<1>(HA), std::get<2>(HA),
1818+
std::get<3>(HA)};
18181819
SmallString<128> ExecPath(
18191820
C.getDefaultToolChain().GetProgramPath(std::get<1>(HA).data()));
18201821
auto ToolBinary = llvm::sys::findProgramByName(ExecPath);
@@ -1824,7 +1825,10 @@ void Driver::PrintSYCLToolHelp(const Compilation &C) const {
18241825
}
18251826
// do not run the tools with -###.
18261827
if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
1827-
llvm::errs() << "\"" << ExecPath << "\" \"" << ToolArgs[1] << "\"\n";
1828+
llvm::errs() << "\"" << ExecPath << "\" \"" << ToolArgs[1] << "\"";
1829+
if (!ToolArgs[2].empty())
1830+
llvm::errs() << " \"" << ToolArgs[2] << "\"";
1831+
llvm::errs() << "\n";
18281832
continue;
18291833
}
18301834
// Run the Tool.
@@ -2715,6 +2719,16 @@ static SmallVector<const char *, 16> getLinkerArgs(Compilation &C,
27152719
return LibArgs;
27162720
}
27172721

2722+
static bool IsSYCLDeviceLibObj(std::string ObjFilePath, bool isMSVCEnv) {
2723+
StringRef ObjFileName = llvm::sys::path::filename(ObjFilePath);
2724+
StringRef ObjSuffix = isMSVCEnv ? ".obj" : ".o";
2725+
bool Ret =
2726+
(ObjFileName.startswith("libsycl-") && ObjFileName.endswith(ObjSuffix))
2727+
? true
2728+
: false;
2729+
return Ret;
2730+
}
2731+
27182732
// Goes through all of the arguments, including inputs expected for the
27192733
// linker directly, to determine if we need to perform additional work for
27202734
// static offload libraries.
@@ -3793,7 +3807,13 @@ class OffloadingActionBuilder final {
37933807
if (IA->getType() == types::TY_Object) {
37943808
if (!isObjectFile(FileName))
37953809
return ABRT_Inactive;
3796-
if (Args.hasArg(options::OPT_fintelfpga))
3810+
// For SYCL device libraries, don't need to add them to
3811+
// FPGAObjectInputs as there is no FPGA dep files inside.
3812+
3813+
if (Args.hasArg(options::OPT_fintelfpga) &&
3814+
!IsSYCLDeviceLibObj(FileName, C.getDefaultToolChain()
3815+
.getTriple()
3816+
.isWindowsMSVCEnvironment()))
37973817
FPGAObjectInputs.push_back(IA);
37983818
}
37993819
// When creating FPGA device fat objects, all host objects are
@@ -3857,6 +3877,92 @@ class OffloadingActionBuilder final {
38573877
SYCLDeviceActions.clear();
38583878
}
38593879

3880+
void addSYCLDeviceLibs(const ToolChain *TC, ActionList &DeviceLinkObjects,
3881+
bool isSpirvAOT, bool isMSVCEnv) {
3882+
enum SYCLDeviceLibType {
3883+
sycl_devicelib_wrapper,
3884+
sycl_devicelib_fallback
3885+
};
3886+
struct DeviceLibOptInfo {
3887+
StringRef devicelib_name;
3888+
StringRef devicelib_option;
3889+
};
3890+
3891+
bool NoDeviceLibs = false;
3892+
// Currently, libc, libm-fp32 will be linked in by default. In order
3893+
// to use libm-fp64, -fsycl-device-lib=libm-fp64/all should be used.
3894+
llvm::StringMap<bool> devicelib_link_info = {
3895+
{"libc", true}, {"libm-fp32", true}, {"libm-fp64", false}};
3896+
if (Arg *A = Args.getLastArg(options::OPT_fsycl_device_lib_EQ,
3897+
options::OPT_fno_sycl_device_lib_EQ)) {
3898+
if (A->getValues().size() == 0)
3899+
C.getDriver().Diag(diag::warn_drv_empty_joined_argument)
3900+
<< A->getAsString(Args);
3901+
else {
3902+
if (A->getOption().matches(options::OPT_fno_sycl_device_lib_EQ))
3903+
NoDeviceLibs = true;
3904+
3905+
for (StringRef Val : A->getValues()) {
3906+
if (Val == "all") {
3907+
for (auto &K : devicelib_link_info.keys())
3908+
devicelib_link_info[K] = true && !NoDeviceLibs;
3909+
break;
3910+
}
3911+
auto LinkInfoIter = devicelib_link_info.find(Val);
3912+
if (LinkInfoIter == devicelib_link_info.end()) {
3913+
C.getDriver().Diag(diag::err_drv_unsupported_option_argument)
3914+
<< A->getOption().getName() << Val;
3915+
}
3916+
devicelib_link_info[Val] = true && !NoDeviceLibs;
3917+
}
3918+
}
3919+
}
3920+
3921+
SmallString<128> LibLoc(TC->getDriver().Dir);
3922+
llvm::sys::path::append(LibLoc, "/../lib");
3923+
StringRef LibSuffix = isMSVCEnv ? ".obj" : ".o";
3924+
SmallVector<DeviceLibOptInfo, 5> sycl_device_wrapper_libs = {
3925+
{"libsycl-crt", "libc"},
3926+
{"libsycl-complex", "libm-fp32"},
3927+
{"libsycl-complex-fp64", "libm-fp64"},
3928+
{"libsycl-cmath", "libm-fp32"},
3929+
{"libsycl-cmath-fp64", "libm-fp64"}};
3930+
// For AOT compilation, we need to link sycl_device_fallback_libs as
3931+
// default too.
3932+
SmallVector<DeviceLibOptInfo, 5> sycl_device_fallback_libs = {
3933+
{"libsycl-fallback-cassert", "libc"},
3934+
{"libsycl-fallback-complex", "libm-fp32"},
3935+
{"libsycl-fallback-complex-fp64", "libm-fp64"},
3936+
{"libsycl-fallback-cmath", "libm-fp32"},
3937+
{"libsycl-fallback-cmath-fp64", "libm-fp64"}};
3938+
auto addInputs = [&](SYCLDeviceLibType t) {
3939+
auto sycl_libs = (t == sycl_devicelib_wrapper)
3940+
? sycl_device_wrapper_libs
3941+
: sycl_device_fallback_libs;
3942+
for (const DeviceLibOptInfo &Lib : sycl_libs) {
3943+
if (!devicelib_link_info[Lib.devicelib_option])
3944+
continue;
3945+
SmallString<128> LibName(LibLoc);
3946+
llvm::sys::path::append(LibName, Lib.devicelib_name);
3947+
llvm::sys::path::replace_extension(LibName, LibSuffix);
3948+
if (llvm::sys::fs::exists(LibName)) {
3949+
Arg *InputArg = MakeInputArg(Args, C.getDriver().getOpts(),
3950+
Args.MakeArgString(LibName));
3951+
auto *SYCLDeviceLibsInputAction =
3952+
C.MakeAction<InputAction>(*InputArg, types::TY_Object);
3953+
auto *SYCLDeviceLibsUnbundleAction =
3954+
C.MakeAction<OffloadUnbundlingJobAction>(
3955+
SYCLDeviceLibsInputAction);
3956+
addDeviceDepences(SYCLDeviceLibsUnbundleAction);
3957+
DeviceLinkObjects.push_back(SYCLDeviceLibsUnbundleAction);
3958+
}
3959+
}
3960+
};
3961+
addInputs(sycl_devicelib_wrapper);
3962+
if (isSpirvAOT)
3963+
addInputs(sycl_devicelib_fallback);
3964+
}
3965+
38603966
void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {
38613967
assert(ToolChains.size() == DeviceLinkerInputs.size() &&
38623968
"Toolchains and linker inputs sizes do not match.");
@@ -3936,13 +4042,27 @@ class OffloadingActionBuilder final {
39364042
}
39374043
ActionList DeviceLibObjects;
39384044
ActionList LinkObjects;
4045+
auto TT = SYCLTripleList[I];
4046+
auto isNVPTX = (*TC)->getTriple().isNVPTX();
4047+
bool isSpirvAOT = TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga ||
4048+
TT.getSubArch() == llvm::Triple::SPIRSubArch_gen ||
4049+
TT.getSubArch() == llvm::Triple::SPIRSubArch_x86_64;
39394050
for (const auto &Input : LI) {
39404051
// FPGA aoco does not go through the link, everything else does.
39414052
if (Input->getType() == types::TY_FPGA_AOCO)
39424053
DeviceLibObjects.push_back(Input);
39434054
else
39444055
LinkObjects.push_back(Input);
39454056
}
4057+
// FIXME: Link all wrapper and fallback device libraries as default,
4058+
// When spv online link is supported by all backends, the fallback
4059+
// device libraries are only needed when current toolchain is using
4060+
// AOT compilation.
4061+
if (!isNVPTX) {
4062+
addSYCLDeviceLibs(
4063+
*TC, LinkObjects, true,
4064+
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment());
4065+
}
39464066
// The linkage actions subgraph leading to the offload wrapper.
39474067
// [cond] Means incoming/outgoing dependence is created only when cond
39484068
// is true. A function of:
@@ -3997,7 +4117,6 @@ class OffloadingActionBuilder final {
39974117
Action *DeviceLinkAction =
39984118
C.MakeAction<LinkJobAction>(LinkObjects, types::TY_LLVM_BC);
39994119
// setup some flags upfront
4000-
auto isNVPTX = (*TC)->getTriple().isNVPTX();
40014120

40024121
if (isNVPTX && DeviceCodeSplit) {
40034122
// TODO Temporary limitation, need to support code splitting for PTX
@@ -4009,10 +4128,6 @@ class OffloadingActionBuilder final {
40094128
D.Diag(diag::err_drv_unsupported_opt_for_target)
40104129
<< OptName << (*TC)->getTriple().str();
40114130
}
4012-
auto TT = SYCLTripleList[I];
4013-
bool isSpirvAOT = TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga ||
4014-
TT.getSubArch() == llvm::Triple::SPIRSubArch_gen ||
4015-
TT.getSubArch() == llvm::Triple::SPIRSubArch_x86_64;
40164131
// reflects whether current target is ahead-of-time and can't support
40174132
// runtime setting of specialization constants
40184133
bool isAOT = isNVPTX || isSpirvAOT;

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -823,14 +823,10 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
823823
Args.getLastArg(OPT_emit_llvm_uselists, OPT_no_emit_llvm_uselists))
824824
Opts.EmitLLVMUseLists = A->getOption().getID() == OPT_emit_llvm_uselists;
825825

826-
// ESIMD GPU Back-end requires optimized IR
827-
bool IsSyclESIMD = Args.hasFlag(options::OPT_fsycl_esimd,
828-
options::OPT_fno_sycl_esimd, false);
829-
830826
Opts.DisableLLVMPasses =
831827
Args.hasArg(OPT_disable_llvm_passes) ||
832828
(Args.hasArg(OPT_fsycl_is_device) && Triple.isSPIR() &&
833-
Args.hasArg(OPT_fno_sycl_early_optimizations) && !IsSyclESIMD);
829+
Args.hasArg(OPT_fno_sycl_early_optimizations));
834830
Opts.DisableLifetimeMarkers = Args.hasArg(OPT_disable_lifetimemarkers);
835831

836832
const llvm::Triple::ArchType DebugEntryValueArchs[] = {
@@ -2612,6 +2608,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
26122608
Opts.SYCLValueFitInMaxInt =
26132609
Args.hasFlag(options::OPT_fsycl_id_queries_fit_in_int,
26142610
options::OPT_fno_sycl_id_queries_fit_in_int, false);
2611+
Opts.SYCLIntHeader =
2612+
std::string(Args.getLastArgValue(OPT_fsycl_int_header));
26152613
}
26162614

26172615
Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);
@@ -2672,8 +2670,6 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
26722670
Diags.Report(diag::warn_ignored_hip_only_option)
26732671
<< Args.getLastArg(OPT_gpu_max_threads_per_block_EQ)->getAsString(Args);
26742672

2675-
Opts.SYCLIntHeader = std::string(Args.getLastArgValue(OPT_fsycl_int_header));
2676-
26772673
if (Opts.ObjC) {
26782674
if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
26792675
StringRef value = arg->getValue();

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2978,6 +2978,13 @@ void SYCLIntegrationHeader::emitFwdDecl(raw_ostream &O, const Decl *D,
29782978
if (!NS) {
29792979
break;
29802980
}
2981+
2982+
if (NS->isStdNamespace()) {
2983+
Diag.Report(KernelLocation, diag::err_sycl_kernel_incorrectly_named)
2984+
<< /* name cannot be a type in the std namespace */ 3;
2985+
return;
2986+
}
2987+
29812988
++NamespaceCnt;
29822989
const StringRef NSInlinePrefix = NS->isInline() ? "inline " : "";
29832990
NSStr.insert(
@@ -3060,8 +3067,13 @@ void SYCLIntegrationHeader::emitForwardClassDecls(
30603067
;
30613068
const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
30623069

3063-
if (!RD)
3070+
if (!RD) {
3071+
if (T->isNullPtrType())
3072+
Diag.Report(KernelLocation, diag::err_sycl_kernel_incorrectly_named)
3073+
<< /* name cannot be a type in the std namespace */ 3;
3074+
30643075
return;
3076+
}
30653077

30663078
// see if this is a template specialization ...
30673079
if (const auto *TSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsycl-int-header=%t.h -DCHECK_ERROR -verify %s
2+
// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -fsycl-int-header=%t.h %s
3+
// RUN: FileCheck -input-file=%t.h %s
4+
//
5+
// CHECK: #include <CL/sycl/detail/defines.hpp>
6+
// CHECK-NEXT: #include <CL/sycl/detail/kernel_desc.hpp>
7+
//
8+
// CHECK: static constexpr
9+
// CHECK-NEXT: const char* const kernel_names[] = {
10+
// CHECK-NEXT: "_ZTSm",
11+
// CHECK-NEXT: "_ZTSl"
12+
// CHECK-NEXT: };
13+
//
14+
// CHECK: static constexpr
15+
// CHECK-NEXT: const kernel_param_desc_t kernel_signatures[] = {
16+
// CHECK-NEXT: //--- _ZTSm
17+
// CHECK-EMPTY:
18+
// CHECK-NEXT: //--- _ZTSl
19+
// CHECK-EMPTY:
20+
// CHECK-NEXT: };
21+
//
22+
// CHECK: static constexpr
23+
// CHECK-NEXT: const unsigned kernel_signature_start[] = {
24+
// CHECK-NEXT: 0, // _ZTSm
25+
// CHECK-NEXT: 1 // _ZTSl
26+
// CHECK-NEXT: };
27+
28+
// CHECK: template <> struct KernelInfo<unsigned long> {
29+
// CHECK: template <> struct KernelInfo<long> {
30+
31+
void usage() {
32+
}
33+
34+
namespace std {
35+
typedef long unsigned int size_t;
36+
typedef long int ptrdiff_t;
37+
typedef decltype(nullptr) nullptr_t;
38+
class T;
39+
class U;
40+
} // namespace std
41+
42+
template <typename T>
43+
struct Templated_kernel_name;
44+
45+
template <typename name, typename Func>
46+
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
47+
kernelFunc();
48+
}
49+
50+
int main() {
51+
#ifdef CHECK_ERROR
52+
kernel_single_task<std::nullptr_t>([=]() {}); // expected-error {{kernel name cannot be a type in the "std" namespace}}
53+
kernel_single_task<std::T>([=]() {}); // expected-error {{kernel name cannot be a type in the "std" namespace}}
54+
kernel_single_task<Templated_kernel_name<std::nullptr_t>>([=]() {}); // expected-error {{kernel name cannot be a type in the "std" namespace}}
55+
kernel_single_task<Templated_kernel_name<std::U>>([=]() {}); // expected-error {{kernel name cannot be a type in the "std" namespace}}
56+
#endif
57+
58+
// Although in the std namespace, these resolve to builtins such as `int` that are allowed in kernel names
59+
kernel_single_task<std::size_t>([=]() {});
60+
kernel_single_task<std::ptrdiff_t>([=]() {});
61+
62+
return 0;
63+
}

0 commit comments

Comments
 (0)