forked from OSchip/llvm-project
106 lines
2.9 KiB
ReStructuredText
106 lines
2.9 KiB
ReStructuredText
.. title:: clang-tidy - altera-unroll-loops
|
|
|
|
altera-unroll-loops
|
|
===================
|
|
|
|
Finds inner loops that have not been unrolled, as well as fully unrolled loops
|
|
with unknown loop bounds or a large number of iterations.
|
|
|
|
Unrolling inner loops could improve the performance of OpenCL kernels. However,
|
|
if they have unknown loop bounds or a large number of iterations, they cannot
|
|
be fully unrolled, and should be partially unrolled.
|
|
|
|
Notes:
|
|
|
|
- This check is unable to determine the number of iterations in a ``while`` or
|
|
``do..while`` loop; hence if such a loop is fully unrolled, a note is emitted
|
|
advising the user to partially unroll instead.
|
|
|
|
- In ``for`` loops, our check only works with simple arithmetic increments (
|
|
``+``, ``-``, ``*``, ``/``). For all other increments, partial unrolling is
|
|
advised.
|
|
|
|
- Depending on the exit condition, the calculations for determining if the
|
|
number of iterations is large may be off by 1. This should not be an issue
|
|
since the cut-off is generally arbitrary.
|
|
|
|
Based on the `Altera SDK for OpenCL: Best Practices Guide
|
|
<https://www.altera.com/en_US/pdfs/literature/hb/opencl-sdk/aocl_optimization_guide.pdf>`_.
|
|
|
|
.. code-block:: c++
|
|
|
|
for (int i = 0; i < 10; i++) { // ok: outer loops should not be unrolled
|
|
int j = 0;
|
|
do { // warning: this inner do..while loop should be unrolled
|
|
j++;
|
|
} while (j < 15);
|
|
|
|
int k = 0;
|
|
#pragma unroll
|
|
while (k < 20) { // ok: this inner loop is already unrolled
|
|
k++;
|
|
}
|
|
}
|
|
|
|
int A[1000];
|
|
#pragma unroll
|
|
// warning: this loop is large and should be partially unrolled
|
|
for (int a : A) {
|
|
printf("%d", a);
|
|
}
|
|
|
|
#pragma unroll 5
|
|
// ok: this loop is large, but is partially unrolled
|
|
for (int a : A) {
|
|
printf("%d", a);
|
|
}
|
|
|
|
#pragma unroll
|
|
// warning: this loop is large and should be partially unrolled
|
|
for (int i = 0; i < 1000; ++i) {
|
|
printf("%d", i);
|
|
}
|
|
|
|
#pragma unroll 5
|
|
// ok: this loop is large, but is partially unrolled
|
|
for (int i = 0; i < 1000; ++i) {
|
|
printf("%d", i);
|
|
}
|
|
|
|
#pragma unroll
|
|
// warning: << operator not supported, recommend partial unrolling
|
|
for (int i = 0; i < 1000; i<<1) {
|
|
printf("%d", i);
|
|
}
|
|
|
|
std::vector<int> someVector (100, 0);
|
|
int i = 0;
|
|
#pragma unroll
|
|
// note: loop may be large, recommend partial unrolling
|
|
while (i < someVector.size()) {
|
|
someVector[i]++;
|
|
}
|
|
|
|
#pragma unroll
|
|
// note: loop may be large, recommend partial unrolling
|
|
while (true) {
|
|
printf("In loop");
|
|
}
|
|
|
|
#pragma unroll 5
|
|
// ok: loop may be large, but is partially unrolled
|
|
while (i < someVector.size()) {
|
|
someVector[i]++;
|
|
}
|
|
|
|
Options
|
|
-------
|
|
|
|
.. option:: MaxLoopIterations
|
|
|
|
Defines the maximum number of loop iterations that a fully unrolled loop
|
|
can have. By default, it is set to `100`.
|
|
|
|
In practice, this refers to the integer value of the upper bound
|
|
within the loop statement's condition expression.
|