Skip to content

Commit a504f72

Browse files
authored
[SYCL] Let tablegen handle mutually exclusive decl attrs (#3507)
The new MutualExclusions tablegen facilities allow us to remove a bunch of custom diagnostic checking code. This also fixes an issue with the upstream implementation of the MutualExclusions facilities for DeclOrStmtAttr attributes.
1 parent 5e33df3 commit a504f72

File tree

5 files changed

+27
-99
lines changed

5 files changed

+27
-99
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,6 +1950,8 @@ def SYCLIntelFPGADisableLoopPipelining : DeclOrStmtAttr {
19501950
let Documentation = [SYCLIntelFPGADisableLoopPipeliningAttrDocs];
19511951
let SupportsNonconformingLambdaSyntax = 1;
19521952
}
1953+
def : MutualExclusions<[SYCLIntelFPGAInitiationInterval,
1954+
SYCLIntelFPGADisableLoopPipelining]>;
19531955

19541956
def SYCLIntelFPGAMaxInterleaving : StmtAttr {
19551957
let Spellings = [CXX11<"intelfpga","max_interleaving">,
@@ -2061,6 +2063,8 @@ def IntelFPGARegister : Attr {
20612063
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
20622064
let Documentation = [IntelFPGARegisterAttrDocs];
20632065
}
2066+
def : MutualExclusions<[IntelFPGADoublePump, IntelFPGASinglePump,
2067+
IntelFPGARegister]>;
20642068

20652069
// One integral argument.
20662070
def IntelFPGABankWidth : Attr {
@@ -2072,6 +2076,7 @@ def IntelFPGABankWidth : Attr {
20722076
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
20732077
let Documentation = [IntelFPGABankWidthAttrDocs];
20742078
}
2079+
def : MutualExclusions<[IntelFPGARegister, IntelFPGABankWidth]>;
20752080

20762081
def IntelFPGANumBanks : Attr {
20772082
let Spellings = [CXX11<"intelfpga","numbanks">,
@@ -2091,6 +2096,7 @@ def IntelFPGAPrivateCopies : InheritableAttr {
20912096
let Subjects = SubjectList<[IntelFPGALocalNonConstVar, Field], ErrorDiag>;
20922097
let Documentation = [IntelFPGAPrivateCopiesAttrDocs];
20932098
}
2099+
def : MutualExclusions<[IntelFPGARegister, IntelFPGAPrivateCopies]>;
20942100

20952101
// Two string arguments.
20962102
def IntelFPGAMerge : Attr {
@@ -2102,6 +2108,7 @@ def IntelFPGAMerge : Attr {
21022108
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
21032109
let Documentation = [IntelFPGAMergeAttrDocs];
21042110
}
2111+
def : MutualExclusions<[IntelFPGARegister, IntelFPGAMerge]>;
21052112

21062113
def IntelFPGAMaxReplicates : InheritableAttr {
21072114
let Spellings = [CXX11<"intelfpga","max_replicates">,
@@ -2112,6 +2119,7 @@ def IntelFPGAMaxReplicates : InheritableAttr {
21122119
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
21132120
let Documentation = [IntelFPGAMaxReplicatesAttrDocs];
21142121
}
2122+
def : MutualExclusions<[IntelFPGARegister, IntelFPGAMaxReplicates]>;
21152123

21162124
def IntelFPGASimpleDualPort : Attr {
21172125
let Spellings = [CXX11<"intelfpga","simple_dual_port">,
@@ -2121,6 +2129,7 @@ def IntelFPGASimpleDualPort : Attr {
21212129
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
21222130
let Documentation = [IntelFPGASimpleDualPortAttrDocs];
21232131
}
2132+
def : MutualExclusions<[IntelFPGARegister, IntelFPGASimpleDualPort]>;
21242133

21252134
def SYCLFPGAPipe : TypeAttr {
21262135
let Spellings = [GNU<"pipe">];
@@ -2147,6 +2156,7 @@ def IntelFPGABankBits : Attr {
21472156
let LangOpts = [SYCLIsDevice, SYCLIsHost];
21482157
let Documentation = [IntelFPGABankBitsDocs];
21492158
}
2159+
def : MutualExclusions<[IntelFPGARegister, IntelFPGABankBits]>;
21502160

21512161
def IntelFPGAForcePow2Depth : InheritableAttr {
21522162
let Spellings = [CXX11<"intelfpga","force_pow2_depth">,
@@ -2157,6 +2167,7 @@ def IntelFPGAForcePow2Depth : InheritableAttr {
21572167
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
21582168
let Documentation = [IntelFPGAForcePow2DepthAttrDocs];
21592169
}
2170+
def : MutualExclusions<[IntelFPGARegister, IntelFPGAForcePow2Depth]>;
21602171

21612172
def Naked : InheritableAttr {
21622173
let Spellings = [GCC<"naked">, Declspec<"naked">];

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 5 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -3307,12 +3307,6 @@ static void handleUseStallEnableClustersAttr(Sema &S, Decl *D,
33073307
static void handleSYCLIntelFPGADisableLoopPipeliningAttr(Sema &S, Decl *D,
33083308
const ParsedAttr &A) {
33093309
S.CheckDeprecatedSYCLAttributeSpelling(A);
3310-
3311-
// [[intel::disable_loop_pipelining] and [[intel::initiation_interval()]]
3312-
// attributes are incompatible.
3313-
if (checkAttrMutualExclusion<SYCLIntelFPGAInitiationIntervalAttr>(S, D, A))
3314-
return;
3315-
33163310
D->addAttr(::new (S.Context)
33173311
SYCLIntelFPGADisableLoopPipeliningAttr(S.Context, A));
33183312
}
@@ -3355,12 +3349,6 @@ void Sema::AddSYCLIntelFPGAInitiationIntervalAttr(Decl *D,
33553349
}
33563350
}
33573351

3358-
// [[intel::disable_loop_pipelining] and [[intel::initiation_interval()]]
3359-
// attributes are incompatible.
3360-
if (checkAttrMutualExclusion<SYCLIntelFPGADisableLoopPipeliningAttr>(*this, D,
3361-
CI))
3362-
return;
3363-
33643352
D->addAttr(::new (Context)
33653353
SYCLIntelFPGAInitiationIntervalAttr(Context, CI, E));
33663354
}
@@ -3385,12 +3373,6 @@ Sema::MergeSYCLIntelFPGAInitiationIntervalAttr(
33853373
}
33863374
}
33873375

3388-
// [[intel::initiation_interval()]] and [[intel::disable_loop_pipelining]
3389-
// attributes are incompatible.
3390-
if (checkAttrMutualExclusion<SYCLIntelFPGADisableLoopPipeliningAttr>(*this, D,
3391-
A))
3392-
return nullptr;
3393-
33943376
return ::new (Context)
33953377
SYCLIntelFPGAInitiationIntervalAttr(Context, A, A.getIntervalExpr());
33963378
}
@@ -5802,17 +5784,11 @@ static void handleSYCLIntelNoGlobalWorkOffsetAttr(Sema &S, Decl *D,
58025784
S.AddSYCLIntelNoGlobalWorkOffsetAttr(D, A, E);
58035785
}
58045786

5805-
/// Handle the [[intelfpga::doublepump]] and [[intelfpga::singlepump]] attributes.
5806-
/// One but not both can be specified
5807-
/// Both are incompatible with the __register__ attribute.
5808-
template <typename AttrType, typename IncompatAttrType>
5787+
/// Handle the [[intelfpga::doublepump]] and [[intelfpga::singlepump]]
5788+
/// attributes.
5789+
template <typename AttrType>
58095790
static void handleIntelFPGAPumpAttr(Sema &S, Decl *D, const ParsedAttr &A) {
58105791
checkForDuplicateAttribute<AttrType>(S, D, A);
5811-
if (checkAttrMutualExclusion<IncompatAttrType>(S, D, A))
5812-
return;
5813-
5814-
if (checkAttrMutualExclusion<IntelFPGARegisterAttr>(S, D, A))
5815-
return;
58165792

58175793
if (!D->hasAttr<IntelFPGAMemoryAttr>())
58185794
D->addAttr(IntelFPGAMemoryAttr::CreateImplicit(
@@ -5867,28 +5843,10 @@ static bool checkIntelFPGARegisterAttrCompatibility(Sema &S, Decl *D,
58675843
if (!MA->isImplicit() &&
58685844
checkAttrMutualExclusion<IntelFPGAMemoryAttr>(S, D, Attr))
58695845
InCompat = true;
5870-
if (checkAttrMutualExclusion<IntelFPGADoublePumpAttr>(S, D, Attr))
5871-
InCompat = true;
5872-
if (checkAttrMutualExclusion<IntelFPGASinglePumpAttr>(S, D, Attr))
5873-
InCompat = true;
5874-
if (checkAttrMutualExclusion<IntelFPGABankWidthAttr>(S, D, Attr))
5875-
InCompat = true;
5876-
if (checkAttrMutualExclusion<IntelFPGAPrivateCopiesAttr>(S, D, Attr))
5877-
InCompat = true;
58785846
if (auto *NBA = D->getAttr<IntelFPGANumBanksAttr>())
58795847
if (!NBA->isImplicit() &&
58805848
checkAttrMutualExclusion<IntelFPGANumBanksAttr>(S, D, Attr))
58815849
InCompat = true;
5882-
if (checkAttrMutualExclusion<IntelFPGAMaxReplicatesAttr>(S, D, Attr))
5883-
InCompat = true;
5884-
if (checkAttrMutualExclusion<IntelFPGASimpleDualPortAttr>(S, D, Attr))
5885-
InCompat = true;
5886-
if (checkAttrMutualExclusion<IntelFPGAMergeAttr>(S, D, Attr))
5887-
InCompat = true;
5888-
if (checkAttrMutualExclusion<IntelFPGABankBitsAttr>(S, D, Attr))
5889-
InCompat = true;
5890-
if (checkAttrMutualExclusion<IntelFPGAForcePow2DepthAttr>(S, D, Attr))
5891-
InCompat = true;
58925850

58935851
return InCompat;
58945852
}
@@ -5926,9 +5884,6 @@ static void handleIntelFPGASimpleDualPortAttr(Sema &S, Decl *D,
59265884
const ParsedAttr &AL) {
59275885
checkForDuplicateAttribute<IntelFPGASimpleDualPortAttr>(S, D, AL);
59285886

5929-
if (checkAttrMutualExclusion<IntelFPGARegisterAttr>(S, D, AL))
5930-
return;
5931-
59325887
if (!D->hasAttr<IntelFPGAMemoryAttr>())
59335888
D->addAttr(IntelFPGAMemoryAttr::CreateImplicit(
59345889
S.Context, IntelFPGAMemoryAttr::Default));
@@ -5973,11 +5928,6 @@ void Sema::AddIntelFPGAMaxReplicatesAttr(Decl *D, const AttributeCommonInfo &CI,
59735928
}
59745929
}
59755930

5976-
// [[intel::fpga_register]] and [[intel::max_replicates()]]
5977-
// attributes are incompatible.
5978-
if (checkAttrMutualExclusion<IntelFPGARegisterAttr>(*this, D, CI))
5979-
return;
5980-
59815931
// If the declaration does not have an [[intel::fpga_memory]]
59825932
// attribute, this creates one as an implicit attribute.
59835933
if (!D->hasAttr<IntelFPGAMemoryAttr>())
@@ -6004,10 +5954,6 @@ Sema::MergeIntelFPGAMaxReplicatesAttr(Decl *D,
60045954
}
60055955
}
60065956
}
6007-
// [[intel::fpga_register]] and [[intel::max_replicates()]]
6008-
// attributes are incompatible.
6009-
if (checkAttrMutualExclusion<IntelFPGARegisterAttr>(*this, D, A))
6010-
return nullptr;
60115957

60125958
return ::new (Context) IntelFPGAMaxReplicatesAttr(Context, A, A.getValue());
60135959
}
@@ -6026,9 +5972,6 @@ static void handleIntelFPGAMaxReplicatesAttr(Sema &S, Decl *D,
60265972
static void handleIntelFPGAMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
60275973
checkForDuplicateAttribute<IntelFPGAMergeAttr>(S, D, AL);
60285974

6029-
if (checkAttrMutualExclusion<IntelFPGARegisterAttr>(S, D, AL))
6030-
return;
6031-
60325975
SmallVector<StringRef, 2> Results;
60335976
for (int I = 0; I < 2; I++) {
60345977
StringRef Str;
@@ -6066,9 +6009,6 @@ static void handleIntelFPGABankBitsAttr(Sema &S, Decl *D, const ParsedAttr &A) {
60666009
if (!A.checkAtLeastNumArgs(S, 1))
60676010
return;
60686011

6069-
if (checkAttrMutualExclusion<IntelFPGARegisterAttr>(S, D, A))
6070-
return;
6071-
60726012
SmallVector<Expr *, 8> Args;
60736013
for (unsigned I = 0; I < A.getNumArgs(); ++I) {
60746014
Args.push_back(A.getArgAsExpr(I));
@@ -6176,11 +6116,6 @@ void Sema::AddIntelFPGAPrivateCopiesAttr(Decl *D, const AttributeCommonInfo &CI,
61766116
}
61776117
}
61786118

6179-
// [[intel::fpga_register]] and [[intel::private_copies()]]
6180-
// attributes are incompatible.
6181-
if (checkAttrMutualExclusion<IntelFPGARegisterAttr>(*this, D, CI))
6182-
return;
6183-
61846119
// If the declaration does not have [[intel::memory]]
61856120
// attribute, this creates default implicit memory.
61866121
if (!D->hasAttr<IntelFPGAMemoryAttr>())
@@ -6234,11 +6169,6 @@ void Sema::AddIntelFPGAForcePow2DepthAttr(Decl *D,
62346169
}
62356170
}
62366171

6237-
// [[intel::fpga_register]] and [[intel::force_pow2_depth()]]
6238-
// attributes are incompatible.
6239-
if (checkAttrMutualExclusion<IntelFPGARegisterAttr>(*this, D, CI))
6240-
return;
6241-
62426172
// If the declaration does not have an [[intel::fpga_memory]]
62436173
// attribute, this creates one as an implicit attribute.
62446174
if (!D->hasAttr<IntelFPGAMemoryAttr>())
@@ -6266,11 +6196,6 @@ Sema::MergeIntelFPGAForcePow2DepthAttr(Decl *D,
62666196
}
62676197
}
62686198

6269-
// [[intel::fpga_register]] and [[intel::force_pow2_depth()]]
6270-
// attributes are incompatible.
6271-
if (checkAttrMutualExclusion<IntelFPGARegisterAttr>(*this, D, A))
6272-
return nullptr;
6273-
62746199
return ::new (Context) IntelFPGAForcePow2DepthAttr(Context, A, A.getValue());
62756200
}
62766201

@@ -9571,12 +9496,10 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
95719496

95729497
// Intel FPGA specific attributes
95739498
case ParsedAttr::AT_IntelFPGADoublePump:
9574-
handleIntelFPGAPumpAttr<IntelFPGADoublePumpAttr, IntelFPGASinglePumpAttr>(
9575-
S, D, AL);
9499+
handleIntelFPGAPumpAttr<IntelFPGADoublePumpAttr>(S, D, AL);
95769500
break;
95779501
case ParsedAttr::AT_IntelFPGASinglePump:
9578-
handleIntelFPGAPumpAttr<IntelFPGASinglePumpAttr, IntelFPGADoublePumpAttr>(
9579-
S, D, AL);
9502+
handleIntelFPGAPumpAttr<IntelFPGASinglePumpAttr>(S, D, AL);
95809503
break;
95819504
case ParsedAttr::AT_IntelFPGAMemory:
95829505
handleIntelFPGAMemoryAttr(S, D, AL);

clang/test/SemaSYCL/initiation_interval.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
// expected-note@+1 {{conflicting attribute is here}}
3737
[[intel::initiation_interval(4)]] [[intel::disable_loop_pipelining]] void func8();
3838

39-
// expected-error@+2 {{'initiation_interval' and 'disable_loop_pipelining' attributes are not compatible}}
40-
// expected-note@+2 {{conflicting attribute is here}}
39+
// expected-error@+3 {{'disable_loop_pipelining' and 'initiation_interval' attributes are not compatible}}
40+
// expected-note@+1 {{conflicting attribute is here}}
4141
[[intel::initiation_interval(4)]] void func9();
4242
[[intel::disable_loop_pipelining]] void func9();
4343

clang/test/SemaSYCL/intel-fpga-global-const.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@
2424
//expected-note@-2{{previous attribute is here}}
2525

2626
// Merging of incompatible attributes.
27-
// FIXME: Diagnostic order isn't correct, this isn't what we'd want here but
28-
// this is an upstream issue. Merge function is calling here
29-
// checkAttrMutualExclusion() function that has backwards diagnostic behavior.
30-
// This should be fixed into upstream.
31-
//expected-error@+2{{'max_replicates' and 'fpga_register' attributes are not compatible}}
32-
//expected-note@+2{{conflicting attribute is here}}
27+
//expected-error@+3{{'fpga_register' and 'max_replicates' attributes are not compatible}}
28+
//expected-note@+1{{conflicting attribute is here}}
3329
[[intel::max_replicates(12)]] extern const int var_max_replicates_2;
3430
[[intel::fpga_register]] const int var_max_replicates_2 =0;
3531

@@ -57,11 +53,7 @@
5753
//expected-note@-2{{previous attribute is here}}
5854

5955
// Merging of incompatible attributes.
60-
// FIXME: Diagnostic order isn't correct, this isn't what we'd want here but
61-
// this is an upstream issue. Merge function is calling here
62-
// checkAttrMutualExclusion() function that has backwards diagnostic behavior.
63-
// This should be fixed into upstream.
64-
//expected-error@+2{{'force_pow2_depth' and 'fpga_register' attributes are not compatible}}
65-
//expected-note@+2{{conflicting attribute is here}}
56+
//expected-error@+3{{'fpga_register' and 'force_pow2_depth' attributes are not compatible}}
57+
//expected-note@+1{{conflicting attribute is here}}
6658
[[intel::force_pow2_depth(1)]] extern const int var_force_pow2_depth_2;
6759
[[intel::fpga_register]] const int var_force_pow2_depth_2 =0;

clang/utils/TableGen/ClangAttrEmitter.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3664,10 +3664,12 @@ static void GenerateMutualExclusionsChecks(const Record &Attr,
36643664
if (Attr.isSubClassOf("TypeAttr"))
36653665
return;
36663666

3667-
// This means the attribute is either a statement attribute or a decl
3668-
// attribute, find out which.
3667+
// This means the attribute is either a statement attribute, a decl
3668+
// attribute, or both; find out which.
36693669
bool CurAttrIsStmtAttr =
36703670
Attr.isSubClassOf("StmtAttr") || Attr.isSubClassOf("DeclOrStmtAttr");
3671+
bool CurAttrIsDeclAttr =
3672+
!CurAttrIsStmtAttr || Attr.isSubClassOf("DeclOrStmtAttr");
36713673

36723674
std::vector<std::string> DeclAttrs, StmtAttrs;
36733675

@@ -3686,7 +3688,7 @@ static void GenerateMutualExclusionsChecks(const Record &Attr,
36863688

36873689
if (CurAttrIsStmtAttr)
36883690
StmtAttrs.push_back((AttrToExclude->getName() + "Attr").str());
3689-
else
3691+
if (CurAttrIsDeclAttr)
36903692
DeclAttrs.push_back((AttrToExclude->getName() + "Attr").str());
36913693
}
36923694
}

0 commit comments

Comments
 (0)