Skip to content

[SYCL][FPGA] Refactor of [[intel::max_global_work_dim()]] attribute #3326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 35 commits into from
May 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3614707
[SYCL][FPGA] Refactor of [[intel::max_global_work_dim()]] attribute
smanna12 Mar 9, 2021
bda9eef
Fix errors
smanna12 Mar 9, 2021
a56f449
Fix errors
smanna12 Mar 9, 2021
86509bf
address review comments
smanna12 Mar 9, 2021
165f537
Update comments
smanna12 Mar 9, 2021
1f82fa3
remove paren
smanna12 Mar 9, 2021
0b88e5c
Merge remote-tracking branch 'my_remote/sycl' into MaxGlobalAttr
smanna12 Mar 10, 2021
9e6a71e
Remove generic template function addIntelSingleArgAttr(), remove -fsy…
smanna12 Mar 10, 2021
a17f9cd
address review comments
smanna12 Mar 11, 2021
586a2d9
Fix errors
smanna12 Mar 11, 2021
22bc2d3
Merge remote-tracking branch 'my_remote/sycl' into MaxGlobalAttr
smanna12 Mar 11, 2021
f172eb4
don't duplicate the attribute with the same arguments
smanna12 Mar 20, 2021
422e730
Merge remote-tracking branch 'my_remote/sycl' into MaxGlobalAttr
smanna12 Mar 20, 2021
93e00ba
Fix lit test failure
smanna12 Mar 20, 2021
2833331
Upadte test
smanna12 Mar 20, 2021
0be1b62
Update logic for dropping duplicate attribute with same arguments and…
smanna12 Mar 21, 2021
afb6849
Refcator duplicate attr logic for same argument and add test
smanna12 Mar 21, 2021
70f87ca
Address review comments
smanna12 Mar 24, 2021
17166de
address review comments
smanna12 Mar 25, 2021
c5c31f1
Merge remote-tracking branch 'my_remote/sycl' into MaxGlobalAttr
smanna12 May 13, 2021
1ba0baa
handle dependent argument values and addressed review comments
smanna12 May 13, 2021
c4d5423
fix format issues
smanna12 May 13, 2021
8600280
fix wrong value
smanna12 May 13, 2021
56a36ee
adress review comments
smanna12 May 14, 2021
d8effc1
address review comments
smanna12 May 24, 2021
af29f9a
Merge remote-tracking branch 'my_remote/sycl' into MaxGlobalAttr
smanna12 May 24, 2021
a9ad2c4
Fix clang format issues
smanna12 May 24, 2021
ce62808
address review comments
smanna12 May 25, 2021
2ccb247
Merge remote-tracking branch 'my_remote/sycl' into MaxGlobalAttr
smanna12 May 25, 2021
f6c7c57
fix format issues
smanna12 May 25, 2021
a1139cd
address review comments
smanna12 May 26, 2021
45a294b
fix format issues
smanna12 May 26, 2021
65da4b8
address review comments
smanna12 May 26, 2021
5d5f1fa
fix format issues
smanna12 May 26, 2021
618bb3e
address review comments
smanna12 May 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -11346,7 +11346,7 @@ def err_conflicting_sycl_function_attributes : Error<
def err_sycl_function_attribute_mismatch : Error<
"SYCL kernel without %0 attribute can't call a function with this attribute">;
def err_sycl_x_y_z_arguments_must_be_one : Error<
"%0 X-, Y- and Z- sizes must be 1 when %1 attribute is used with value 0">;
"all %0 attribute arguments must be '1' when the %1 attribute argument is '0'">;
def err_sycl_attribute_internal_function
: Error<"%0 attribute cannot be applied to a "
"static function or function in an anonymous namespace">;
Expand Down
39 changes: 5 additions & 34 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -10302,8 +10302,6 @@ class Sema final {
void AddIntelFPGABankBitsAttr(Decl *D, const AttributeCommonInfo &CI,
Expr **Exprs, unsigned Size);
template <typename AttrType>
void addIntelSingleArgAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E);
template <typename AttrType>
void addIntelTripleArgAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *XDimExpr, Expr *YDimExpr, Expr *ZDimExpr);
void AddWorkGroupSizeHintAttr(Decl *D, const AttributeCommonInfo &CI,
Expand Down Expand Up @@ -10359,7 +10357,11 @@ class Sema final {

SYCLIntelFPGAMaxConcurrencyAttr *MergeSYCLIntelFPGAMaxConcurrencyAttr(
Decl *D, const SYCLIntelFPGAMaxConcurrencyAttr &A);

void AddSYCLIntelMaxGlobalWorkDimAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *E);
SYCLIntelMaxGlobalWorkDimAttr *
MergeSYCLIntelMaxGlobalWorkDimAttr(Decl *D,
const SYCLIntelMaxGlobalWorkDimAttr &A);
/// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
bool IsPackExpansion);
Expand Down Expand Up @@ -13332,37 +13334,6 @@ class Sema final {
}
};

