Skip to content

Commit 3614707

Browse files
committed
[SYCL][FPGA] Refactor of [[intel::max_global_work_dim()]] attribute
This patch 1. refactors FPGA function attribute using intel#3224: [[intel::max_global_work_dim()]] attribute to better fit for community standards. 2. refactors the way we handle duplicate attributes and mutually exclusive attributes logic when present on a given declaration. 3. handles redeclarations or template instantiations properly. 4. adds tests 5. adds new test cases where the value of 'max_global_work_dim' attribute equals to 0, we shall ensure that if max_work_group_size and reqd_work_group_size attributes exist, they hold equal values (1, 1, 1). Before the new refactoring patch, we silently accepeted this test case: struct TRIFuncObjBad { [[intel::max_work_group_size(8, 8, 8)]] [[cl::reqd_work_group_size(4, 4, 4)]] [[intel::max_global_work_dim(0)]] void operator()() const {} }; Signed-off-by: Soumi Manna <soumi.manna@intel.com>
1 parent 4127426 commit 3614707

File tree

6 files changed

+351
-33
lines changed

6 files changed

+351
-33
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10234,6 +10234,10 @@ class Sema final {
1023410234
Expr *E);
1023510235
SYCLIntelLoopFuseAttr *
1023610236
MergeSYCLIntelLoopFuseAttr(Decl *D, const SYCLIntelLoopFuseAttr &A);
10237+
void AddSYCLIntelMaxGlobalWorkDimAttr(Decl *D, const AttributeCommonInfo &CI,
10238+
Expr *E);
10239+
SYCLIntelMaxGlobalWorkDimAttr *MergeSYCLIntelMaxGlobalWorkDimAttr(
10240+
Decl *D, const SYCLIntelMaxGlobalWorkDimAttr &A);
1023710241

1023810242
/// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
1023910243
void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
@@ -13100,20 +13104,6 @@ void Sema::addIntelSingleArgAttr(Decl *D, const AttributeCommonInfo &CI,
1310013104
return;
1310113105
}
1310213106
}
13103-
if (CI.getParsedKind() == ParsedAttr::AT_SYCLIntelMaxGlobalWorkDim) {
13104-
if (ArgInt < 0) {
13105-
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
13106-
<< CI << /*non-negative*/ 1;
13107-
return;
13108-
}
13109-
}
13110-
if (CI.getParsedKind() == ParsedAttr::AT_SYCLIntelMaxGlobalWorkDim) {
13111-
if (ArgInt > 3) {
13112-
Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)
13113-
<< CI << 0 << 3 << E->getSourceRange();
13114-
return;
13115-
}
13116-
}
1311713107
if (CI.getParsedKind() == ParsedAttr::AT_IntelFPGAPrivateCopies) {
1311813108
if (ArgInt < 0) {
1311913109
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)

clang/lib/Sema/SemaDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2626,6 +2626,8 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
26262626
NewAttr = S.MergeSYCLIntelSchedulerTargetFmaxMhzAttr(D, *A);
26272627
else if (const auto *A = dyn_cast<SYCLIntelNoGlobalWorkOffsetAttr>(Attr))
26282628
NewAttr = S.MergeSYCLIntelNoGlobalWorkOffsetAttr(D, *A);
2629+
else if (const auto *A = dyn_cast<SYCLIntelMaxGlobalWorkDimAttr>(Attr))
2630+
NewAttr = S.MergeSYCLIntelMaxGlobalWorkDimAttr(D, *A);
26292631
else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
26302632
NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));
26312633

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 93 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3430,23 +3430,103 @@ static void handleSYCLIntelSchedulerTargetFmaxMhzAttr(Sema &S, Decl *D,
34303430
}
34313431

