Skip to content

Commit 3fc6708

Browse files
authored
[FPGA][SYCL] Add support for memory attributes on device_global variables (#12785)
Currently we allow FPGA memory attributes on const variables. This patch relaxes the restriction that permits the attributes when applied on non-const device_global variables and updates the error message to properly convey which types of variables are allowed to have attributes. Also this patch relaxes the restriction that permits the private_copies attribute when applied on const variables. Previously we had restriction that the private_copies attribute would work with local non-const variables only. --------- Signed-off-by: Soumi Manna <soumi.manna@intel.com>
1 parent 19bb017 commit 3fc6708

File tree

6 files changed

+630
-66
lines changed

6 files changed

+630
-66
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,50 +2646,14 @@ def SYCLIntelEnableLoopPipelining : StmtAttr {
26462646
def : MutualExclusions<[SYCLIntelDisableLoopPipelining,
26472647
SYCLIntelEnableLoopPipelining]>;
26482648

2649-
def SYCLIntelLocalNonConstVar : SubsetSubject<Var,
2650-
[{S->hasLocalStorage() &&
2651-
S->getKind() != Decl::ImplicitParam &&
2652-
S->getKind() != Decl::ParmVar &&
2653-
S->getKind() != Decl::NonTypeTemplateParm &&
2654-
!S->getType().isConstQualified()}],
2655-
"local non-const variables">;
2656-
2657-
def SYCLIntelConstVar : SubsetSubject<Var,
2658-
[{S->getKind() != Decl::ImplicitParam &&
2659-
S->getKind() != Decl::ParmVar &&
2660-
S->getKind() != Decl::NonTypeTemplateParm &&
2661-
(S->getType().isConstQualified() ||
2662-
S->getType().getAddressSpace() ==
2663-
LangAS::opencl_constant)}],
2664-
"constant variables">;
2665-
2666-
def SYCLIntelLocalStaticAgentMemVar : SubsetSubject<Var,
2667-
[{S->getKind() != Decl::ImplicitParam &&
2668-
S->getKind() != Decl::NonTypeTemplateParm &&
2669-
(S->getStorageClass() == SC_Static ||
2670-
S->hasLocalStorage())}],
2671-
"local variables, static variables, agent memory arguments">;
2672-
2673-
def SYCLIntelLocalOrStaticVar : SubsetSubject<Var,
2674-
[{S->getKind() != Decl::ImplicitParam &&
2675-
S->getKind() != Decl::ParmVar &&
2676-
S->getKind() != Decl::NonTypeTemplateParm &&
2677-
(S->getStorageClass() == SC_Static ||
2678-
S->hasLocalStorage())}],
2679-
"local variables, static variables">;
2680-
26812649
def SYCLIntelDoublePump : Attr {
26822650
let Spellings = [CXX11<"intel", "doublepump">];
2683-
let Subjects = SubjectList<[SYCLIntelConstVar, SYCLIntelLocalOrStaticVar,
2684-
Field], ErrorDiag>;
26852651
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
26862652
let Documentation = [SYCLIntelDoublePumpAttrDocs];
26872653
}
26882654

26892655
def SYCLIntelSinglePump : Attr {
26902656
let Spellings = [CXX11<"intel", "singlepump">];
2691-
let Subjects = SubjectList<[SYCLIntelConstVar, SYCLIntelLocalOrStaticVar,
2692-
Field], ErrorDiag>;
26932657
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
26942658
let Documentation = [SYCLIntelSinglePumpAttrDocs];
26952659
}
@@ -2708,17 +2672,12 @@ def SYCLIntelMemory : Attr {
27082672
}
27092673
}
27102674
}];
2711-
let Subjects = SubjectList<[SYCLIntelConstVar,
2712-
SYCLIntelLocalStaticAgentMemVar,
2713-
Field], ErrorDiag>;
27142675
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
27152676
let Documentation = [SYCLIntelMemoryAttrDocs];
27162677
}
27172678