template <typename AttrType>
void Sema::addIntelSingleArgAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *E) {
assert(E && "Attribute must have an argument.");

if (!E->isInstantiationDependent()) {
llvm::APSInt ArgVal;
ExprResult ICE = VerifyIntegerConstantExpression(E, &ArgVal);
if (ICE.isInvalid())
return;
E = ICE.get();
int32_t ArgInt = ArgVal.getSExtValue();
if (CI.getParsedKind() == ParsedAttr::AT_SYCLIntelMaxGlobalWorkDim) {
if (ArgInt < 0) {
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
<< CI << /*non-negative*/ 1;
return;
}
}
if (CI.getParsedKind() == ParsedAttr::AT_SYCLIntelMaxGlobalWorkDim) {
if (ArgInt > 3) {
Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)
<< CI << 0 << 3 << E->getSourceRange();
return;
}
}
}

D->addAttr(::new (Context) AttrType(Context, CI, E));
}

inline Expr *checkMaxWorkSizeAttrExpr(Sema &S, const AttributeCommonInfo &CI,
Expr *E) {
assert(E && "Attribute must have an argument.");
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2643,6 +2643,8 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
NewAttr = S.MergeSYCLIntelFPGAInitiationIntervalAttr(D, *A);
else if (const auto *A = dyn_cast<WorkGroupSizeHintAttr>(Attr))
NewAttr = S.MergeWorkGroupSizeHintAttr(D, *A);
else if (const auto *A = dyn_cast<SYCLIntelMaxGlobalWorkDimAttr>(Attr))
NewAttr = S.MergeSYCLIntelMaxGlobalWorkDimAttr(D, *A);
else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));

