Skip to content

Commit 55a1b08

Browse files
author
Erich Keane
authored
[SYCL] Correct CFE behavior with named lambdas in unnamed-lambda mode (#3990)
The library is responsible to replace a non-named kernel's name with the type of the lambda. However, it still allows the user to specify the name if they'd like, and uses that as the name instead. The current implementation ALWAYS marked the kernel functor as the name of the kernel, but this isn't correct, it isn't the name of the kernel unless the library makes it so. This ends up causing user-named kernels that have their names changed by the functor they pass in. We can't mark the first template parameter, since it might be a user provided name, and we can't mark the functor since the user might have provided a name. However, if they are both the same (after unqualification and canonicalization) that means that the library has done such a replacement, and thus needs to be marked.
1 parent ebb9fe8 commit 55a1b08

26 files changed

+465
-238
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ defvar hip = LangOpts<"HIP">;
470470
defvar gnu_mode = LangOpts<"GNUMode">;
471471
defvar asm_preprocessor = LangOpts<"AsmPreprocessor">;
472472
defvar cpp_modules = LangOpts<"CPlusPlusModules">;
473+
defvar sycl_ver = LangOpts<"SYCLVersion">;
473474

474475
defvar std = !strconcat("LangStandard::getLangStandardForKind(", lang_std.KeyPath, ")");
475476

@@ -2599,9 +2600,14 @@ def fsycl_link_EQ : Joined<["-"], "fsycl-link=">,
25992600
def fsycl_link : Flag<["-"], "fsycl-link">, Alias<fsycl_link_EQ>,
26002601
AliasArgs<["early"]>, Flags<[CC1Option, CoreOption]>,
26012602
HelpText<"Generate partially linked device object to be used with the host link">;
2602-
def fsycl_unnamed_lambda : Flag<["-"], "fsycl-unnamed-lambda">,
2603-
Flags<[CC1Option, CoreOption]>, HelpText<"Allow unnamed SYCL lambda kernels">,
2604-
MarshallingInfoFlag<LangOpts<"SYCLUnnamedLambda">>;
2603+
defm sycl_unnamed_lambda
2604+
: BoolFOption<
2605+
"sycl-unnamed-lambda", LangOpts<"SYCLUnnamedLambda">,
2606+
Default<!strconcat(
2607+
sycl_ver.KeyPath,
2608+
" >= clang::LangOptions::SYCLMajorVersion::SYCL_2020")>,
2609+
PosFlag<SetTrue, [], "Allow">, NegFlag<SetFalse, [], "Disallow">,
2610+
BothFlags<[CC1Option, CoreOption], " unnamed SYCL lambda kernels">>;
26052611
def fsycl_help_EQ : Joined<["-"], "fsycl-help=">,
26062612
Flags<[NoXarchOption, CoreOption]>, HelpText<"Emit help information from the "
26072613
"related offline compilation tool. Valid values: all, fpga, gen, x86_64.">,
@@ -5896,9 +5902,6 @@ def sycl_std_EQ : Joined<["-"], "sycl-std=">, Group<sycl_Group>,
58965902
Flags<[CC1Option, NoArgumentUnused, CoreOption]>,
58975903
HelpText<"SYCL language standard to compile for.">,
58985904
Values<"2020,2017,121,1.2.1,sycl-1.2.1">,
5899-
NormalizedValues<["SYCL_2020", "SYCL_2017", "SYCL_2017", "SYCL_2017", "SYCL_2017"]>,
5900-
NormalizedValuesScope<"LangOptions">,
5901-
MarshallingInfoEnum<LangOpts<"SYCLVersion">, "SYCL_None">,
59025905
ShouldParseIf<!strconcat(fsycl_is_device.KeyPath, "||", fsycl_is_host.KeyPath)>;
59035906

59045907
def fsycl_default_sub_group_size

clang/include/clang/Sema/Sema.h

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ class SYCLIntegrationHeader {
322322
};
323323

324324
public:
325-
SYCLIntegrationHeader(bool UnnamedLambdaSupport, Sema &S);
325+
SYCLIntegrationHeader(Sema &S);
326326

327327
/// Emits contents of the header into given stream.
328328
void emit(raw_ostream &Out);
@@ -334,8 +334,8 @@ class SYCLIntegrationHeader {
334334
/// Signals that subsequent parameter descriptor additions will go to
335335
/// the kernel with given name. Starts new kernel invocation descriptor.
336336
void startKernel(StringRef KernelName, QualType KernelNameType,
337-
StringRef KernelStableName, SourceLocation Loc,
338-
bool IsESIMD);
337+
StringRef KernelStableName, SourceLocation Loc, bool IsESIMD,
338+
bool IsUnnamedKernel);
339339

340340
/// Adds a kernel parameter descriptor to current kernel invocation
341341
/// descriptor.
@@ -375,10 +375,10 @@ class SYCLIntegrationHeader {
375375
// there are four free functions the kernel may call (this_id, this_item,
376376
// this_nd_item, this_group)
377377
struct KernelCallsSYCLFreeFunction {
378-
bool CallsThisId;
379-
bool CallsThisItem;
380-
bool CallsThisNDItem;
381-
bool CallsThisGroup;
378+
bool CallsThisId = false;
379+
bool CallsThisItem = false;
380+
bool CallsThisNDItem = false;
381+
bool CallsThisGroup = false;
382382
};
383383

384384
// Kernel invocation descriptor
@@ -404,7 +404,15 @@ class SYCLIntegrationHeader {
404404
// this_id(), etc)
405405
KernelCallsSYCLFreeFunction FreeFunctionCalls;
406406

407-
KernelDesc() = default;
407+
// If we are in unnamed kernel/lambda mode AND this is one that the user
408+
// hasn't provided an explicit name for.
409+
bool IsUnnamedKernel;
410+
411+
KernelDesc(StringRef Name, QualType NameType, StringRef StableName,
412+
SourceLocation KernelLoc, bool IsESIMD, bool IsUnnamedKernel)
413+
: Name(Name), NameType(NameType), StableName(StableName),
414+
KernelLocation(KernelLoc), IsESIMDKernel(IsESIMD),
415+
IsUnnamedKernel(IsUnnamedKernel) {}
408416
};
409417

410418
/// Returns the latest invocation descriptor started by
@@ -426,9 +434,6 @@ class SYCLIntegrationHeader {
426434
/// integration header emission time.
427435
llvm::SmallVector<SpecConstID, 4> SpecConsts;
428436

429-
/// Whether header is generated with unnamed lambda support
430-
bool UnnamedLambdaSupport;
431-
432437
Sema &S;
433438
};
434439

@@ -13293,8 +13298,7 @@ class Sema final {
1329313298
/// Lazily creates and returns SYCL integration header instance.
1329413299
SYCLIntegrationHeader &getSyclIntegrationHeader() {
1329513300
if (SyclIntHeader == nullptr)
13296-
SyclIntHeader = std::make_unique<SYCLIntegrationHeader>(
13297-
getLangOpts().SYCLUnnamedLambda, *this);
13301+
SyclIntHeader = std::make_unique<SYCLIntegrationHeader>(*this);
1329813302
return *SyclIntHeader.get();
1329913303
}
1330013304

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4675,8 +4675,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
46754675
// Ensure the default version in SYCL mode is 2020.
46764676
CmdArgs.push_back("-sycl-std=2020");
46774677
}
4678-
if (Args.hasArg(options::OPT_fsycl_unnamed_lambda))
4679-
CmdArgs.push_back("-fsycl-unnamed-lambda");
4678+
4679+
if (!Args.hasFlag(options::OPT_fsycl_unnamed_lambda,
4680+
options::OPT_fno_sycl_unnamed_lambda))
4681+
CmdArgs.push_back("-fno-sycl-unnamed-lambda");
46804682

46814683
// Add the Unique ID prefix
46824684
StringRef UniqueID = D.getSYCLUniqueID(Input.getBaseInput());

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3546,6 +3546,20 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
35463546
case LangOptions::SubGroupSizeType::None:
35473547
break;
35483548
}
3549+
3550+
if (Opts.isSYCL()) {
3551+
switch (Opts.SYCLVersion) {
3552+
case LangOptions::SYCL_2017:
3553+
GenerateArg(Args, OPT_sycl_std_EQ, "2017", SA);
3554+
break;
3555+
case LangOptions::SYCL_2020:
3556+
GenerateArg(Args, OPT_sycl_std_EQ, "2020", SA);
3557+
break;
3558+
case LangOptions::SYCL_None:
3559+
// Do nothing, case where we were given an invalid value.
3560+
break;
3561+
}
3562+
}
35493563
}
35503564