27182679
def SYCLIntelRegister : Attr {
27192680
let Spellings = [CXX11<"intel", "fpga_register">];
2720-
let Subjects = SubjectList<[SYCLIntelConstVar, SYCLIntelLocalOrStaticVar,
2721-
Field], ErrorDiag>;
27222681
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
27232682
let Documentation = [SYCLIntelRegisterAttrDocs];
27242683
}
@@ -2729,9 +2688,6 @@ def : MutualExclusions<[SYCLIntelDoublePump, SYCLIntelSinglePump,
27292688
def SYCLIntelBankWidth : InheritableAttr {
27302689
let Spellings = [CXX11<"intel", "bankwidth">];
27312690
let Args = [ExprArgument<"Value">];
2732-
let Subjects = SubjectList<[SYCLIntelConstVar,
2733-
SYCLIntelLocalStaticAgentMemVar,
2734-
Field], ErrorDiag>;
27352691
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
27362692
let Documentation = [SYCLIntelBankWidthAttrDocs];
27372693
}
@@ -2740,9 +2696,6 @@ def : MutualExclusions<[SYCLIntelRegister, SYCLIntelBankWidth]>;
27402696
def SYCLIntelNumBanks : InheritableAttr {
27412697
let Spellings = [CXX11<"intel", "numbanks">];
27422698
let Args = [ExprArgument<"Value">];
2743-
let Subjects = SubjectList<[SYCLIntelConstVar,
2744-
SYCLIntelLocalStaticAgentMemVar,
2745-
Field], ErrorDiag>;
27462699
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
27472700
let Documentation = [SYCLIntelNumBanksAttrDocs];
27482701
}
@@ -2751,7 +2704,6 @@ def SYCLIntelPrivateCopies : InheritableAttr {
27512704
let Spellings = [CXX11<"intel", "private_copies">];
27522705
let Args = [ExprArgument<"Value">];
27532706
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
2754-
let Subjects = SubjectList<[SYCLIntelLocalNonConstVar, Field], ErrorDiag>;
27552707
let Documentation = [SYCLIntelPrivateCopiesAttrDocs];
27562708
}
27572709
def : MutualExclusions<[SYCLIntelRegister, SYCLIntelPrivateCopies]>;
@@ -2760,8 +2712,6 @@ def : MutualExclusions<[SYCLIntelRegister, SYCLIntelPrivateCopies]>;
27602712
def SYCLIntelMerge : Attr {
27612713
let Spellings = [CXX11<"intel", "merge">];
27622714
let Args = [StringArgument<"Name">, StringArgument<"Direction">];
2763-
let Subjects = SubjectList<[SYCLIntelConstVar, SYCLIntelLocalOrStaticVar,
2764-
Field], ErrorDiag>;
27652715
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
27662716
let Documentation = [SYCLIntelMergeAttrDocs];
27672717
}
@@ -2770,19 +2720,13 @@ def : MutualExclusions<[SYCLIntelRegister, SYCLIntelMerge]>;
27702720
def SYCLIntelMaxReplicates : InheritableAttr {
27712721
let Spellings = [CXX11<"intel", "max_replicates">];
27722722
let Args = [ExprArgument<"Value">];
2773-
let Subjects = SubjectList<[SYCLIntelConstVar,
2774-
SYCLIntelLocalStaticAgentMemVar,
2775-
Field], ErrorDiag>;
27762723
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
27772724
let Documentation = [SYCLIntelMaxReplicatesAttrDocs];
27782725
}
27792726
def : MutualExclusions<[SYCLIntelRegister, SYCLIntelMaxReplicates]>;
27802727

27812728
def SYCLIntelSimpleDualPort : Attr {
27822729
let Spellings = [CXX11<"intel", "simple_dual_port">];
2783-
let Subjects = SubjectList<[SYCLIntelConstVar,
2784-
SYCLIntelLocalStaticAgentMemVar,
2785-
Field], ErrorDiag>;
27862730
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
27872731
let Documentation = [SYCLIntelSimpleDualPortAttrDocs];
27882732
}
@@ -2807,9 +2751,6 @@ def SYCLIntelPipeIO : InheritableAttr {
28072751
def SYCLIntelBankBits : Attr {
28082752
let Spellings = [CXX11<"intel", "bank_bits">];
28092753
let Args = [VariadicExprArgument<"Args">];
2810-
let Subjects = SubjectList<[SYCLIntelConstVar,
2811-
SYCLIntelLocalStaticAgentMemVar,
2812-
Field], ErrorDiag>;
28132754
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
28142755
let Documentation = [SYCLIntelBankBitsDocs];
28152756
}
@@ -2819,9 +2760,6 @@ def : MutualExclusions<[SYCLIntelRegister, SYCLIntelNumBanks]>;
28192760
def SYCLIntelForcePow2Depth : InheritableAttr {
28202761
let Spellings = [CXX11<"intel", "force_pow2_depth">];
28212762
let Args = [ExprArgument<"Value">];
2822-
let Subjects = SubjectList<[SYCLIntelConstVar,
2823-
SYCLIntelLocalStaticAgentMemVar,
2824-
Field], ErrorDiag>;
28252763
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
28262764
let Documentation = [SYCLIntelForcePow2DepthAttrDocs];
28272765
}

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12218,6 +12218,13 @@ def err_sycl_attribute_internal_decl
1221812218
"in an anonymous namespace">;
1221912219
def err_sycl_attribute_not_device_global
1222012220
: Error<"%0 attribute can only be applied to 'device_global' variables">;
12221+
def err_fpga_attribute_incorrect_variable
12222+
: Error<"%0 attribute only applies to constant variables, local variables, "
12223+
"static variables, %select{|agent memory arguments, }1non-static data "
12224+
"members and device_global variables">;
12225+
def err_fpga_attribute_invalid_decl
12226+
: Error<"%0 attribute only applies to const variables, local variables, "
12227+
"non-static data members and device_global variables">;
1222112228
def err_sycl_compiletime_property_duplication : Error<
1222212229
"can't apply %0 property twice to the same accessor">;
1222312230
def err_sycl_invalid_property_list_param_number : Error<

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7443,6 +7443,24 @@ static bool checkForDuplicateAttribute(Sema &S, Decl *D,
74437443
return false;
74447444
}
74457445

7446+
// Checks if FPGA memory attributes apply on valid variables.
7447+
// Returns true if an error occured.
7448+
static bool CheckValidFPGAMemoryAttributesVar(Sema &S, Decl *D) {
7449+
if (const auto *VD = dyn_cast<VarDecl>(D)) {
7450+
if (!(isa<FieldDecl>(D) ||
7451+
(VD->getKind() != Decl::ImplicitParam &&
7452+
VD->getKind() != Decl::NonTypeTemplateParm &&
7453+
(S.isTypeDecoratedWithDeclAttribute<SYCLDeviceGlobalAttr>(
7454+
VD->getType()) ||
7455+
VD->getType().isConstQualified() ||
7456+
VD->getType().getAddressSpace() == LangAS::opencl_constant ||
7457+
VD->getStorageClass() == SC_Static || VD->hasLocalStorage())))) {
7458+
return true;
7459+
}
7460+
}
7461+
return false;
7462+
}
7463+
74467464
void Sema::AddSYCLIntelNoGlobalWorkOffsetAttr(Decl *D,
74477465
const AttributeCommonInfo &CI,
74487466
Expr *E) {
@@ -7521,6 +7539,15 @@ static void handleSYCLIntelSinglePumpAttr(Sema &S, Decl *D,
75217539
}
75227540
}
75237541

7542+
// Check attribute applies to field, constant variables, local variables,
7543+
// static variables, non-static data members, and device_global variables.
7544+
if ((D->getKind() == Decl::ParmVar) ||
7545+
CheckValidFPGAMemoryAttributesVar(S, D)) {
7546+
S.Diag(AL.getLoc(), diag::err_fpga_attribute_incorrect_variable)
7547+
<< AL << /*agent memory arguments*/ 0;
7548+
return;
7549+
}
7550+
75247551
// If the declaration does not have an [[intel::fpga_memory]]
75257552
// attribute, this creates one as an implicit attribute.
75267553
if (!D->hasAttr<SYCLIntelMemoryAttr>())
@@ -7544,6 +7571,15 @@ static void handleSYCLIntelDoublePumpAttr(Sema &S, Decl *D,
75447571
}
75457572
}
75467573

7574+
// Check attribute applies to field, constant variables, local variables,
7575+
// static variables, non-static data members, and device_global variables.
7576+
if ((D->getKind() == Decl::ParmVar) ||
7577+
CheckValidFPGAMemoryAttributesVar(S, D)) {
7578+
S.Diag(AL.getLoc(), diag::err_fpga_attribute_incorrect_variable)
7579+
<< AL << /*agent memory arguments*/ 0;
7580+
return;
7581+
}
7582+
75477583
// If the declaration does not have an [[intel::fpga_memory]]
75487584
// attribute, this creates one as an implicit attribute.
75497585
if (!D->hasAttr<SYCLIntelMemoryAttr>())
@@ -7591,6 +7627,15 @@ static void handleSYCLIntelMemoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
75917627
D->dropAttr<SYCLIntelMemoryAttr>();
75927628
}
75937629

