Skip to content

Commit c536e76

Browse files
authored
[SYCL][FPGA] Add support for [[intel::loop_count()]] attribute (#5520)
The original implementation of this attribute in #3438, did not support the [[intel::loop_count()]] attribute spelling. This patch adds support for that spelling. Signed-off-by: Soumi Manna <[email protected]>
1 parent 00048b3 commit c536e76

File tree

6 files changed

+69
-15
lines changed

6 files changed

+69
-15
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2062,12 +2062,14 @@ def : MutualExclusions<[SYCLIntelFPGAMaxConcurrency,
20622062
def SYCLIntelFPGALoopCount : StmtAttr {
20632063
let Spellings = [CXX11<"intel", "loop_count_min">,
20642064
CXX11<"intel", "loop_count_max">,
2065-
CXX11<"intel", "loop_count_avg">];
2065+
CXX11<"intel", "loop_count_avg">,
2066+
CXX11<"intel", "loop_count">];
20662067
let Subjects = SubjectList<[ForStmt, CXXForRangeStmt, WhileStmt, DoStmt],
20672068
ErrorDiag, "'for', 'while', and 'do' statements">;
20682069
let Accessors = [Accessor<"isMin", [CXX11<"intel", "loop_count_min">]>,
20692070
Accessor<"isMax", [CXX11<"intel", "loop_count_max">]>,
2070-
Accessor<"isAvg", [CXX11<"intel", "loop_count_avg">]>];
2071+
Accessor<"isAvg", [CXX11<"intel", "loop_count_avg">]>,
2072+
Accessor<"isCount", [CXX11<"intel", "loop_count">]>];
20712073
let Args = [ExprArgument<"NTripCount">];
20722074
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
20732075
let IsStmtDependent = 1;

clang/include/clang/Basic/AttrDocs.td

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3270,7 +3270,7 @@ or ``ivdep``.
32703270

32713271
def SYCLIntelFPGALoopCountAttrDocs : Documentation {
32723272
let Category = DocCatVariable;
3273-
let Heading = "intel::loop_count_min, intel::loop_count_max, intel::loop_count_avg";
3273+
let Heading = "intel::loop_count_min, intel::loop_count_max, intel::loop_count_avg, intel::loop_count";
32743274
let Content = [{
32753275
The loop count attributes specify the minimum, maximum, or average number of
32763276
iterations for a ``for`` loop. These are hints that the user specify that can be
@@ -3288,10 +3288,15 @@ using PGO.
32883288
[[intel::loop_count_max(10)]] for (int i = 0; i < n; ++i) array[i] = 0;
32893289
}
32903290

3291+
void count(int *array, size_t n) {
3292+
[[intel::loop_count(20)]] for (int i = 0; i < n; ++i) array[i] = 0;
3293+
}
3294+
32913295
void goo(int *array, size_t n) {
32923296
[[intel::loop_count_min(3)]]
32933297
[[intel::loop_count_max(10)]]
32943298
[[intel::loop_count_avg(5)]]
3299+
[[intel::loop_count(20)]]
32953300
for (int i = 0; i < n; ++i) array[i] = 0;
32963301
}
32973302

@@ -3300,6 +3305,10 @@ using PGO.
33003305
[[intel::loop_count_avg(N)]] for(;;) { }
33013306
}
33023307

3308+
template<int A>
3309+
void func() {
3310+
[[intel::loop_count(A)]] for(;;) { }
3311+
}
33033312
}];
33043313
}
33053314

clang/lib/CodeGen/CGLoopInfo.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,11 +1036,11 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
10361036
const auto *CE =
10371037
cast<ConstantExpr>(IntelFPGALoopCountAvg->getNTripCount());
10381038
llvm::APSInt ArgVal = CE->getResultAsAPSInt();
1039-
const char *Var = IntelFPGALoopCountAvg->isMax()
1040-
? "llvm.loop.intel.loopcount_max"
1041-
: IntelFPGALoopCountAvg->isMin()
1042-
? "llvm.loop.intel.loopcount_min"
1043-
: "llvm.loop.intel.loopcount_avg";
1039+
const char *Var =
1040+
IntelFPGALoopCountAvg->isMax() ? "llvm.loop.intel.loopcount_max"
1041+
: IntelFPGALoopCountAvg->isMin() ? "llvm.loop.intel.loopcount_min"
1042+
: IntelFPGALoopCountAvg->isAvg() ? "llvm.loop.intel.loopcount_avg"
1043+
: "llvm.loop.intel.loopcount";
10441044
setSYCLIntelFPGAVariantCount(Var, ArgVal.getSExtValue());
10451045
}
10461046

