commit 9a0fa0b9429882eca17849a64592b697ca4e2bf9 Author: Sandra Loosemore Date: Tue Mar 21 22:15:33 2023 +0000 Docs, OpenMP: Correct internal documentation of OMP_FOR. gcc/ChangeLog: * doc/generic.texi (OpenMP): Document OMP_SIMD, OMP_DISTRIBUTE, OMP_TASKLOOP, and OMP_LOOP with OMP_FOR. Document how collapsed loops are represented and which fields are vectors. Add documentation for OMP_FOR_PRE_BODY field. Document internal form of non-rectangular loops and OMP_FOR_NON_RECTANGULAR. * tree.def (OMP_FOR): Make documentation consistent with the Texinfo manual, to fill some gaps and correct errors. diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi index ad1270f9025..2c14b7abce2 100644 --- a/gcc/doc/generic.texi +++ b/gcc/doc/generic.texi @@ -2253,6 +2253,10 @@ edge. Rethrowing the exception is represented using @code{RESX_EXPR}. @subsection OpenMP @tindex OMP_PARALLEL @tindex OMP_FOR +@tindex OMP_SIMD +@tindex OMP_DISTRIBUTE +@tindex OMP_TASKLOOP +@tindex OMP_LOOP @tindex OMP_SECTIONS @tindex OMP_SINGLE @tindex OMP_SECTION @@ -2294,37 +2298,71 @@ the @code{VAR_DECL} that contains all the shared values and variables. @item OMP_FOR +@itemx OMP_SIMD +@itemx OMP_DISTRIBUTE +@itemx OMP_TASKLOOP +@itemx OMP_LOOP -Represents @code{#pragma omp for [clause1 @dots{} clauseN]}. It has -six operands: +Represents @code{#pragma omp for [clause1 @dots{} clauseN]} and +related loop constructs (respectively). + +A single @code{OMP_FOR} node represents an entire nest of collapsed +loops; as noted below, some of its arguments are vectors of length +equal to the collapse depth, and the corresponding elements holding +data specific to a particular loop in the nest. These vectors are +numbered from the outside in so that the outermost loop is element 0. + +These constructs have seven operands: Operand @code{OMP_FOR_BODY} contains the loop body. Operand @code{OMP_FOR_CLAUSES} is the list of clauses associated with the directive. -Operand @code{OMP_FOR_INIT} is the loop initialization code of -the form @code{VAR = N1}. +Operand @code{OMP_FOR_INIT} is a vector containing iteration +variable initializations of the form @code{VAR = N1}. -Operand @code{OMP_FOR_COND} is the loop conditional expression -of the form @code{VAR @{<,>,<=,>=@} N2}. +Operand @code{OMP_FOR_COND} is vector containing loop +conditional expressions of the form @code{VAR @{<,>,<=,>=@} N2}. -Operand @code{OMP_FOR_INCR} is the loop index increment of the -form @code{VAR @{+=,-=@} INCR}. +Operand @code{OMP_FOR_INCR} is a vector containing loop index +increment expressions of the form @code{VAR @{+=,-=@} INCR}. Operand @code{OMP_FOR_PRE_BODY} contains side effect code from operands @code{OMP_FOR_INIT}, @code{OMP_FOR_COND} and -@code{OMP_FOR_INC}. These side effects are part of the +@code{OMP_FOR_INCR}. These side effects are part of the @code{OMP_FOR} block but must be evaluated before the start of -loop body. +loop body. @code{OMP_FOR_PRE_BODY} specifically +includes @code{DECL_EXPR}s for iteration variables that are +declared in the nested @code{for} loops. +Note this field is not a vector; it may be null, but otherwise is +usually a statement list collecting the side effect code from all +the collapsed loops. + +Operand @code{OMP_FOR_ORIG_DECLS} holds @code{VAR_DECLS} for the +original user-specified iterator variables in the source code. +In some cases, like C++ class iterators or range @code{for} with +decomposition, the @code{for} loop is rewritten by the front end to +use a temporary iteration variable. The purpose of this field is to +make the original variables available to the gimplifier so it can +adjust their data-sharing attributes and diagnose errors. +@code{OMP_FOR_ORIG_DECLS} is a vector field, with each element holding +a list of @code{VAR_DECLS} for the corresponding collapse level. The loop index variable @code{VAR} must be a signed integer variable, -which is implicitly private to each thread. Bounds -@code{N1} and @code{N2} and the increment expression -@code{INCR} are required to be loop invariant integer -expressions that are evaluated without any synchronization. The -evaluation order, frequency of evaluation and side effects are -unspecified by the standard. +which is implicitly private to each thread. For rectangular loops, +the bounds @code{N1} and @code{N2} and the increment expression +@code{INCR} are required to be loop-invariant integer expressions +that are evaluated without any synchronization. The evaluation order, +frequency of evaluation and side effects are otherwise unspecified +by the standard. + +For non-rectangular loops, in which the bounds of an inner loop depend +on the index of an outer loop, the bit @code{OMP_FOR_NON_RECTANGULAR} +must be set. In this case @code{N1} and @code{N2} are not ordinary +expressions, but instead a @code{TREE_VEC} with three elements: +the @code{DECL} for the outer loop variable, a multiplication +factor, and an offset. @item OMP_SECTIONS diff --git a/gcc/tree.def b/gcc/tree.def index e639a039db9..ee02754354f 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -1141,29 +1141,65 @@ DEFTREECODE (OMP_PARALLEL, "omp_parallel", tcc_statement, 2) DEFTREECODE (OMP_TASK, "omp_task", tcc_statement, 2) /* OpenMP - #pragma omp for [clause1 ... clauseN] - Operand 0: OMP_FOR_BODY: Loop body. - Operand 1: OMP_FOR_CLAUSES: List of clauses. - Operand 2: OMP_FOR_INIT: Initialization code of the form - VAR = N1. - Operand 3: OMP_FOR_COND: Loop conditional expression of the form - VAR { <, >, <=, >= } N2. - Operand 4: OMP_FOR_INCR: Loop index increment of the form - VAR { +=, -= } INCR. - Operand 5: OMP_FOR_PRE_BODY: Filled by the gimplifier with things - from INIT, COND, and INCR that are technically part of the - OMP_FOR structured block, but are evaluated before the loop - body begins. - Operand 6: OMP_FOR_ORIG_DECLS: If non-NULL, list of DECLs initialized - in OMP_FOR_INIT. In some cases, like C++ iterators, the original - DECL init has been lost in gimplification and now contains a - temporary (D.nnnn). This list contains the original DECLs in - the source. - - VAR must be an integer or pointer variable, which is implicitly thread - private. N1, N2 and INCR are required to be loop invariant integer - expressions that are evaluated without any synchronization. - The evaluation order, frequency of evaluation and side-effects are - unspecified by the standards. */ + + A single OMP_FOR node represents an entire nest of collapsed + loops; as noted below, some of its arguments are vectors of length + equal to the collapse depth, and the corresponding elements holding + data specific to a particular loop in the nest. These vectors are + numbered from the outside in so that the outermost loop is element 0. + + These constructs have seven operands: + + Operand 0: OMP_FOR_BODY contains the loop body. + + Operand 1: OMP_FOR_CLAUSES is the list of clauses + associated with the directive. + + Operand 2: OMP_FOR_INIT is a vector containing iteration + variable initializations of the form VAR = N1. + + Operand 3: OMP_FOR_COND is vector containing loop + conditional expressions of the form VAR {<,>,<=,>=} N2. + + Operand 4: OMP_FOR_INCR is a vector containing loop index + increment expressions of the form VAR {+=,-=} INCR. + + Operand 5: OMP_FOR_PRE_BODY contains side effect code from + operands OMP_FOR_INIT, OMP_FOR_COND and + OMP_FOR_INCR. These side effects are part of the + OMP_FOR block but must be evaluated before the start of + loop body. OMP_FOR_PRE_BODY specifically + includes DECL_EXPRs for iteration variables that are + declared in the nested for loops. + Note this field is not a vector; it may be null, but otherwise is + usually a statement list collecting the side effect code from all + the collapsed loops. + + Operand 6: OMP_FOR_ORIG_DECLS holds VAR_DECLS for the + original user-specified iterator variables in the source code. + In some cases, like C++ class iterators or range for with + decomposition, the for loop is rewritten by the front end to + use a temporary iteration variable. The purpose of this field is to + make the original variables available to the gimplifier so it can + adjust their data-sharing attributes and diagnose errors. + OMP_FOR_ORIG_DECLS is a vector field, with each element holding + a list of VAR_DECLS for the corresponding collapse level. + + The loop index variable VAR must be a signed integer variable, + which is implicitly private to each thread. For rectangular loops, + the bounds N1 and N2 and the increment expression + INCR are required to be loop-invariant integer expressions + that are evaluated without any synchronization. The evaluation order, + frequency of evaluation and side effects are otherwise unspecified + by the standard. + + For non-rectangular loops, in which the bounds of an inner loop depend + on the index of an outer loop, the bit OMP_FOR_NON_RECTANGULAR + must be set. In this case N1 and N2 are not ordinary + expressions, but instead a TREE_VEC with three elements: + the DECL for the outer loop variable, a multiplication + factor, and an offset. */ + DEFTREECODE (OMP_FOR, "omp_for", tcc_statement, 7) /* OpenMP - #pragma omp simd [clause1 ... clauseN]