34323432
// Handles max_global_work_dim.
3433-
static void handleMaxGlobalWorkDimAttr(Sema &S, Decl *D, const ParsedAttr &A) {
3434-
if (D->isInvalidDecl())
3435-
return;
3436-
3437-
Expr *E = A.getArgAsExpr(0);
3433+
void Sema::AddSYCLIntelMaxGlobalWorkDimAttr(Decl *D,
3434+
const AttributeCommonInfo &CI,
3435+
Expr *E) {
3436+
if (!E->isValueDependent()) {
3437+
// Validate that we have an integer constant expression and then store the
3438+
// converted constant expression into the semantic attribute so that we
3439+
// don't have to evaluate it again later.
3440+
llvm::APSInt ArgVal;
3441+
ExprResult Res = VerifyIntegerConstantExpression(E, &ArgVal);
3442+
if (Res.isInvalid())
3443+
return;
3444+
E = Res.get();
34383445

3439-
if (!checkWorkGroupSizeValues(S, D, A)) {
3440-
D->setInvalidDecl();
3441-
return;
3446+
// This attribute requires a non-negative value.
3447+
if (ArgVal < 0) {
3448+
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
3449+
<< CI << /*non-negative*/ 1;
3450+
return;
3451+
}
3452+
// This attribute must be in the range [0, 3].
3453+
if (ArgVal > 3) {
3454+
Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)
3455+
<< CI << 0 << 3 << E->getSourceRange();
3456+
return;
3457+
}
3458+
// Check to see if there's a duplicate attribute with different values
3459+
// already applied to the declaration.
3460+
if (const auto *DeclAttr =
3461+
D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>()) {
3462+
// If the other attribute argument is instantiation dependent, we won't
3463+
// have converted it to a constant expression yet and thus we test
3464+
// whether this is a null pointer.
3465+
const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue());
3466+
if (DeclExpr && ArgVal != DeclExpr->getResultAsAPSInt()) {
3467+
Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI;
3468+
Diag(DeclAttr->getLoc(), diag::note_previous_attribute);
3469+
return;
3470+
}
3471+
}
3472+
// If the declaration has an [[intel::reqd_work_group_size()]] or
3473+
// [[cl::reqd_work_group_size()]] attribute, check to see if they
3474+
// hold equal values (1, 1, 1) in case the value of
3475+
// [[intel::max_global_work_dim()]] attribute equals to 0.
3476+
if (const auto *DeclAttr = D->getAttr<ReqdWorkGroupSizeAttr>()) {
3477+
Optional<llvm::APSInt> XDimVal = DeclAttr->getXDimVal(Context);
3478+
Optional<llvm::APSInt> YDimVal = DeclAttr->getYDimVal(Context);
3479+
Optional<llvm::APSInt> ZDimVal = DeclAttr->getZDimVal(Context);
3480+
if ((ArgVal == 0) && (*XDimVal != 1 || *YDimVal != 1 || *ZDimVal != 1)) {
3481+
Diag(DeclAttr->getLocation(), diag::err_sycl_x_y_z_arguments_must_be_one)
3482+
<< DeclAttr << CI;
3483+
return;
3484+
}
3485+
}
3486+
// If the declaration has an [[intel::max_work_group_size()]]
3487+
// attribute, check to see if it holds equal values (1, 1, 1) in
3488+
// case the value of [[intel::max_global_work_dim()]] attribute equals to 0.
3489+
if (const auto *DeclAttr = D->getAttr<SYCLIntelMaxWorkGroupSizeAttr>()) {
3490+
Optional<llvm::APSInt> XDimVal = DeclAttr->getXDimVal(Context);
3491+
Optional<llvm::APSInt> YDimVal = DeclAttr->getYDimVal(Context);
3492+
Optional<llvm::APSInt> ZDimVal = DeclAttr->getZDimVal(Context);
3493+
if ((ArgVal == 0) && (*XDimVal != 1 || *YDimVal != 1 || *ZDimVal != 1)) {
3494+
Diag(DeclAttr->getLocation(), diag::err_sycl_x_y_z_arguments_must_be_one)
3495+
<< DeclAttr << CI;
3496+
return;
3497+
}
3498+
}
34423499
}
34433500

3444-
if (D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>())
3445-
S.Diag(A.getLoc(), diag::warn_duplicate_attribute) << A;
3501+
D->addAttr(::new (Context)
3502+
SYCLIntelMaxGlobalWorkDimAttr(Context, CI, E));
3503+
}
34463504

