Skip to content

Commit 6c296c3

Browse files
author
Alexander Batashev
committed
Merge remote-tracking branch 'upstream/sycl' into postcommit_abi
* upstream/sycl: [SYCL] Fix broken build after introduction USM to ocl headers (intel#1852) [SYCL][ESIMD] Implement "private globals" (file scope private vars) in FE (intel#1756) [SYCL] Introduce interop handle for host task (intel#1747)
2 parents 381d263 + 4a8c432 commit 6c296c3

19 files changed

+324
-199
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,19 @@ def SYCLKernel : InheritableAttr {
11351135
let Documentation = [SYCLKernelDocs];
11361136
}
11371137

1138+
// Available in SYCL explicit SIMD extension. Binds a file scope private
1139+
// variable to a specific register.
1140+
def SYCLRegisterNum : InheritableAttr {
1141+
let Spellings = [GNU<"register_num">, Declspec<"register_num">];
1142+
let Args = [UnsignedArgument<"Number">];
1143+
let Subjects = SubjectList<[GlobalVar]>;
1144+
// This attribute is applied to file-scope variables and must be compilable
1145+
// for the host device as well
1146+
let LangOpts = [SYCLExplicitSIMD];
1147+
let Documentation = [SYCLRegisterNumDocs];
1148+
let PragmaAttributeSupport = 0;
1149+
}
1150+
11381151
def SYCLScope : Attr {
11391152
// No spelling, as this attribute can't be created in the source code.
11401153
let Spellings = [];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,17 @@ The SYCL kernel in the previous code sample meets these expectations.
330330
}];
331331
}
332332