clang/lib/Sema/SemaStmtAttr.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,14 @@ CheckForDuplicateSYCLIntelLoopCountAttrs(Sema &S,
399399
unsigned int MinCount = 0;
400400
unsigned int MaxCount = 0;
401401
unsigned int AvgCount = 0;
402+
unsigned int Count = 0;
402403
for (const auto *A : OnlyLoopCountAttrs) {
403404
const auto *At = dyn_cast<SYCLIntelFPGALoopCountAttr>(A);
404-
At->isMin() ? MinCount++ : At->isMax() ? MaxCount++ : AvgCount++;
405-
if (MinCount > 1 || MaxCount > 1 || AvgCount > 1)
405+
At->isMin() ? MinCount++
406+
: At->isMax() ? MaxCount++
407+
: At->isAvg() ? AvgCount++
408+
: Count++;
409+
if (MinCount > 1 || MaxCount > 1 || AvgCount > 1 || Count > 1)
406410
S.Diag(A->getLocation(), diag::err_sycl_loop_attr_duplication) << 1 << A;
407411
}
408412
}

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
// CHECK: br label %for.cond, !llvm.loop ![[MD_LCA:[0-9]+]]
2020
// CHECK: br label %for.cond2, !llvm.loop ![[MD_LCA_1:[0-9]+]]
2121
// CHECK: br label %for.cond13, !llvm.loop ![[MD_LCA_2:[0-9]+]]
22+
// CHECK: br label %for.cond24, !llvm.loop ![[MD_LCA_3:[0-9]+]]
2223