3447-
S.CheckDeprecatedSYCLAttributeSpelling(A);
3505+
SYCLIntelMaxGlobalWorkDimAttr *Sema::MergeSYCLIntelMaxGlobalWorkDimAttr(
3506+
Decl *D, const SYCLIntelMaxGlobalWorkDimAttr &A) {
3507+
// Check to see if there's a duplicate attribute with different values
3508+
// already applied to the declaration.
3509+
if (const auto *DeclAttr =
3510+
D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>()) {
3511+
const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue());
3512+
const auto *MergeExpr = dyn_cast<ConstantExpr>(A.getValue());
3513+
if (DeclExpr && MergeExpr &&
3514+
DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) {
3515+
Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A;
3516+
Diag(A.getLoc(), diag::note_previous_attribute);
3517+
return nullptr;
3518+
}
3519+
}
3520+
return ::new (Context)
3521+
SYCLIntelMaxGlobalWorkDimAttr(Context, A, A.getValue());
3522+
}
34483523

3449-
S.addIntelSingleArgAttr<SYCLIntelMaxGlobalWorkDimAttr>(D, A, E);
3524+
static void handleSYCLIntelMaxGlobalWorkDimAttr(Sema &S, Decl *D,
3525+
const ParsedAttr &AL) {
3526+
S.CheckDeprecatedSYCLAttributeSpelling(AL);
3527+
3528+
Expr *E = AL.getArgAsExpr(0);
3529+
S.AddSYCLIntelMaxGlobalWorkDimAttr(D, AL, E);
34503530
}
34513531

34523532
// Handles [[intel::loop_fuse]] and [[intel::loop_fuse_independent]].
@@ -9129,7 +9209,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
91299209
handleSYCLIntelSchedulerTargetFmaxMhzAttr(S, D, AL);
91309210
break;
91319211
case ParsedAttr::AT_SYCLIntelMaxGlobalWorkDim:
9132-
handleMaxGlobalWorkDimAttr(S, D, AL);
9212+
handleSYCLIntelMaxGlobalWorkDimAttr(S, D, AL);
91339213
break;
91349214
case ParsedAttr::AT_SYCLIntelNoGlobalWorkOffset:
91359215
handleSYCLIntelNoGlobalWorkOffsetAttr(S, D, AL);

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,16 @@ static void instantiateSYCLIntelNoGlobalWorkOffsetAttr(
683683
S.AddSYCLIntelNoGlobalWorkOffsetAttr(New, *A, Result.getAs<Expr>());
684684
}
685685

686+
static void instantiateSYCLIntelMaxGlobalWorkDimAttr(
687+
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
688+
const SYCLIntelMaxGlobalWorkDimAttr *A, Decl *New) {
689+
EnterExpressionEvaluationContext Unevaluated(
690+
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
691+
ExprResult Result = S.SubstExpr(A->getValue(), TemplateArgs);
692+
if (!Result.isInvalid())
693+
S.AddSYCLIntelMaxGlobalWorkDimAttr(New, *A, Result.getAs<Expr>());
694+
}
695+
686696
template <typename AttrName>
687697
static void instantiateIntelSYCLFunctionAttr(
688698
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
@@ -892,7 +902,7 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
892902
}
893903
if (const auto *SYCLIntelMaxGlobalWorkDim =
894904
dyn_cast<SYCLIntelMaxGlobalWorkDimAttr>(TmplAttr)) {
895-
instantiateIntelSYCLFunctionAttr<SYCLIntelMaxGlobalWorkDimAttr>(
905+
instantiateSYCLIntelMaxGlobalWorkDimAttr(
896906
*this, TemplateArgs, SYCLIntelMaxGlobalWorkDim, New);
897907
continue;
898908
}

0 commit comments

Comments
 (0)