Previous: Cleanups, Up: Statements

11.7.7 OpenMP

All the statements starting with OMP_ represent directives and clauses used by the OpenMP API

Represents #pragma omp parallel [clause1 ... clauseN]. It has four operands:

Operand OMP_PARALLEL_BODY is valid while in GENERIC and High GIMPLE forms. It contains the body of code to be executed by all the threads. During GIMPLE lowering, this operand becomes NULL and the body is emitted linearly after OMP_PARALLEL.

Operand OMP_PARALLEL_CLAUSES is the list of clauses associated with the directive.

Operand OMP_PARALLEL_FN is created by pass_lower_omp, it contains the FUNCTION_DECL for the function that will contain the body of the parallel region.

Operand OMP_PARALLEL_DATA_ARG is also created by pass_lower_omp. If there are shared variables to be communicated to the children threads, this operand will contain the VAR_DECL that contains all the shared values and variables.

Represents #pragma omp for [clause1 ... clauseN]. It has 5 operands:

Operand OMP_FOR_BODY contains the loop body.

Operand OMP_FOR_CLAUSES is the list of clauses associated with the directive.

Operand OMP_FOR_INIT is the loop initialization code of the form VAR = N1.

Operand OMP_FOR_COND is the loop conditional expression of the form VAR {<,>,<=,>=} N2.

Operand OMP_FOR_INCR is the loop index increment of the form VAR {+=,-=} INCR.

Operand OMP_FOR_PRE_BODY contains side-effect code from operands OMP_FOR_INIT, OMP_FOR_COND and OMP_FOR_INC. These side-effects are part of the OMP_FOR block but must be evaluated before the start of loop body.

The loop index variable VAR must be a signed integer variable, which is implicitly private to each thread. 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 unspecified by the standard.

Represents #pragma omp sections [clause1 ... clauseN].

Operand OMP_SECTIONS_BODY contains the sections body, which in turn contains a set of OMP_SECTION nodes for each of the concurrent sections delimited by #pragma omp section.

Operand OMP_SECTIONS_CLAUSES is the list of clauses associated with the directive.

Section delimiter for OMP_SECTIONS.
Represents #pragma omp single.

Operand OMP_SINGLE_BODY contains the body of code to be executed by a single thread.

Operand OMP_SINGLE_CLAUSES is the list of clauses associated with the directive.

Represents #pragma omp master.

Operand OMP_MASTER_BODY contains the body of code to be executed by the master thread.

Represents #pragma omp ordered.

Operand OMP_ORDERED_BODY contains the body of code to be executed in the sequential order dictated by the loop index variable.

Represents #pragma omp critical [name].

Operand OMP_CRITICAL_BODY is the critical section.

Operand OMP_CRITICAL_NAME is an optional identifier to label the critical section.

This does not represent any OpenMP directive, it is an artificial marker to indicate the end of the body of an OpenMP. It is used by the flow graph (tree-cfg.c) and OpenMP region building code (omp-low.c).
Similarly, this instruction does not represent an OpenMP directive, it is used by OMP_FOR and OMP_SECTIONS to mark the place where the code needs to loop to the next iteration (in the case of OMP_FOR) or the next section (in the case of OMP_SECTIONS).

In some cases, OMP_CONTINUE is placed right before OMP_RETURN. But if there are cleanups that need to occur right after the looping body, it will be emitted between OMP_CONTINUE and OMP_RETURN.

Represents #pragma omp atomic.

Operand 0 is the address at which the atomic operation is to be performed.

Operand 1 is the expression to evaluate. The gimplifier tries three alternative code generation strategies. Whenever possible, an atomic update built-in is used. If that fails, a compare-and-swap loop is attempted. If that also fails, a regular critical section around the expression is used.

Represents clauses associated with one of the OMP_ directives. Clauses are represented by separate sub-codes defined in tree.h. Clauses codes can be one of: OMP_CLAUSE_PRIVATE, OMP_CLAUSE_SHARED, OMP_CLAUSE_FIRSTPRIVATE, OMP_CLAUSE_LASTPRIVATE, OMP_CLAUSE_COPYIN, OMP_CLAUSE_COPYPRIVATE, OMP_CLAUSE_IF, OMP_CLAUSE_NUM_THREADS, OMP_CLAUSE_SCHEDULE, OMP_CLAUSE_NOWAIT, OMP_CLAUSE_ORDERED, OMP_CLAUSE_DEFAULT, and OMP_CLAUSE_REDUCTION. Each code represents the corresponding OpenMP clause.

Clauses associated with the same directive are chained together via OMP_CLAUSE_CHAIN. Those clauses that accept a list of variables are restricted to exactly one, accessed with OMP_CLAUSE_VAR. Therefore, multiple variables under the same clause C need to be represented as multiple C clauses chained together. This facilitates adding new clauses during compilation.