2324
void disable_loop_pipelining() {
2425
int a[10];
@@ -136,11 +137,16 @@ void loop_count_control() {
136137
// CHECK-NEXT: ![[MD_loop_count_max]] = !{!"llvm.loop.intel.loopcount_max", i32 4}
137138
[[intel::loop_count_max(4)]] for (int i = 0; i != 10; ++i)
138139
a[i] = 0;
139-
// CHECK: ![[MD_LCA_2]] = distinct !{![[MD_LCA_2]], ![[MP:[0-9]+]], ![[MD_loop_count_min:[0-9]+]], ![[MD_loop_count_max_1:[0-9]+]], ![[MD_loop_count_avg_1:[0-9]+]]}
140+
// CHECK: ![[MD_LCA_2]] = distinct !{![[MD_LCA_2]], ![[MP:[0-9]+]], ![[MD_loop_count_min:[0-9]+]], ![[MD_loop_count_max_1:[0-9]+]], ![[MD_loop_count_avg_1:[0-9]+]], ![[MD_loop_count:[0-9]+]]}
140141
// CHECK: ![[MD_loop_count_min]] = !{!"llvm.loop.intel.loopcount_min", i32 4}
141142
// CHECK: ![[MD_loop_count_max_1]] = !{!"llvm.loop.intel.loopcount_max", i32 40}
142-
// CHECK-NEXT: ![[MD_loop_count_avg_1]] = !{!"llvm.loop.intel.loopcount_avg", i32 21}
143-
[[intel::loop_count_min(4)]] [[intel::loop_count_max(40)]] [[intel::loop_count_avg(21)]] for (int i = 0; i != 10; ++i)
143+
// CHECK: ![[MD_loop_count_avg_1]] = !{!"llvm.loop.intel.loopcount_avg", i32 21}
144+
// CHECK-NEXT: ![[MD_loop_count]] = !{!"llvm.loop.intel.loopcount", i32 30}
145+
[[intel::loop_count_min(4)]] [[intel::loop_count_max(40)]] [[intel::loop_count_avg(21)]] [[intel::loop_count(30)]] for (int i = 0; i != 10; ++i)
146+
a[i] = 0;
147+
// CHECK: ![[MD_LCA_3]] = distinct !{![[MD_LCA_3]], ![[MP:[0-9]+]], ![[MD_loop_count_1:[0-9]+]]}
148+
// CHECK-NEXT: ![[MD_loop_count_1]] = !{!"llvm.loop.intel.loopcount", i32 12}
149+
[[intel::loop_count(A)]] for (int i = 0; i != 10; ++i)
144150
a[i] = 0;
145151
}
146152

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

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ void foo() {
2323
// expected-error@+1 {{'nofusion' attribute cannot be applied to a declaration}}
2424
[[intel::nofusion]] int k[10];
2525
// expected-error@+1{{'loop_count_avg' attribute cannot be applied to a declaration}}
26-
[[intel::loop_count_avg(6)]] int p[10];
26+
[[intel::loop_count_avg(6)]] int l[10];
27+
// expected-error@+1{{'loop_count' attribute cannot be applied to a declaration}}
28+
[[intel::loop_count(8)]] int m[10];
2729
}
2830

2931
// Test for deprecated spelling of Intel FPGA loop attributes
@@ -115,7 +117,10 @@ void boo() {
115117
[[intel::nofusion(0)]] for (int i = 0; i != 10; ++i)
116118
a[i] = 0;
117119
// expected-error@+1 {{'loop_count_avg' attribute takes one argument}}
118-
[[intel::loop_count_avg(3, 6)]] for (int i = 0; i != 10; ++i)
120+
[[intel::loop_count_avg(3, 6)]] for (int i = 0; i != 10; ++i)
121+
a[i] = 0;
122+
// expected-error@+1 {{'loop_count' attribute takes one argument}}
123+
[[intel::loop_count(6, 9)]] for (int i = 0; i != 10; ++i)
119124
a[i] = 0;
120125
}
121126

@@ -203,6 +208,14 @@ void goo() {
203208
// expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'const char[4]'}}
204209
[[intel::loop_count_avg("abc")]] for (int i = 0; i != 10; ++i)
205210
a[i] = 0;
211+
// expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'const char[4]'}}
212+
[[intel::loop_count("abc")]] for (int i = 0; i != 10; ++i)
213+
a[i] = 0;
214+
[[intel::loop_count(0)]] for (int i = 0; i != 10; ++i)
215+
a[i] = 0;
216+
// expected-error@+1 {{'loop_count' attribute requires a non-negative integral compile time constant expression}}
217+
[[intel::loop_count(-1)]] for (int i = 0; i != 10; ++i)
218+
a[i] = 0;
206219
}
207220

208221
// Test for Intel FPGA loop attributes duplication
@@ -316,6 +329,11 @@ void zoo() {
316329
// expected-error@+1{{duplicate Intel FPGA loop attribute 'loop_count_avg'}}
317330
[[intel::loop_count_avg(2)]] for (int i = 0; i != 10; ++i)
318331
a[i] = 0;
332+
333+
[[intel::loop_count(2)]]
334+
// expected-error@+1{{duplicate Intel FPGA loop attribute 'loop_count'}}
335+
[[intel::loop_count(2)]] for (int i = 0; i != 10; ++i)
336+
a[i] = 0;
319337
}
320338

321339
// Test for Intel FPGA loop attributes compatibility
@@ -365,6 +383,8 @@ void loop_attrs_compatibility() {
365383
[[intel::loop_count_max(8)]]
366384
for (int i = 0; i != 10; ++i)
367385
a[i] = 0;
386+
[[intel::loop_count(8)]] for (int i = 0; i != 10; ++i)
387+
a[i] = 0;
368388
}
369389

370390
template<int A, int B, int C>
@@ -499,6 +519,10 @@ void loop_count_control_dependent() {
499519
for (int i = 0; i != 10; ++i)
500520
a[i] = 0;
501521

522+
// expected-error@+1{{'loop_count' attribute requires a non-negative integral compile time constant expression}}
523+
[[intel::loop_count(C)]] for (int i = 0; i != 10; ++i)
524+
a[i] = 0;
525+
502526
[[intel::loop_count_avg(A)]]
503527
//expected-error@+1{{duplicate Intel FPGA loop attribute 'loop_count_avg'}}
504528
[[intel::loop_count_avg(B)]] for (int i = 0; i != 10; ++i)
@@ -514,6 +538,10 @@ void loop_count_control_dependent() {
514538
[[intel::loop_count_max(B)]] for (int i = 0; i != 10; ++i)
515539
a[i] = 0;
516540

541+
[[intel::loop_count(A)]]
542+
// expected-error@+1{{duplicate Intel FPGA loop attribute 'loop_count'}}
543+
[[intel::loop_count(B)]] for (int i = 0; i != 10; ++i)
544+
a[i] = 0;
517545
}
518546

519547
void check_max_concurrency_expression() {
@@ -648,6 +676,11 @@ void check_loop_attr_template_instantiation() {
648676
// expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'float'}}
649677
[[intel::loop_count_min(Ty{})]] for (int i = 0; i != 10; ++i)
650678
a[i] = 0;
679+
680+
// expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'S'}}
681+
// expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'float'}}
682+
[[intel::loop_count(Ty{})]] for (int i = 0; i != 10; ++i)
683+
a[i] = 0;
651684
}
652685

653686
int main() {

0 commit comments

Comments
 (0)