7630+
// Check attribute applies to field, constant variables, local variables,
7631+
// static variables, agent memory arguments, non-static data members,
7632+
// and device_global variables.
7633+
if (CheckValidFPGAMemoryAttributesVar(S, D)) {
7634+
S.Diag(AL.getLoc(), diag::err_fpga_attribute_incorrect_variable)
7635+
<< AL << /*agent memory arguments*/ 1;
7636+
return;
7637+
}
7638+
75947639
D->addAttr(::new (S.Context) SYCLIntelMemoryAttr(S.Context, AL, Kind));
75957640
}
75967641

@@ -7623,6 +7668,15 @@ static void handleSYCLIntelRegisterAttr(Sema &S, Decl *D,
76237668
}
76247669
}
76257670

7671+
// Check attribute applies to field, constant variables, local variables,
7672+
// static variables, non-static data members, and device_global variables.
7673+
if ((D->getKind() == Decl::ParmVar) ||
7674+
CheckValidFPGAMemoryAttributesVar(S, D)) {
7675+
S.Diag(A.getLoc(), diag::err_fpga_attribute_incorrect_variable)
7676+
<< A << /*agent memory arguments*/ 0;
7677+
return;
7678+
}
7679+
76267680
if (checkIntelFPGARegisterAttrCompatibility(S, D, A))
76277681
return;
76287682