333+
def SYCLRegisterNumDocs : Documentation {
334+
let Category = DocCatVariable;
335+
let Content = [{
336+
The ``__attribute__((register_num(n)))`` attribute can be used to bind
337+
"private globals" (SYCL private address space variables declared in the file
338+
scope) to a particular register with number 'n'. Actual mapping of registers
339+
to numbers is target-specific. For Intel GPUs 'n' is a byte offset in the
340+
GRF.
341+
}];
342+
}
343+
333344
def C11NoReturnDocs : Documentation {
334345
let Category = DocCatFunction;
335346
let Content = [{

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10890,4 +10890,6 @@ def err_ext_int_bad_size : Error<"%select{signed|unsigned}0 _ExtInt must "
1089010890
"have a bit size of at least %select{2|1}0">;
1089110891
def err_ext_int_max_size : Error<"%select{signed|unsigned}0 _ExtInt of bit "
1089210892
"sizes greater than %1 not supported">;
10893+
def err_esimd_glob_cant_init : Error<
10894+
"SYCL explicit SIMD does not permit private global variable to have an initializer">;
1089310895
} // end of sema component.

clang/include/clang/Sema/Sema.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12664,6 +12664,14 @@ class Sema final {
1266412664
void finalizeSYCLDelayedAnalysis(const FunctionDecl *Caller,
1266512665
const FunctionDecl *Callee,
1266612666
SourceLocation Loc);
12667+
12668+
/// Tells whether given variable is a SYCL explicit SIMD extension's "private
12669+
/// global" variable - global variable in the private address space.
12670+
bool isSYCLEsimdPrivateGlobal(VarDecl *VDecl) {
12671+
return getLangOpts().SYCLIsDevice && getLangOpts().SYCLExplicitSIMD &&
12672+
VDecl->hasGlobalStorage() &&
12673+
(VDecl->getType().getAddressSpace() != LangAS::opencl_constant);
12674+
}
1266712675
};
1266812676

1266912677
template <typename AttrType>

clang/lib/CodeGen/CGSYCLRuntime.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,11 @@ static bool isPFWI(const FunctionDecl &FD) {
5050
return FD.getName() == "parallel_for_work_item";
5151
}
5252

53-
const char *WG_SCOPE_MD_ID = "work_group_scope";
54-
const char *WI_SCOPE_MD_ID = "work_item_scope";
55-
const char *PFWI_MD_ID = "parallel_for_work_item";
53+
constexpr char WG_SCOPE_MD_ID[] = "work_group_scope";
54+
constexpr char WI_SCOPE_MD_ID[] = "work_item_scope";
55+
constexpr char PFWI_MD_ID[] = "parallel_for_work_item";
56+
constexpr char ATTR_GENX_VOLATILE[] = "genx_volatile";
57+
constexpr char ATTR_GENX_BYTE_OFFSET[] = "genx_byte_offset";
5658

5759
} // anonymous namespace
5860

@@ -101,6 +103,19 @@ bool CGSYCLRuntime::actOnAutoVarEmit(CodeGenFunction &CGF, const VarDecl &D,
101103
return true;
102104
}
103105

106+
bool CGSYCLRuntime::actOnGlobalVarEmit(CodeGenModule &CGM, const VarDecl &D,
107+
llvm::Value *Addr) {
108+
SYCLRegisterNumAttr *RegAttr = D.getAttr<SYCLRegisterNumAttr>();
109+
if (!RegAttr)
110+
return false;
111+
auto *GlobVar = cast<llvm::GlobalVariable>(Addr);
112+
GlobVar->addAttribute(ATTR_GENX_VOLATILE);
113+
GlobVar->addAttribute(ATTR_GENX_BYTE_OFFSET,
114+
Twine(RegAttr->getNumber()).str());
115+
// TODO consider reversing the error/success return values
116+
return true;
117+
}
118+
104119
bool Util::matchQualifiedTypeName(const CXXRecordDecl *RecTy,
105120
ArrayRef<Util::DeclContextDesc> Scopes) {
106121
// The idea: check the declaration context chain starting from the type

clang/lib/CodeGen/CGSYCLRuntime.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class CGSYCLRuntime {
3434
void emitWorkGroupLocalVarDecl(CodeGenFunction &CGF, const VarDecl &D);
3535
bool actOnAutoVarEmit(CodeGenFunction &CGF, const VarDecl &D,
3636
llvm::Value *Addr);
37+
bool actOnGlobalVarEmit(CodeGenModule &CGM, const VarDecl &D,
38+
llvm::Value *Addr);
3739
};
3840

3941
} // namespace CodeGen

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4416,8 +4416,12 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
44164416
if (getCodeGenOpts().hasReducedDebugInfo())
44174417
DI->EmitGlobalVariable(GV, D);
44184418

4419-
if (LangOpts.SYCLIsDevice)
4419+
if (LangOpts.SYCLIsDevice) {
44204420
maybeEmitPipeStorageMetadata(D, GV, *this);
4421+
// Notify SYCL code generation infrastructure that a global variable is
4422+
// being generated.
4423+
getSYCLRuntime().actOnGlobalVarEmit(*this, *D, GV);
4424+
}
44214425
}
44224426

44234427
void CodeGenModule::EmitExternalVarDeclaration(const VarDecl *D) {

clang/lib/Sema/SemaDecl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11979,6 +11979,13 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
1197911979
VDecl->setInvalidDecl();
1198011980
return;
1198111981
}
11982+
// In the SYCL explicit SIMD extension non constant "private globals" can't
11983+
// be explicitly initialized in the declaration.
11984+
if (isSYCLEsimdPrivateGlobal(VDecl)) {
11985+
Diag(VDecl->getLocation(), diag::err_esimd_glob_cant_init);
11986+
VDecl->setInvalidDecl();
11987+
return;
11988+
}
1198211989