35513565
bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
@@ -3637,6 +3651,28 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
36373651
LangStd = OpenCLLangStd;
36383652
}
36393653

3654+
// We have to parse this manually before the marshalling, otherwise we can't
3655+
// use the marshalling to set other flags based on the SYCL version.
3656+
if (Args.hasArg(OPT_fsycl_is_device) || Args.hasArg(OPT_fsycl_is_host)) {
3657+
if (const Arg *A = Args.getLastArg(OPT_sycl_std_EQ)) {
3658+
Opts.setSYCLVersion(
3659+
llvm::StringSwitch<LangOptions::SYCLMajorVersion>(A->getValue())
3660+
.Case("2020", LangOptions::SYCL_2020)
3661+
.Cases("2017", "121", "1.2.1", "sycl-1.2.1",
3662+
LangOptions::SYCL_2017)
3663+
.Default(LangOptions::SYCL_None));
3664+
3665+
if (Opts.SYCLVersion == LangOptions::SYCL_None)
3666+
Diags.Report(diag::err_drv_invalid_value)
3667+
<< A->getAsString(Args) << A->getValue();
3668+
} else {
3669+
// If the user supplied -fsycl-is-device or -fsycl-is-host, but failed to
3670+
// provide -sycl-std=, we want to default it to whatever the default SYCL
3671+
// version is.
3672+
Opts.setSYCLVersion(LangOptions::SYCL_Default);
3673+
}
3674+
}
3675+
36403676
// Parse SYCL Default Sub group size.
36413677
if (const Arg *A = Args.getLastArg(OPT_fsycl_default_sub_group_size)) {
36423678
StringRef Value = A->getValue();
@@ -3687,16 +3723,6 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
36873723
}
36883724
}
36893725

3690-
if ((Args.hasArg(OPT_fsycl_is_device) || Args.hasArg(OPT_fsycl_is_host)) &&
3691-
!Args.hasArg(OPT_sycl_std_EQ)) {
3692-
// If the user supplied -fsycl-is-device or -fsycl-is-host, but failed to
3693-
// provide -sycl-std=, we want to default it to whatever the default SYCL
3694-
// version is. I could not find a way to express this with the options
3695-
// tablegen because we still want this value to be SYCL_None when the user
3696-
// is not in device or host mode.
3697-
Opts.setSYCLVersion(LangOptions::SYCL_Default);
3698-
}
3699-
37003726
if (Opts.ObjC) {
37013727
if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
37023728
StringRef value = arg->getValue();

0 commit comments

Comments
 (0)