@@ -7661,6 +7715,15 @@ void Sema::AddSYCLIntelBankWidthAttr(Decl *D, const AttributeCommonInfo &CI,
76617715
return;
76627716
}
76637717

7718+
// Check attribute applies to field, constant variables, local variables,
7719+
// static variables, agent memory arguments, non-static data members,
7720+
// and device_global variables.
7721+
if (CheckValidFPGAMemoryAttributesVar(*this, D)) {
7722+
Diag(CI.getLoc(), diag::err_fpga_attribute_incorrect_variable)
7723+
<< CI << /*agent memory arguments*/ 1;
7724+
return;
7725+
}
7726+
76647727
// Check to see if there's a duplicate attribute with different values
76657728
// already applied to the declaration.
76667729
if (const auto *DeclAttr = D->getAttr<SYCLIntelBankWidthAttr>()) {
@@ -7745,6 +7808,15 @@ void Sema::AddSYCLIntelNumBanksAttr(Decl *D, const AttributeCommonInfo &CI,
77457808
}
77467809
}
77477810

7811+
// Check attribute applies to constant variables, local variables,
7812+
// static variables, agent memory arguments, non-static data members,
7813+
// and device_global variables.
7814+
if (CheckValidFPGAMemoryAttributesVar(*this, D)) {
7815+
Diag(CI.getLoc(), diag::err_fpga_attribute_incorrect_variable)
7816+
<< CI << /*agent memory arguments*/ 1;
7817+
return;
7818+
}
7819+
77487820
// Check to see if there's a duplicate attribute with different values
77497821
// already applied to the declaration.
77507822
if (const auto *DeclAttr = D->getAttr<SYCLIntelNumBanksAttr>()) {
@@ -7812,6 +7884,15 @@ static void handleIntelSimpleDualPortAttr(Sema &S, Decl *D,
78127884
}
78137885
}
78147886

7887+
// Check attribute applies to field, constant variables, local variables,
7888+
// static variables, agent memory arguments, non-static data members,
7889+
// and device_global variables.
7890+
if (CheckValidFPGAMemoryAttributesVar(S, D)) {
7891+
S.Diag(AL.getLoc(), diag::err_fpga_attribute_incorrect_variable)
7892+
<< AL << /*agent memory arguments*/ 1;
7893+
return;
7894+
}
7895+
78157896
if (!D->hasAttr<SYCLIntelMemoryAttr>())
78167897
D->addAttr(SYCLIntelMemoryAttr::CreateImplicit(
78177898
S.Context, SYCLIntelMemoryAttr::Default));
@@ -7837,6 +7918,16 @@ void Sema::AddSYCLIntelMaxReplicatesAttr(Decl *D, const AttributeCommonInfo &CI,
78377918
<< CI << /*positive*/ 0;
78387919
return;
78397920
}
7921+
7922+
// Check attribute applies to field, constant variables, local variables,
7923+
// static variables, agent memory arguments, non-static data members,
7924+
// and device_global variables.
7925+
if (CheckValidFPGAMemoryAttributesVar(*this, D)) {
7926+
Diag(CI.getLoc(), diag::err_fpga_attribute_incorrect_variable)
7927+
<< CI << /*agent memory arguments*/ 1;
7928+
return;
7929+
}
7930+
78407931
// Check to see if there's a duplicate attribute with different values
78417932
// already applied to the declaration.
78427933
if (const auto *DeclAttr = D->getAttr<SYCLIntelMaxReplicatesAttr>()) {
@@ -7920,6 +8011,15 @@ static void handleSYCLIntelMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
79208011
return;
79218012
}
79228013