Expand Down
189 changes: 140 additions & 49 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2989,19 +2989,6 @@ static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// they hold equal values (1, 1, 1).
static bool checkWorkGroupSizeValues(Sema &S, Decl *D, const ParsedAttr &AL) {
bool Result = true;
auto checkZeroDim = [&S, &AL](auto &A, size_t X, size_t Y, size_t Z,
bool ReverseAttrs = false) -> bool {
if (X != 1 || Y != 1 || Z != 1) {
auto Diag =
S.Diag(AL.getLoc(), diag::err_sycl_x_y_z_arguments_must_be_one);
if (ReverseAttrs)
Diag << AL << A;
else
Diag << A << AL;
return false;
}
return true;
};

// Returns the unsigned constant integer value represented by
// given expression.
Expand All @@ -3011,30 +2998,6 @@ static bool checkWorkGroupSizeValues(Sema &S, Decl *D, const ParsedAttr &AL) {

ASTContext &Ctx = S.getASTContext();

if (AL.getKind() == ParsedAttr::AT_SYCLIntelMaxGlobalWorkDim) {
ArrayRef<const Expr *> Dims;
Attr *B = nullptr;
if (const auto *B = D->getAttr<SYCLIntelMaxWorkGroupSizeAttr>())
Dims = B->dimensions();
else if (const auto *B = D->getAttr<ReqdWorkGroupSizeAttr>())
Dims = B->dimensions();
if (B) {
Result &=
checkZeroDim(B, getExprValue(Dims[0], Ctx),
getExprValue(Dims[1], Ctx), getExprValue(Dims[2], Ctx));
}
return Result;
}

if (const auto *A = D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>()) {
if ((A->getValue()->getIntegerConstantExpr(Ctx)->getSExtValue()) == 0) {
Result &= checkZeroDim(A, getExprValue(AL.getArgAsExpr(0), Ctx),
getExprValue(AL.getArgAsExpr(1), Ctx),
getExprValue(AL.getArgAsExpr(2), Ctx),
/*ReverseAttrs=*/true);
}
}

if (const auto *A = D->getAttr<SYCLIntelMaxWorkGroupSizeAttr>()) {
if (!((getExprValue(AL.getArgAsExpr(0), Ctx) <=
getExprValue(A->getXDim(), Ctx)) &&
Expand Down Expand Up @@ -3144,6 +3107,27 @@ static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
}
}

// If the declaration has a SYCLIntelMaxWorkGroupSizeAttr or
// ReqdWorkGroupSizeAttr, check to see if they hold equal values
// (1, 1, 1) in case the value of SYCLIntelMaxGlobalWorkDimAttr
// equals to 0.
if (const auto *DeclAttr = D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>()) {
if (const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue())) {
// If the value is dependent, we can not test anything.
if (!DeclExpr)
return;

// Test the attribute value.
if (DeclExpr->getResultAsAPSInt() == 0 &&
(XDimVal.getZExtValue() != 1 || YDimVal.getZExtValue() != 1 ||
ZDimVal.getZExtValue() != 1)) {
S.Diag(AL.getLoc(), diag::err_sycl_x_y_z_arguments_must_be_one)
<< AL << DeclAttr;
return;
}
}
}

if (const auto *ExistingAttr = D->getAttr<WorkGroupAttr>()) {
// Compare attribute arguments value and warn for a mismatch.
if (ExistingAttr->getXDimVal(Ctx) != XDimVal ||
Expand Down Expand Up @@ -3646,23 +3630,130 @@ static void handleSYCLIntelSchedulerTargetFmaxMhzAttr(Sema &S, Decl *D,
}

// Handles max_global_work_dim.
static void handleMaxGlobalWorkDimAttr(Sema &S, Decl *D, const ParsedAttr &A) {
if (D->isInvalidDecl())
return;
// Returns a OneArgResult value; EqualToOne means all argument values are
// equal to one, NotEqualToOne means at least one argument value is not
// equal to one, and Unknown means that at least one of the argument values
// could not be determined.
enum class OneArgResult { Unknown, EqualToOne, NotEqualToOne };
static OneArgResult AreAllArgsOne(const Expr *Args[], size_t Count) {

for (size_t Idx = 0; Idx < Count; ++Idx) {
const auto *CE = dyn_cast<ConstantExpr>(Args[Idx]);
if (!CE)
return OneArgResult::Unknown;
if (CE->getResultAsAPSInt() != 1)
return OneArgResult::NotEqualToOne;
}
return OneArgResult::EqualToOne;
}

// If the declaration has a SYCLIntelMaxWorkGroupSizeAttr or
// ReqdWorkGroupSizeAttr, check to see if they hold equal values
// (1, 1, 1). Returns true if diagnosed.
template <typename AttrTy>
static bool checkWorkGroupSizeAttrExpr(Sema &S, Decl *D,
const AttributeCommonInfo &AL) {
if (const auto *A = D->getAttr<AttrTy>()) {
const Expr *Args[3] = {A->getXDim(), A->getYDim(), A->getZDim()};
if (OneArgResult::NotEqualToOne == AreAllArgsOne(Args, 3)) {
S.Diag(A->getLocation(), diag::err_sycl_x_y_z_arguments_must_be_one)
<< A << AL;
return true;
}
}
return false;
}

Expr *E = A.getArgAsExpr(0);
void Sema::AddSYCLIntelMaxGlobalWorkDimAttr(Decl *D,
const AttributeCommonInfo &CI,
Expr *E) {
if (!E->isValueDependent()) {
// Validate that we have an integer constant expression and then store the
// converted constant expression into the semantic attribute so that we
// don't have to evaluate it again later.
llvm::APSInt ArgVal;
ExprResult Res = VerifyIntegerConstantExpression(E, &ArgVal);
if (Res.isInvalid())
return;
E = Res.get();

if (!checkWorkGroupSizeValues(S, D, A)) {
D->setInvalidDecl();
return;
// This attribute must be in the range [0, 3].
if (ArgVal < 0 || ArgVal > 3) {
Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)
<< CI << 0 << 3 << E->getSourceRange();
return;
}

// Check to see if there's a duplicate attribute with different values
// already applied to the declaration.
if (const auto *DeclAttr = D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>()) {
// If the other attribute argument is instantiation dependent, we won't
// have converted it to a constant expression yet and thus we test
// whether this is a null pointer.
if (const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue())) {
if (ArgVal != DeclExpr->getResultAsAPSInt()) {
Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI;
Diag(DeclAttr->getLoc(), diag::note_previous_attribute);
}
// Drop the duplicate attribute.
return;
}
}

// If the declaration has a SYCLIntelMaxWorkGroupSizeAttr or
// ReqdWorkGroupSizeAttr, check to see if they hold equal values
// (1, 1, 1) in case the value of SYCLIntelMaxGlobalWorkDimAttr
// equals to 0.
if (ArgVal == 0) {
if (checkWorkGroupSizeAttrExpr<SYCLIntelMaxWorkGroupSizeAttr>(*this, D,
CI) ||
checkWorkGroupSizeAttrExpr<ReqdWorkGroupSizeAttr>(*this, D, CI))
return;
}
}

if (D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>())
S.Diag(A.getLoc(), diag::warn_duplicate_attribute) << A;
D->addAttr(::new (Context) SYCLIntelMaxGlobalWorkDimAttr(Context, CI, E));
}

S.CheckDeprecatedSYCLAttributeSpelling(A);
SYCLIntelMaxGlobalWorkDimAttr *Sema::MergeSYCLIntelMaxGlobalWorkDimAttr(
Decl *D, const SYCLIntelMaxGlobalWorkDimAttr &A) {
// Check to see if there's a duplicate attribute with different values
// already applied to the declaration.
if (const auto *DeclAttr = D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>()) {
if (const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue())) {
if (const auto *MergeExpr = dyn_cast<ConstantExpr>(A.getValue())) {
if (DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) {
Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A;
Diag(A.getLoc(), diag::note_previous_attribute);
}
// Do not add a duplicate attribute.
return nullptr;
}
}
}

// If the declaration has a SYCLIntelMaxWorkGroupSizeAttr or
// ReqdWorkGroupSizeAttr, check to see if they hold equal values
// (1, 1, 1) in case the value of SYCLIntelMaxGlobalWorkDimAttr
// equals to 0.
const auto *MergeExpr = dyn_cast<ConstantExpr>(A.getValue());
if (MergeExpr->getResultAsAPSInt() == 0) {
if (checkWorkGroupSizeAttrExpr<SYCLIntelMaxWorkGroupSizeAttr>(*this, D,
A) ||
checkWorkGroupSizeAttrExpr<ReqdWorkGroupSizeAttr>(*this, D, A))
return nullptr;
}

return ::new (Context)
SYCLIntelMaxGlobalWorkDimAttr(Context, A, A.getValue());
}

S.addIntelSingleArgAttr<SYCLIntelMaxGlobalWorkDimAttr>(D, A, E);
static void handleSYCLIntelMaxGlobalWorkDimAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
S.CheckDeprecatedSYCLAttributeSpelling(AL);

Expr *E = AL.getArgAsExpr(0);
S.AddSYCLIntelMaxGlobalWorkDimAttr(D, AL, E);
}

// Handles [[intel::loop_fuse]] and [[intel::loop_fuse_independent]].
Expand Down Expand Up @@ -9543,7 +9634,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleSYCLIntelSchedulerTargetFmaxMhzAttr(S, D, AL);
break;
case ParsedAttr::AT_SYCLIntelMaxGlobalWorkDim:
handleMaxGlobalWorkDimAttr(S, D, AL);
handleSYCLIntelMaxGlobalWorkDimAttr(S, D, AL);
break;
case ParsedAttr::AT_SYCLIntelNoGlobalWorkOffset:
handleSYCLIntelNoGlobalWorkOffsetAttr(S, D, AL);
Expand Down
13 changes: 6 additions & 7 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,15 +682,14 @@ static void instantiateSYCLIntelNoGlobalWorkOffsetAttr(
S.AddSYCLIntelNoGlobalWorkOffsetAttr(New, *A, Result.getAs<Expr>());
}

template <typename AttrName>
static void instantiateIntelSYCLFunctionAttr(
static void instantiateSYCLIntelMaxGlobalWorkDimAttr(
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
const AttrName *Attr, Decl *New) {
const SYCLIntelMaxGlobalWorkDimAttr *A, Decl *New) {
EnterExpressionEvaluationContext Unevaluated(
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
ExprResult Result = S.SubstExpr(Attr->getValue(), TemplateArgs);
ExprResult Result = S.SubstExpr(A->getValue(), TemplateArgs);
if (!Result.isInvalid())
S.addIntelSingleArgAttr<AttrName>(New, *Attr, Result.getAs<Expr>());
S.AddSYCLIntelMaxGlobalWorkDimAttr(New, *A, Result.getAs<Expr>());
}

static void instantiateSYCLIntelFPGAMaxConcurrencyAttr(
Expand Down Expand Up @@ -960,8 +959,8 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
}
if (const auto *SYCLIntelMaxGlobalWorkDim =
dyn_cast<SYCLIntelMaxGlobalWorkDimAttr>(TmplAttr)) {
instantiateIntelSYCLFunctionAttr<SYCLIntelMaxGlobalWorkDimAttr>(
*this, TemplateArgs, SYCLIntelMaxGlobalWorkDim, New);
instantiateSYCLIntelMaxGlobalWorkDimAttr(*this, TemplateArgs,
SYCLIntelMaxGlobalWorkDim, New);
continue;
}
if (const auto *SYCLIntelLoopFuse =
Expand Down
Loading