1198311990
// The LoaderUninitialized attribute acts as a definition (of undef).
1198411991
if (VDecl->hasAttr<LoaderUninitializedAttr>()) {
@@ -12578,6 +12585,11 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
1257812585
if (getLangOpts().OpenCL &&
1257912586
Var->getType().getAddressSpace() == LangAS::opencl_local)
1258012587
return;
12588+
// In SYCL explicit SIMD extension "private global" variables can't be
12589+
// initialized even implicitly, so don't synthesize an implicit initializer.
12590+
if (isSYCLEsimdPrivateGlobal(Var))
12591+
return;
12592+
1258112593
// C++03 [dcl.init]p9:
1258212594
// If no initializer is specified for an object, and the
1258312595
// object is of (possibly cv-qualified) non-POD class type (or

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4511,6 +4511,22 @@ static void handleSYCLDeviceIndirectlyCallableAttr(Sema &S, Decl *D,
45114511
handleSimpleAttribute<SYCLDeviceIndirectlyCallableAttr>(S, D, AL);
45124512
}
45134513

4514+
static void handleSYCLRegisterNumAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4515+
auto *VD = cast<VarDecl>(D);
4516+
if (!VD->hasGlobalStorage()) {
4517+
S.Diag(AL.getLoc(), diag::err_sycl_attibute_cannot_be_applied_here)
4518+
<< AL << 0;
4519+
return;
4520+
}
4521+
if (!checkAttributeNumArgs(S, AL, 1))
4522+
return;
4523+
uint32_t RegNo = 0;
4524+
const Expr *E = AL.getArgAsExpr(0);
4525+
if (!checkUInt32Argument(S, AL, E, RegNo, 0, /*StrictlyUnsigned=*/true))
4526+
return;
4527+
D->addAttr(::new (S.Context) SYCLRegisterNumAttr(S.Context, AL, RegNo));
4528+
}
4529+
45144530
static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
45154531
if (checkAttrMutualExclusion<CUDASharedAttr>(S, D, AL))
45164532
return;
@@ -7550,6 +7566,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
75507566
case ParsedAttr::AT_SYCLDeviceIndirectlyCallable:
75517567
handleSYCLDeviceIndirectlyCallableAttr(S, D, AL);
75527568
break;
7569+
case ParsedAttr::AT_SYCLRegisterNum:
7570+
handleSYCLRegisterNumAttr(S, D, AL);
7571+
break;
75537572
case ParsedAttr::AT_Format:
75547573
handleFormatAttr(S, D, AL);
75557574
break;

clang/lib/Sema/SemaExpr.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,9 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
221221
if (!IsConst && VD->getStorageClass() == SC_Static)
222222
SYCLDiagIfDeviceCode(*Locs.begin(), diag::err_sycl_restrict)
223223
<< Sema::KernelNonConstStaticDataVariable;
224-
else if (!IsConst && VD->hasGlobalStorage() && !isa<ParmVarDecl>(VD))
224+
// Non-const globals are allowed for SYCL explicit SIMD.
225+
else if (!isSYCLEsimdPrivateGlobal(VD) && !IsConst &&
226+
VD->hasGlobalStorage() && !isa<ParmVarDecl>(VD))
225227
SYCLDiagIfDeviceCode(*Locs.begin(), diag::err_sycl_restrict)
226228
<< Sema::KernelGlobalVariable;
227229
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang_cc1 -disable-llvm-passes -triple spir64-unknown-unknown-sycldevice \
2+
// RUN: -fsycl -fsycl-is-device -fsycl-explicit-simd -emit-llvm %s -o - | \
3+
// RUN: FileCheck %s
4+
5+
// This test checks that FE allows globals with register_num attribute in ESIMD mode.
6+
7+
__attribute__((opencl_private)) __attribute__((register_num(17))) int vc;
8+
// CHECK: @vc = {{.+}} i32 0, align 4 #0
9+
10+
SYCL_EXTERNAL void init_vc(int x) {
11+
vc = x;
12+
// CHECK: store i32 %0, i32* @vc
13+
}
14+
// CHECK: attributes #0 = { "genx_byte_offset"="17" "genx_volatile" }
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsycl-explicit-simd -fsyntax-only -verify -pedantic %s
2+
3+
// no error expected
4+
__attribute__((opencl_private)) __attribute__((register_num(17))) int privGlob;
5+
6+
// expected-error@+1{{'register_num' attribute takes one argument}}
7+
__attribute__((opencl_private)) __attribute__((register_num())) int privGlob1;
8+
9+
// expected-error@+1{{'register_num' attribute takes one argument}}
10+
__attribute__((opencl_private)) __attribute__((register_num(10, 11))) int privGlob2;
11+
12+
// expected-error@+1{{SYCL explicit SIMD does not permit private global variable to have an initializer}}
13+
__attribute__((opencl_private)) int privGlob3 = 10;
14+
15+
void foo() {
16+
// expected-warning@+1{{'register_num' attribute only applies to global variables}}
17+
__attribute__((register_num(17))) int privLoc;
18+
}

0 commit comments

Comments
 (0)