8014+
// Check attribute applies to field, constant variables, local variables,
8015+
// static variables, non-static data members, and device_global variables.
8016+
if ((D->getKind() == Decl::ParmVar) ||
8017+
CheckValidFPGAMemoryAttributesVar(S, D)) {
8018+
S.Diag(AL.getLoc(), diag::err_fpga_attribute_incorrect_variable)
8019+
<< AL << /*agent memory arguments*/ 0;
8020+
return;
8021+
}
8022+
79238023
if (!D->hasAttr<SYCLIntelMemoryAttr>())
79248024
D->addAttr(SYCLIntelMemoryAttr::CreateImplicit(
79258025
S.Context, SYCLIntelMemoryAttr::Default));
@@ -8005,6 +8105,15 @@ void Sema::AddSYCLIntelBankBitsAttr(Decl *D, const AttributeCommonInfo &CI,
80058105
D->addAttr(SYCLIntelNumBanksAttr::CreateImplicit(Context, NBE));
80068106
}
80078107

8108+
// Check attribute applies to field, constant variables, local variables,
8109+
// static variables, agent memory arguments, non-static data members,
8110+
// and device_global variables.
8111+
if (CheckValidFPGAMemoryAttributesVar(*this, D)) {
8112+
Diag(CI.getLoc(), diag::err_fpga_attribute_incorrect_variable)
8113+
<< CI << /*agent memory arguments*/ 1;
8114+
return;
8115+
}
8116+
80088117
if (!D->hasAttr<SYCLIntelMemoryAttr>())
80098118
D->addAttr(SYCLIntelMemoryAttr::CreateImplicit(
80108119
Context, SYCLIntelMemoryAttr::Default));
@@ -8030,6 +8139,22 @@ void Sema::AddSYCLIntelPrivateCopiesAttr(Decl *D, const AttributeCommonInfo &CI,
80308139
<< CI << /*non-negative*/ 1;
80318140
return;
80328141
}
8142+
8143+
// Check attribute applies to field as well as const variables, non-static
8144+
// local variables, non-static data members, and device_global variables.
8145+
if (const auto *VD = dyn_cast<VarDecl>(D)) {
8146+
if (!(isa<FieldDecl>(D) ||
8147+
(VD->getKind() != Decl::ImplicitParam &&
8148+
VD->getKind() != Decl::NonTypeTemplateParm &&
8149+
VD->getKind() != Decl::ParmVar &&
8150+
(VD->hasLocalStorage() ||
8151+
isTypeDecoratedWithDeclAttribute<SYCLDeviceGlobalAttr>(
8152+
VD->getType()))))) {
8153+
Diag(CI.getLoc(), diag::err_fpga_attribute_invalid_decl) << CI;
8154+
return;
8155+
}
8156+
}
8157+
80338158
// Check to see if there's a duplicate attribute with different values
80348159
// already applied to the declaration.
80358160
if (const auto *DeclAttr = D->getAttr<SYCLIntelPrivateCopiesAttr>()) {
@@ -8080,6 +8205,15 @@ void Sema::AddSYCLIntelForcePow2DepthAttr(Decl *D,
80808205
return;
80818206
}
80828207

8208+
// Check attribute applies to field, constant variables, local variables,
8209+
// static variables, agent memory arguments, non-static data members,
8210+
// and device_global variables.
8211+
if (CheckValidFPGAMemoryAttributesVar(*this, D)) {
8212+
Diag(CI.getLoc(), diag::err_fpga_attribute_incorrect_variable)
8213+
<< CI << /*agent memory arguments*/ 1;
8214+
return;
8215+
}
8216+
80838217
// Check to see if there's a duplicate attribute with different values
80848218
// already applied to the declaration.
80858219
if (const auto *DeclAttr = D->getAttr<SYCLIntelForcePow2DepthAttr>()) {

0 commit comments

Comments
 (0)