A loop nest has canonical loop nest form if it conforms to loop-nest in the following grammar:
Symbol
Meaning
loop-nest
One of the following:
for(init-expr;test-expr;incr-expr) loop-body
or
for(range-decl:range-expr) loop-body
A range-based for loop is equivalent to a regular for loop using iterators, as defined in the base language.
A range-based for loop has no iteration variable.
A generated loop from a loop transformation construct that has canonical loop
nest form and for which the loop body matches loop-body.
intervening-code
A structured block sequence that does not contain OpenMP directives or calls to the
OpenMP runtime API in its corresponding region, referred to as intervening code. If intervening code
is present, then a loop at the same depth within the loop nest is not a perfectly nested loop.
It must not contain iteration statements, continue statements or break statements that apply to the
enclosing loop.
It must not contain loops, array expressions, CYCLE statements or EXIT statements.
final-loop-body
A structured block that terminates the scope of loops in the loop nest. If the loop nest is
associated with a loop-associated directive, loops in this structured block cannot be associated with that
directive.
init-expr
One of the following:
var
=
lb
integer-typevar
=
lb
pointer-typevar
=
lb
random-access-iterator-typevar
=
lb
test-expr
One of the following:
varrelational-opub
ubrelational-opvar
relational-op
One of the following:
<
<=
>
>=
!=
incr-expr
One of the following:
++var
var++
-
-
var
var
-
-
var
+=
incr
var
-
=
incr
var
=
var
+
incr
var
=
incr
+
var
var
=
var
-
incr
The value of incr, respectively 1 and -1 for the increment and decrement operators, is the increment of the
loop.
var
One of the following:
A
variable
of
a
signed
or
unsigned
integer
type.
A
variable
of
a
pointer
type.
A
variable
of
a
random
access
iterator
type.
A
variable
of
integer
type.
var is the iteration variable of the loop. It must not be modified during the execution of intervening-code or
loop-body in the loop.
lb, ub
One of the following:
Expressions of a type compatible with the type of var that are loop invariant with respect to the outermost
loop.
or
One of the following:
var-outer
var-outer
+
a2
a2
+
var-outer
var-outer
-
a2
where var-outer is of a type compatible with the type of var.
or
If var is of an integer type, one of the following:
a2
-
var-outer
a1
*
var-outer
a1
*
var-outer
+
a2
a2
+
a1
*
var-outer
a1
*
var-outer
-
a2
a2
-
a1
*
var-outer
var-outer
*
a1
var-outer
*
a1
+
a2
a2
+
var-outer
*
a1
var-outer
*
a1
-
a2
a2
-
var-outer
*
a1
where var-outer is of an integer type.
lb and ub are loop bounds. A loop for which lb or ub refers to var-outer is a non-rectangular loop. If var is of
an integer type, var-outer must be of an integer type with the same signedness and bit precision as the type
of var.
The coefficient in a loop bound is 0 if the bound does not refer to var-outer. If a loop bound
matches a form in which a1 appears, the coefficient is -a1 if the product of var-outer and a1 is
subtracted from a2, and otherwise the coefficient is a1. For other matched forms where a1 does not
appear, the coefficient is -1 if var-outer is subtracted from a2, and otherwise the coefficient is 1.
a1, a2, incr
Integer expressions that are loop invariant with respect to the outermost loop of the loop
nest.
If the loop is associated with a loop-associated directive, the expressions are evaluated before the construct
formed from that directive.
var-outer
The loop iteration variable of a surrounding loop in the loop nest.
range-decl
A declaration of a variable as defined by the base language for range-based for
loops.
range-expr
An expression that is valid as defined by the base language for range-based for loops. It must
be invariant with respect to the outermost loop of the loop nest and the iterator derived from it must be a
random access iterator.
A loop transformation construct that appears inside a loop nest is replaced according to its semantics before
any loop can be associated with a loop-associated directive that is applied to the loop nest. The depth of the
loop nest is determined according to the loops in the loop nest, after any such replacements have taken
place. A loop counts towards the depth of the loop nest if it is a base language loop statement or generated
loop and it matches loop-nest while applying the production rules for canonical loop nest form to the loop
nest.
A loop-associated directive controls some number of the outermost loops of an associated loop nest, called
the associated loops, in accordance with its specified clauses. The canonical loop nest form
allows the iteration count of all associated loops to be computed before executing the outermost
loop.
For any associated loop, the iteration count is computed as follows:
If
var
has
a
signed
integer
type
and
the
var
operand
of
test-expr
after
usual
arithmetic
conversions
has
an
unsigned
integer
type
then
the
loop
iteration
count
is
computed
from
lb,
test-expr
and
incr
using
an
unsigned
integer
type
corresponding
to
the
type
of
var.
Otherwise,
if
var
has
an
integer
type
then
the
loop
iteration
count
is
computed
from
lb,
test-expr
and
incr
using
the
type
of
var.
If
var
has
a
pointer
type
then
the
loop
iteration
count
is
computed
from
lb,
test-expr
and
incr
using
the
type
ptrdiff_t.
If
var
has
a
random
access
iterator
type
then
the
loop
iteration
count
is
computed
from
lb,
test-expr
and
incr
using
the
type
std::iterator_traits<random-access-iterator-type>::difference_type.
For
range-based
for
loops,
the
loop
iteration
count
is
computed
from
range-expr
using
the
type
std::iterator_traits<random-access-iterator-type>::difference_type
where
random-access-iterator-type
is
the
iterator
type
derived
from
range-expr.
The
loop
iteration
count
is
computed
from
lb,
ub
and
incr
using
the
type
of
var.
The behavior is unspecified if any intermediate result required to compute the iteration count cannot be
represented in the type determined above.
No synchronization is implied during the evaluation of the lb, ub, incr or range-expr expressions. Whether,
in what order, or how many times any side effects within the lb, ub, incr, or range-expr expressions occur is
unspecified.
The iterations of some number of associated loops can be collapsed into one larger iteration space that is
called the logical iteration space. The particular integer type used to compute the iteration count for the
collapsed loop is implementation defined.
For directives that result in the execution of a collapsed logical iteration space, the number of times that any
intervening code between any two loops of the same logical iteration space will be executed is unspecified
but will be the same for all intervening code at the same depth, at least once per iteration of
the loop enclosing the intervening code and at most once per logical iteration. If the iteration
count of any loop is zero and that loop does not enclose the intervening code, the behavior is
unspecified.
Restrictions
Restrictions to canonical loop nests are as follows:
If
test-expr
is
of
the
form
varrelational-opb
and
relational-op
is
<
or
<=
then
incr-expr
must
cause
var
to
increase
on
each
iteration
of
the
loop.
If
test-expr
is
of
the
form
varrelational-opb
and
relational-op
is
>
or
>=
then
incr-expr
must
cause
var
to
decrease
on
each
iteration
of
the
loop.
Increase
and
decrease
are
using
the
order
induced
by
relational-op.
If
test-expr
is
of
the
form
ubrelational-opvar
and
relational-op
is
<
or
<=
then
incr-expr
must
cause
var
to
decrease
on
each
iteration
of
the
loop.
If
test-expr
is
of
the
form
ubrelational-opvar
and
relational-op
is
>
or
>=
then
incr-expr
must
cause
var
to
increase
on
each
iteration
of
the
loop.
Increase
and
decrease
are
using
the
order
induced
by
relational-op.
If
relational-op
is
!=
then
incr-expr
must
cause
var
to
always
increase
by
1
or
always
decrease
by
1
and
the
increment
must
be
a
constant
expression.
final-loop-body
must
not
contain
any
break
statement
that
would
cause
the
termination
of
the
innermost
loop.
final-loop-body
must
not
contain
any
EXIT
statement
that
would
cause
the
termination
of
the
innermost
loop.
A
loop-nest
must
also
be
a
structured
block.
For
a
non-rectangular
loop,
if
var-outer
is
referenced
in
lb
and
ub
then
they
must
both
refer
to
the
same
iteration
variable.
For
a
non-rectangular
loop,
let
a1lb
and
a1ub
be
the
respective
coefficients
in
lb
and
ub,
incrinner
the
increment
of
the
non-rectangular
loop
and
incrouter
the
increment
of
the
loop
referenced
by
var-outer.
incrinner(a1ub- a1lb)
must
be
a
multiple
of
incrouter.
The
loop
iteration
variable
may
not
appear
in
a
threadprivate
directive.
Cross References
Loop
transformation
constructs,
see
Section 2.11.9.