Skip to content

Commit 6a283ae

Browse files
vmaksimobader
authored andcommitted
[SYCL] Enable template parameter support for ii and max_concurrency attributes (#811)
Signed-off-by: Viktoria Maksimova <[email protected]>
1 parent 20248cf commit 6a283ae

File tree

7 files changed

+156
-45
lines changed

7 files changed

+156
-45
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,8 +1550,9 @@ def SYCLIntelFPGAIVDep : Attr {
15501550

15511551
def SYCLIntelFPGAII : Attr {
15521552
let Spellings = [CXX11<"intelfpga","ii">];
1553-
let Args = [IntArgument<"Interval">];
1553+
let Args = [ExprArgument<"IntervalExpr">];
15541554
let LangOpts = [SYCLIsDevice, SYCLIsHost];
1555+
let HasCustomTypeTransform = 1;
15551556
let AdditionalMembers = [{
15561557
static const char *getName() {
15571558
return "ii";
@@ -1562,8 +1563,9 @@ def SYCLIntelFPGAII : Attr {
15621563

15631564
def SYCLIntelFPGAMaxConcurrency : Attr {
15641565
let Spellings = [CXX11<"intelfpga","max_concurrency">];
1565-
let Args = [IntArgument<"NThreads">];
1566+
let Args = [ExprArgument<"NThreadsExpr">];
15661567
let LangOpts = [SYCLIsDevice, SYCLIsHost];
1568+
let HasCustomTypeTransform = 1;
15671569
let AdditionalMembers = [{
15681570
static const char *getName() {
15691571
return "max_concurrency";

clang/include/clang/Sema/Sema.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,6 +1659,9 @@ class Sema {
16591659
SYCLIntelFPGAIVDepAttr *
16601660
BuildSYCLIntelFPGAIVDepAttr(const AttributeCommonInfo &CI, Expr *Expr1,
16611661
Expr *Expr2);
1662+
template <typename FPGALoopAttrT>
1663+
FPGALoopAttrT *BuildSYCLIntelFPGALoopAttr(const AttributeCommonInfo &A,
1664+
Expr *E);
16621665

16631666
bool CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc);
16641667

clang/lib/CodeGen/CGLoopInfo.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -895,14 +895,23 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
895895
}
896896

897897
if (IntelFPGAII) {
898-
unsigned ValueInt = IntelFPGAII->getInterval();
899-
if (ValueInt > 0)
900-
setSYCLIInterval(ValueInt);
898+
llvm::APSInt ArgVal(32);
899+
bool IsValid =
900+
IntelFPGAII->getIntervalExpr()->isIntegerConstantExpr(ArgVal, Ctx);
901+
assert(IsValid && "Not an integer constant expression");
902+
(void)IsValid;
903+
setSYCLIInterval(ArgVal.getSExtValue());
901904
}
902905

903906
if (IntelFPGAMaxConcurrency) {
907+
llvm::APSInt ArgVal(32);
908+
bool IsValid =
909+
IntelFPGAMaxConcurrency->getNThreadsExpr()->isIntegerConstantExpr(
910+
ArgVal, Ctx);
911+
assert(IsValid && "Not an integer constant expression");
912+
(void)IsValid;
904913
setSYCLMaxConcurrencyEnable();
905-
setSYCLMaxConcurrencyNThreads(IntelFPGAMaxConcurrency->getNThreads());
914+
setSYCLMaxConcurrencyNThreads(ArgVal.getSExtValue());
906915
}
907916
}
908917

clang/lib/Sema/SemaStmtAttr.cpp

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ static Attr *handleSuppressAttr(Sema &S, Stmt *St, const ParsedAttr &A,
7474
}
7575

7676
template <typename FPGALoopAttrT>
77-
static Attr *handleIntelFPGALoopAttr(Sema &S, Stmt *St, const ParsedAttr &A) {
78-
77+
static Attr *handleIntelFPGALoopAttr(Sema &S, const ParsedAttr &A) {
7978
if(S.LangOpts.SYCLIsHost)
8079
return nullptr;
8180

@@ -93,39 +92,7 @@ static Attr *handleIntelFPGALoopAttr(Sema &S, Stmt *St, const ParsedAttr &A) {
9392
}
9493
}
9594

96-
unsigned SafeInterval = 0;
97-
98-
if (NumArgs == 1) {
99-
Expr *E = A.getArgAsExpr(0);
100-
llvm::APSInt ArgVal(32);
101-
102-
if (!E->isIntegerConstantExpr(ArgVal, S.Context)) {
103-
S.Diag(A.getLoc(), diag::err_attribute_argument_type)
104-
<< A << AANT_ArgumentIntegerConstant << E->getSourceRange();
105-
return nullptr;
106-
}
107-
108-
int Val = ArgVal.getSExtValue();
109-
110-
if (A.getKind() != ParsedAttr::AT_SYCLIntelFPGAMaxConcurrency) {
111-
if (Val <= 0) {
112-
S.Diag(A.getRange().getBegin(),
113-
diag::warn_attribute_requires_positive_integer)
114-
<< A << /* positive */ 0;
115-
return nullptr;
116-
}
117-
} else {
118-
if (Val < 0) {
119-
S.Diag(A.getRange().getBegin(),
120-
diag::warn_attribute_requires_positive_integer)
121-
<< A << /* non-negative */ 1;
122-
return nullptr;
123-
}
124-
}
125-
SafeInterval = Val;
126-
}
127-
128-
return FPGALoopAttrT::CreateImplicit(S.Context, SafeInterval);
95+
return S.BuildSYCLIntelFPGALoopAttr<FPGALoopAttrT>(A, A.getArgAsExpr(0));
12996
}
13097

13198
static bool checkSYCLIntelFPGAIVDepSafeLen(Sema &S, llvm::APSInt &Value,
@@ -207,6 +174,44 @@ Sema::BuildSYCLIntelFPGAIVDepAttr(const AttributeCommonInfo &CI, Expr *Expr1,
207174
SYCLIntelFPGAIVDepAttr(Context, CI, SafeLenExpr, ArrayExpr, SafelenValue);
208175
}
209176

177+
template <typename FPGALoopAttrT>
178+
FPGALoopAttrT *Sema::BuildSYCLIntelFPGALoopAttr(const AttributeCommonInfo &A,
179+
Expr *E) {
180+
if (!E)
181+
return nullptr;
182+
183+
if (!E->isInstantiationDependent()) {
184+
llvm::APSInt ArgVal(32);
185+
186+
if (!E->isIntegerConstantExpr(ArgVal, getASTContext())) {
187+
Diag(E->getExprLoc(), diag::err_attribute_argument_type)
188+
<< A.getAttrName() << AANT_ArgumentIntegerConstant
189+
<< E->getSourceRange();
190+
return nullptr;
191+
}
192+
193+
int Val = ArgVal.getSExtValue();
194+
195+
if (A.getParsedKind() == ParsedAttr::AT_SYCLIntelFPGAII) {
196+
if (Val <= 0) {
197+
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
198+
<< "'ii'" << /* positive */ 0;
199+
return nullptr;
200+
}
201+
} else if (A.getParsedKind() ==
202+
ParsedAttr::AT_SYCLIntelFPGAMaxConcurrency) {
203+
if (Val < 0) {
204+
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
205+
<< "'max_concurrency'" << /* non-negative */ 1;
206+
return nullptr;
207+
}
208+
} else {
209+
llvm_unreachable("unknown sycl fpga loop attr");
210+
}
211+
}
212+
213+
return new (Context) FPGALoopAttrT(Context, A, E);
214+
}
210215
// Filters out any attributes from the list that are either not the specified
211216
// type, or whose function isDependent returns true.
212217
template <typename T>
@@ -611,9 +616,9 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A,
611616
case ParsedAttr::AT_SYCLIntelFPGAIVDep:
612617
return handleIntelFPGAIVDepAttr(S, A);
613618
case ParsedAttr::AT_SYCLIntelFPGAII:
614-
return handleIntelFPGALoopAttr<SYCLIntelFPGAIIAttr>(S, St, A);
619+
return handleIntelFPGALoopAttr<SYCLIntelFPGAIIAttr>(S, A);
615620
case ParsedAttr::AT_SYCLIntelFPGAMaxConcurrency:
616-
return handleIntelFPGALoopAttr<SYCLIntelFPGAMaxConcurrencyAttr>(S, St, A);
621+
return handleIntelFPGALoopAttr<SYCLIntelFPGAMaxConcurrencyAttr>(S, A);
617622
case ParsedAttr::AT_OpenCLUnrollHint:
618623
return handleLoopUnrollHint<OpenCLUnrollHintAttr>(S, St, A, Range);
619624
case ParsedAttr::AT_LoopUnrollHint:

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,11 @@ namespace {
952952
const LoopHintAttr *TransformLoopHintAttr(const LoopHintAttr *LH);
953953
const SYCLIntelFPGAIVDepAttr *
954954
TransformSYCLIntelFPGAIVDepAttr(const SYCLIntelFPGAIVDepAttr *IV);
955+
const SYCLIntelFPGAIIAttr *
956+
TransformSYCLIntelFPGAIIAttr(const SYCLIntelFPGAIIAttr *II);
957+
const SYCLIntelFPGAMaxConcurrencyAttr *
958+
TransformSYCLIntelFPGAMaxConcurrencyAttr(
959+
const SYCLIntelFPGAMaxConcurrencyAttr *MC);
955960

956961
ExprResult TransformPredefinedExpr(PredefinedExpr *E);
957962
ExprResult TransformDeclRefExpr(DeclRefExpr *E);
@@ -1356,6 +1361,23 @@ TemplateInstantiator::TransformSYCLIntelFPGAIVDepAttr(
13561361
return getSema().BuildSYCLIntelFPGAIVDepAttr(*IVDep, Expr1, Expr2);
13571362
}
13581363

1364+
const SYCLIntelFPGAIIAttr *TemplateInstantiator::TransformSYCLIntelFPGAIIAttr(
1365+
const SYCLIntelFPGAIIAttr *II) {
1366+
Expr *TransformedExpr =
1367+
getDerived().TransformExpr(II->getIntervalExpr()).get();
1368+
return getSema().BuildSYCLIntelFPGALoopAttr<SYCLIntelFPGAIIAttr>(
1369+
*II, TransformedExpr);
1370+
}
1371+
1372+
const SYCLIntelFPGAMaxConcurrencyAttr *
1373+
TemplateInstantiator::TransformSYCLIntelFPGAMaxConcurrencyAttr(
1374+
const SYCLIntelFPGAMaxConcurrencyAttr *MC) {
1375+
Expr *TransformedExpr =
1376+
getDerived().TransformExpr(MC->getNThreadsExpr()).get();
1377+
return getSema().BuildSYCLIntelFPGALoopAttr<SYCLIntelFPGAMaxConcurrencyAttr>(
1378+
*MC, TransformedExpr);
1379+
}
1380+
13591381
ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(
13601382
NonTypeTemplateParmDecl *parm,
13611383
SourceLocation loc,

clang/test/CodeGenSYCL/intel-fpga-loops.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
// CHECK: br label %for.cond, !llvm.loop ![[MD_A:[0-9]+]]
44
// CHECK: br label %for.cond, !llvm.loop ![[MD_B:[0-9]+]]
5+
// CHECK: br label %for.cond, !llvm.loop ![[MD_C:[0-9]+]]
6+
// CHECK: br label %for.cond2, !llvm.loop ![[MD_D:[0-9]+]]
7+
// CHECK: br label %for.cond, !llvm.loop ![[MD_E:[0-9]+]]
8+
// CHECK: br label %for.cond2, !llvm.loop ![[MD_F:[0-9]+]]
59

610
// CHECK: ![[MD_A]] = distinct !{![[MD_A]], ![[MD_ii:[0-9]+]]}
711
// CHECK-NEXT: ![[MD_ii]] = !{!"llvm.loop.ii.count", i32 2}
@@ -21,6 +25,36 @@ void zoo() {
2125
a[i] = 0;
2226
}
2327

28+
// CHECK: ![[MD_C]] = distinct !{![[MD_C]], ![[MD_ii_2:[0-9]+]]}
29+
// CHECK-NEXT: ![[MD_ii_2]] = !{!"llvm.loop.ii.count", i32 4}
30+
template <int A>
31+
void boo() {
32+
int a[10];
33+
[[intelfpga::ii(A)]]
34+
for (int i = 0; i != 10; ++i)
35+
a[i] = 0;
36+
// CHECK: ![[MD_D]] = distinct !{![[MD_D]], ![[MD_ii_3:[0-9]+]]}
37+
// CHECK-NEXT: ![[MD_ii_3]] = !{!"llvm.loop.ii.count", i32 8}
38+
[[intelfpga::ii(8)]]
39+
for (int i = 0; i != 10; ++i)
40+
a[i] = 0;
41+
}
42+
43+
// CHECK: ![[MD_E]] = distinct !{![[MD_E]], ![[MD_max_concurrency_2:[0-9]+]]}
44+
// CHECK-NEXT: ![[MD_max_concurrency_2]] = !{!"llvm.loop.max_concurrency.count", i32 0}
45+
template <int B>
46+
void foo() {
47+
int a[10];
48+
[[intelfpga::max_concurrency(B)]]
49+
for (int i = 0; i != 10; ++i)
50+
a[i] = 0;
51+
// CHECK: ![[MD_F]] = distinct !{![[MD_F]], ![[MD_max_concurrency_3:[0-9]+]]}
52+
// CHECK-NEXT: ![[MD_max_concurrency_3]] = !{!"llvm.loop.max_concurrency.count", i32 4}
53+
[[intelfpga::max_concurrency(4)]]
54+
for (int i = 0; i != 10; ++i)
55+
a[i] = 0;
56+
}
57+
2458
template <typename name, typename Func>
2559
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
2660
kernelFunc();
@@ -30,6 +64,8 @@ int main() {
3064
kernel_single_task<class kernel_function>([]() {
3165
goo();
3266
zoo();
67+
boo<4>();
68+
foo<0>();
3369
});
3470
return 0;
3571
}

clang/test/SemaSYCL/intel-fpga-loops.cpp

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,11 @@ void goo() {
6565
[[intelfpga::ivdep(0)]]
6666
for (int i = 0; i != 10; ++i)
6767
a[i] = 0;
68-
// expected-warning@+1 {{'ii' attribute requires a positive integral compile time constant expression - attribute ignored}}
68+
// expected-error@+1 {{'ii' attribute requires a positive integral compile time constant expression}}
6969
[[intelfpga::ii(0)]]
7070
for (int i = 0; i != 10; ++i)
7171
a[i] = 0;
72-
// expected-warning@+1 {{'max_concurrency' attribute requires a non-negative integral compile time constant expression - attribute ignored}}
72+
// expected-error@+1 {{'max_concurrency' attribute requires a non-negative integral compile time constant expression}}
7373
[[intelfpga::max_concurrency(-1)]]
7474
for (int i = 0; i != 10; ++i)
7575
a[i] = 0;
@@ -229,6 +229,36 @@ void ivdep_dependent() {
229229
};
230230
}
231231

232+
template <int A, int B, int C>
233+
void ii_dependent() {
234+
int a[10];
235+
// expected-error@+1 {{'ii' attribute requires a positive integral compile time constant expression}}
236+
[[intelfpga::ii(C)]]
237+
for (int i = 0; i != 10; ++i)
238+
a[i] = 0;
239+
240+
// expected-error@+1 {{duplicate Intel FPGA loop attribute 'ii'}}
241+
[[intelfpga::ii(A)]]
242+
[[intelfpga::ii(B)]]
243+
for (int i = 0; i != 10; ++i)
244+
a[i] = 0;
245+
}
246+
247+
template <int A, int B, int C>
248+
void max_concurrency_dependent() {
249+
int a[10];
250+
// expected-error@+1 {{'max_concurrency' attribute requires a non-negative integral compile time constant expression}}
251+
[[intelfpga::max_concurrency(C)]]
252+
for (int i = 0; i != 10; ++i)
253+
a[i] = 0;
254+
255+
// expected-error@+1 {{duplicate Intel FPGA loop attribute 'max_concurrency'}}
256+
[[intelfpga::max_concurrency(A)]]
257+
[[intelfpga::max_concurrency(B)]]
258+
for (int i = 0; i != 10; ++i)
259+
a[i] = 0;
260+
}
261+
232262
template <typename name, typename Func>
233263
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
234264
kernelFunc();
@@ -244,6 +274,10 @@ int main() {
244274
//expected-note@-1 +{{in instantiation of function template specialization}}
245275
ivdep_dependent<2, 4, -1>();
246276
//expected-note@-1 +{{in instantiation of function template specialization}}
277+
ii_dependent<2, 4, -1>();
278+
//expected-note@-1 +{{in instantiation of function template specialization}}
279+
max_concurrency_dependent<1, 4, -2>();
280+
//expected-note@-1 +{{in instantiation of function template specialization}}
247281
});
248282
return 0;
249283
}

0 commit comments

Comments
 (0)