commit ec6a05ed9ff15b4fc458c668cfd5227a1506042b
Author: David Malcolm <dmalcolm@redhat.com>
Date: Tue Nov 5 04:30:15 2013 -0500
Ensure every gimple code has a subclasses; document.
Add empty subclasses to gimple.h as appropriate to ensure that every
gimple code has its own gimple subclass.
Add a copy of the documentation from gimple.def to every gimple subclass
in gimple.h (both new and existing ones) so that the per-code documentation
shows up per-class within Doxygen-generated docs.
gcc/
* gimple.h (struct gimple_statement_error_mark): New subclass of
gimple_statement_base.
(struct gimple_statement_cond): New subclass of
gimple_statement_with_ops.
(struct gimple_statement_debug): New subclass of
gimple_statement_with_ops.
(gimple_statement_goto): New subclass of gimple_statement_with_ops.
(gimple_statement_label): New subclass of gimple_statement_with_ops.
(gimple_statement_switch): New subclass of
gimple_statement_with_ops.
(gimple_statement_assign): New subclass of
gimple_statement_with_memory_ops.
(gimple_statement_call): Add documentation from gimple.def.
(gimple_statement_bind): Likewise.
(gimple_statement_catch): Likewise.
(gimple_statement_eh_filter): Likewise.
(gimple_statement_eh_else): Likewise.
(gimple_statement_eh_mnt): Likewise.
(gimple_statement_phi): Likewise.
(gimple_statement_resx): New subclass of gimple_statement_eh_ctrl.
(gimple_statement_dispatch): Likewise.
(gimple_statement_try): Add documentation from gimple.def.
(gimple_statement_nop): New subclass of gimple_statement_base.
(gimple_statement_wce): Add documentation from gimple.def.
(gimple_statement_asm): Likewise.
(gimple_statement_omp_critical): Likewise.
(gimple_statement_omp_for): Likewise.
(gimple_statement_omp_master): New subclass of gimple_statement_omp.
(gimple_statement_omp_taskgroup): Likewise.
(gimple_statement_omp_ordered): Likewise.
(gimple_statement_omp_parallel): Add documentation from
gimple.def.
(gimple_statement_omp_task): Likewise.
(gimple_statement_omp_section): New subclass of
gimple_statement_omp.
(gimple_statement_omp_sections): Add documentation from gimple.def.
(gimple_statement_omp_sections_switch): New subclass of
gimple_statement_base.
(gimple_statement_omp_continue): Add documentation from gimple.def.
(gimple_statement_omp_target): New subclass of
gimple_statement_omp_parallel.
(gimple_statement_omp_teams): New subclass of
gimple_statement_omp_single.
(gimple_predict): New subclass of gimple_statement_base.
(gimple_statement_omp_atomic_load): Add documentation from
gimple.def.
(gimple_statement_omp_atomic_store): Update comment.
(gimple_statement_omp_return): New subclass of
gimple_statement_omp_atomic_store.
(gimple_statement_transaction): Add documentation from gimple.def.
(gimple_statement_return): New subclass of
gimple_statement_with_memory_ops.
@@ -223,6 +223,13 @@ struct GTY((desc ("gimple_statement_structure (&%h)"), tag ("GSS_BASE"),
gimple GTY((skip)) prev;
};
+/* code == GIMPLE_ERROR_MARK, an error marker. */
+
+struct GTY(())
+ gimple_statement_error_mark : public gimple_statement_base
+{
+ /* no additional fields; this uses the layout for GSS_BASE. */
+};
/* Base structure for tuples with operands. */
@@ -255,6 +262,81 @@ struct GTY((tag("GSS_WITH_OPS")))
tree GTY((length ("%h.num_ops"))) op[1];
};
+/* code == GIMPLE_COND:
+
+ GIMPLE_COND <COND_CODE, OP1, OP2, TRUE_LABEL, FALSE_LABEL>
+ represents the conditional jump:
+
+ if (OP1 COND_CODE OP2) goto TRUE_LABEL else goto FALSE_LABEL
+
+ COND_CODE is the tree code used as the comparison predicate. It
+ must be of class tcc_comparison.
+
+ OP1 and OP2 are the operands used in the comparison. They must be
+ accepted by is_gimple_operand.
+
+ TRUE_LABEL and FALSE_LABEL are the LABEL_DECL nodes used as the
+ jump target for the comparison. */
+
+struct GTY(())
+ gimple_statement_cond : public gimple_statement_with_ops
+{
+ /* no additional fields; this uses the layout for GSS_WITH_OPS. */
+};
+
+/* code == GIMPLE_DEBUG, a debug statement. */
+
+struct GTY(())
+ gimple_statement_debug : public gimple_statement_with_ops
+{
+ /* no additional fields; this uses the layout for GSS_WITH_OPS. */
+};
+
+/* code == GIMPLE_GOTO
+
+ GIMPLE_GOTO <TARGET> represents unconditional jumps.
+ TARGET is a LABEL_DECL or an expression node for computed GOTOs. */
+
+struct GTY(())
+ gimple_statement_goto : public gimple_statement_with_ops
+{
+ /* no additional fields; this uses the layout for GSS_WITH_OPS. */
+};
+
+/* code == GIMPLE_LABEL
+
+ GIMPLE_LABEL <LABEL> represents label statements. LABEL is a
+ LABEL_DECL representing a jump target. */
+
+struct GTY(())
+ gimple_statement_label : public gimple_statement_with_ops
+{
+ /* no additional fields; this uses the layout for GSS_WITH_OPS. */
+};
+
+/* code == GIMPLE_SWITCH
+
+ GIMPLE_SWITCH <INDEX, DEFAULT_LAB, LAB1, ..., LABN> represents the
+ multiway branch:
+
+ switch (INDEX)
+ {
+ case LAB1: ...; break;
+ ...
+ case LABN: ...; break;
+ default: ...
+ }
+
+ INDEX is the variable evaluated to decide which label to jump to.
+
+ DEFAULT_LAB, LAB1 ... LABN are the tree nodes representing case labels.
+ They must be CASE_LABEL_EXPR nodes. */
+
+struct GTY(())
+ gimple_statement_switch : public gimple_statement_with_ops
+{
+ /* no additional fields; this uses the layout for GSS_WITH_OPS. */
+};
/* Base for statements that take both memory and register operands. */
@@ -286,8 +368,49 @@ struct GTY((tag("GSS_WITH_MEM_OPS")))
tree GTY((length ("%h.num_ops"))) op[1];
};
+/* code == GIMPLE_ASSIGN:
+
+ GIMPLE_ASSIGN <SUBCODE, LHS, RHS1[, RHS2]> represents the assignment
+ statement
+
+ LHS = RHS1 SUBCODE RHS2.
+
+ SUBCODE is the tree code for the expression computed by the RHS of the
+ assignment. It must be one of the tree codes accepted by
+ get_gimple_rhs_class. If LHS is not a gimple register according to
+ is_gimple_reg, SUBCODE must be of class GIMPLE_SINGLE_RHS.
+
+ LHS is the operand on the LHS of the assignment. It must be a tree node
+ accepted by is_gimple_lvalue.
+
+ RHS1 is the first operand on the RHS of the assignment. It must always be
+ present. It must be a tree node accepted by is_gimple_val.
+
+ RHS2 is the second operand on the RHS of the assignment. It must be a tree
+ node accepted by is_gimple_val. This argument exists only if SUBCODE is
+ of class GIMPLE_BINARY_RHS. */
+
+struct GTY(())
+ gimple_statement_assign : public gimple_statement_with_memory_ops
+{
+ /* no additional fields; this uses the layout for GSS_WITH_MEM_OPS. */
+};
+
+
+/* code == GIMPLE_CALL.
+
+ GIMPLE_CALL <FN, LHS, ARG1, ..., ARGN[, CHAIN]> represents function
+ calls.
+
+ FN is the callee. It must be accepted by is_gimple_call_addr.
-/* Call statements that take both memory and register operands. */
+ LHS is the operand where the return value from FN is stored. It may
+ be NULL.
+
+ ARG1 ... ARGN are the arguments. They must all be accepted by
+ is_gimple_operand.
+
+ CHAIN is the optional static chain link for nested functions. */
struct GTY((tag("GSS_CALL")))
gimple_statement_call : public gimple_statement_with_memory_ops_base
@@ -324,7 +447,12 @@ struct GTY((tag("GSS_OMP")))
};
-/* GIMPLE_BIND */
+/* code == GIMPLE_BIND:
+
+ GIMPLE_BIND <VARS, BLOCK, BODY> represents a lexical scope.
+ VARS is the set of variables declared in that scope.
+ BLOCK is the symbol binding block used for debug information.
+ BODY is the sequence of statements in the scope. */
struct GTY((tag("GSS_BIND")))
gimple_statement_bind : public gimple_statement_base
@@ -348,7 +476,11 @@ struct GTY((tag("GSS_BIND")))
};
-/* GIMPLE_CATCH */
+/* code == GIMPLE_CATCH:
+
+ GIMPLE_CATCH <TYPES, HANDLER> represents a typed exception handler.
+ TYPES is the type (or list of types) handled. HANDLER is the
+ sequence of statements that handle these types. */
struct GTY((tag("GSS_CATCH")))
gimple_statement_catch : public gimple_statement_base
@@ -363,7 +495,11 @@ struct GTY((tag("GSS_CATCH")))
};
-/* GIMPLE_EH_FILTER */
+/* code == GIMPLE_EH_FILTER:
+
+ GIMPLE_EH_FILTER <TYPES, FAILURE> represents an exception
+ specification. TYPES is a list of allowed types and FAILURE is the
+ sequence of statements to execute on failure. */
struct GTY((tag("GSS_EH_FILTER")))
gimple_statement_eh_filter : public gimple_statement_base
@@ -379,7 +515,12 @@ struct GTY((tag("GSS_EH_FILTER")))
gimple_seq failure;
};
-/* GIMPLE_EH_ELSE */
+/* code == GIMPLE_EH_ELSE:
+
+ GIMPLE_EH_ELSE <N_BODY, E_BODY> must be the sole contents of
+ a GIMPLE_TRY_FINALLY node. For all normal exits from the try block,
+ N_BODY is run; for all exception exits from the try block,
+ E_BODY is run. */
struct GTY((tag("GSS_EH_ELSE")))
gimple_statement_eh_else : public gimple_statement_base
@@ -390,7 +531,11 @@ struct GTY((tag("GSS_EH_ELSE")))
gimple_seq n_body, e_body;
};
-/* GIMPLE_EH_MUST_NOT_THROW */
+/* code == GIMPLE_EH_MUST_NOT_THROW:
+
+ GIMPLE_EH_MUST_NOT_THROW <DECL> represents an exception barrier.
+ DECL is a noreturn function decl taking no arguments that will
+ be invoked if an exception propagates to this point. */
struct GTY((tag("GSS_EH_MNT")))
gimple_statement_eh_mnt : public gimple_statement_base
@@ -401,7 +546,18 @@ struct GTY((tag("GSS_EH_MNT")))
tree fndecl;
};
-/* GIMPLE_PHI */
+/* code == GIMPLE_PHI:
+
+ GIMPLE_PHI <RESULT, ARG1, ..., ARGN> represents the PHI node
+
+ RESULT = PHI <ARG1, ..., ARGN>
+
+ RESULT is the SSA name created by this PHI node.
+
+ ARG1 ... ARGN are the arguments to the PHI node. N must be
+ exactly the same as the number of incoming edges to the basic block
+ holding the PHI node. Every argument is either an SSA name or a
+ tree node of class tcc_constant. */
struct GTY((tag("GSS_PHI")))
gimple_statement_phi : public gimple_statement_base
@@ -432,8 +588,43 @@ struct GTY((tag("GSS_EH_CTRL")))
int region;
};
+/* code == GIMPLE_RESX:
+
+ GIMPLE_RESX resumes execution after an exception. */
+
+struct GTY(())
+ gimple_statement_resx : public gimple_statement_eh_ctrl
+{
+ /* no additional fields; this uses the layout for GSS_EH_CTRL. */
+};
+
+/* code == GIMPLE_EH_DISPATCH:
-/* GIMPLE_TRY */
+ GIMPLE_EH_DISPATCH demultiplexes an exception edge based on
+ the FILTER argument. */
+
+struct GTY(())
+ gimple_statement_dispatch : public gimple_statement_eh_ctrl
+{
+ /* no additional fields; this uses the layout for GSS_EH_CTRL. */
+};
+
+
+/* code == GIMPLE_TRY:
+
+ GIMPLE_TRY <TRY_KIND, EVAL, CLEANUP>
+ represents a try/catch or a try/finally statement.
+
+ TRY_KIND is either GIMPLE_TRY_CATCH or GIMPLE_TRY_FINALLY.
+
+ EVAL is the sequence of statements to execute on entry to GIMPLE_TRY.
+
+ CLEANUP is the sequence of statements to execute according to
+ TRY_KIND. If TRY_KIND is GIMPLE_TRY_CATCH, CLEANUP is only exected
+ if an exception is thrown during execution of EVAL. If TRY_KIND is
+ GIMPLE_TRY_FINALLY, CLEANUP is always executed after executing EVAL
+ (regardless of whether EVAL finished normally, or jumped out or an
+ exception was thrown). */
struct GTY((tag("GSS_TRY")))
gimple_statement_try : public gimple_statement_base
@@ -463,7 +654,24 @@ enum gimple_try_flags
GIMPLE_TRY_CATCH_IS_CLEANUP = 1 << 2
};
-/* GIMPLE_WITH_CLEANUP_EXPR */
+/* code == GIMPLE_NOP:
+
+ GIMPLE_NOP represents the "do nothing" statement. */
+
+struct GTY(())
+ gimple_statement_nop : public gimple_statement_base
+{
+ /* no additional fields; this uses the layout for GSS_BASE. */
+};
+
+
+/* code == GIMPLE_WITH_CLEANUP_EXPR:
+
+ This node represents a cleanup expression. It is ONLY USED INTERNALLY
+ by the gimplifier as a placeholder for cleanups, and its uses will be
+ cleaned up by the time gimplification is done.
+
+ This tuple should not exist outside of the gimplifier proper. */
struct GTY((tag("GSS_WCE")))
gimple_statement_wce : public gimple_statement_base
@@ -481,7 +689,16 @@ struct GTY((tag("GSS_WCE")))
};
-/* GIMPLE_ASM */
+/* code == GIMPLE_ASM:
+
+ GIMPLE_ASM <STRING, I1, ..., IN, O1, ... OM, C1, ..., CP>
+ represents inline assembly statements.
+
+ STRING is the string containing the assembly statements.
+ I1 ... IN are the N input operands.
+ O1 ... OM are the M output operands.
+ C1 ... CP are the P clobber operands.
+ L1 ... LQ are the Q label operands. */
struct GTY((tag("GSS_ASM")))
gimple_statement_asm : public gimple_statement_with_memory_ops_base
@@ -506,7 +723,13 @@ struct GTY((tag("GSS_ASM")))
tree GTY((length ("%h.num_ops"))) op[1];
};
-/* GIMPLE_OMP_CRITICAL */
+/* code == GIMPLE_OMP_CRITICAL:
+ GIMPLE_OMP_CRITICAL <NAME, BODY> represents
+
+ #pragma omp critical [name]
+
+ NAME is the name given to the critical section.
+ BODY is the sequence of statements that are inside the critical section. */
struct GTY((tag("GSS_OMP_CRITICAL")))
gimple_statement_omp_critical : public gimple_statement_omp
@@ -536,7 +759,43 @@ struct GTY(()) gimple_omp_for_iter {
tree incr;
};
-/* GIMPLE_OMP_FOR */
+/* code == GIMPLE_OMP_FOR:
+
+ GIMPLE_OMP_FOR <BODY, CLAUSES, INDEX, INITIAL, FINAL, COND, INCR, PRE_BODY>
+ represents
+
+ PRE_BODY
+ #pragma omp for [clause1 ... clauseN]
+ for (INDEX = INITIAL; INDEX COND FINAL; INDEX {+=,-=} INCR)
+ BODY
+
+ BODY is the loop body.
+
+ CLAUSES is the list of clauses.
+
+ INDEX must be an integer or pointer variable, which is implicitly thread
+ private. It must be accepted by is_gimple_operand.
+
+ INITIAL is the initial value given to INDEX. It must be
+ accepted by is_gimple_operand.
+
+ FINAL is the final value that INDEX should take. It must
+ be accepted by is_gimple_operand.
+
+ COND is the condition code for the controlling predicate. It must
+ be one of { <, >, <=, >= }
+
+ INCR is the loop index increment. It must be tree node of type
+ tcc_constant.
+
+ PRE_BODY is a landing pad 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.
+
+ INITIAL, FINAL 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 standard. */
struct GTY((tag("GSS_OMP_FOR")))
gimple_statement_omp_for : public gimple_statement_omp
@@ -558,8 +817,58 @@ struct GTY((tag("GSS_OMP_FOR")))
gimple_seq pre_body;
};
+/* code == GIMPLE_OMP_MASTER:
+
+ GIMPLE_OMP_MASTER <BODY> represents #pragma omp master.
+ BODY is the sequence of statements to execute in the master section. */
+
+struct GTY(())
+ gimple_statement_omp_master : public gimple_statement_omp
+{
+ /* no additional fields; this uses the layout for GSS_OMP. */
+};
+
+/* code == GIMPLE_OMP_TASKGROUP:
+
+ GIMPLE_OMP_TASKGROUP <BODY> represents #pragma omp taskgroup.
+ BODY is the sequence of statements to execute in the taskgroup section. */
+
+struct GTY(())
+ gimple_statement_omp_taskgroup : public gimple_statement_omp
+{
+ /* no additional fields; this uses the layout for GSS_OMP. */
+};
+
+/* code == GIMPLE_OMP_ORDERED:
-/* GIMPLE_OMP_PARALLEL */
+ GIMPLE_OMP_ORDERED <BODY> represents #pragma omp ordered.
+ BODY is the sequence of statements to execute in the ordered section. */
+
+struct GTY(())
+ gimple_statement_omp_ordered : public gimple_statement_omp
+{
+ /* no additional fields; this uses the layout for GSS_OMP. */
+};
+
+
+/* code == GIMPLE_OMP_PARALLEL:
+
+ GIMPLE_OMP_PARALLEL <BODY, CLAUSES, CHILD_FN, DATA_ARG> represents
+
+ #pragma omp parallel [CLAUSES]
+ BODY
+
+ BODY is a the sequence of statements to be executed by all threads.
+
+ CLAUSES is an OMP_CLAUSE chain with all the clauses.
+
+ CHILD_FN is set when outlining the body of the parallel region.
+ All the statements in BODY are moved into this newly created
+ function when converting OMP constructs into low-GIMPLE.
+
+ DATA_ARG is a local variable in the parent function containing data
+ to be shared with CHILD_FN. This is used to implement all the data
+ sharing clauses. */
struct GTY((tag("GSS_OMP_PARALLEL")))
gimple_statement_omp_parallel : public gimple_statement_omp
@@ -580,7 +889,33 @@ struct GTY((tag("GSS_OMP_PARALLEL")))
};
-/* GIMPLE_OMP_TASK */
+/* code == GIMPLE_OMP_TASK:
+
+ GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN,
+ ARG_SIZE, ARG_ALIGN> represents
+
+ #pragma omp task [CLAUSES]
+ BODY
+
+ BODY is a the sequence of statements to be executed by all threads.
+
+ CLAUSES is an OMP_CLAUSE chain with all the clauses.
+
+ CHILD_FN is set when outlining the body of the explicit task region.
+ All the statements in BODY are moved into this newly created
+ function when converting OMP constructs into low-GIMPLE.
+
+ DATA_ARG is a local variable in the parent function containing data
+ to be shared with CHILD_FN. This is used to implement all the data
+ sharing clauses.
+
+ COPY_FN is set when outlining the firstprivate var initialization.
+ All the needed statements are emitted into the newly created
+ function, or when only memcpy is needed, it is NULL.
+
+ ARG_SIZE and ARG_ALIGN are the size and alignment of the incoming
+ data area allocated by GOMP_task and passed to CHILD_FN. */
+
struct GTY((tag("GSS_OMP_TASK")))
gimple_statement_omp_task : public gimple_statement_omp_parallel
@@ -597,12 +932,25 @@ struct GTY((tag("GSS_OMP_TASK")))
tree arg_align;
};
+/* code == GIMPLE_OMP_SECTION:
+
+ OMP_SECTION <BODY> represents #pragma omp section.
+ BODY is the sequence of statements in the section body. */
-/* GIMPLE_OMP_SECTION */
-/* Uses struct gimple_statement_omp. */
+struct GTY(())
+ gimple_statement_omp_section : public gimple_statement_omp
+{
+ /* no additional fields; this uses the layout for GSS_OMP. */
+};
+/* code == GIMPLE_OMP_SECTIONS:
-/* GIMPLE_OMP_SECTIONS */
+ OMP_SECTIONS <BODY, CLAUSES, CONTROL> represents #pragma omp sections.
+
+ BODY is the sequence of statements in the sections body.
+ CLAUSES is an OMP_CLAUSE chain holding the list of associated clauses.
+ CONTROL is a VAR_DECL used for deciding which of the sections
+ to execute. */
struct GTY((tag("GSS_OMP_SECTIONS")))
gimple_statement_omp_sections : public gimple_statement_omp
@@ -618,10 +966,25 @@ struct GTY((tag("GSS_OMP_SECTIONS")))
tree control;
};
-/* GIMPLE_OMP_CONTINUE.
+/* code == GIMPLE_OMP_SECTIONS_SWITCH:
+
+ GIMPLE_OMP_SECTIONS_SWITCH is a marker placed immediately after
+ OMP_SECTIONS. It represents the GIMPLE_SWITCH used to decide which
+ branch is taken. */
+
+struct GTY(())
+ gimple_statement_omp_sections_switch : public gimple_statement_base
+{
+ /* no additional fields; this uses the layout for GSS_BASE. */
+};
+
+/* code == GIMPLE_OMP_CONTINUE:
Note: This does not inherit from gimple_statement_omp, because we
- do not need the body field. */
+ do not need the body field.
+
+ GIMPLE_OMP_CONTINUE marks the location of the loop or sections
+ iteration in partially lowered OpenMP code. */
struct GTY((tag("GSS_OMP_CONTINUE")))
gimple_statement_omp_continue : public gimple_statement_base
@@ -646,10 +1009,65 @@ struct GTY((tag("GSS_OMP_SINGLE")))
tree clauses;
};
+/* code == GIMPLE_OMP_TARGET:
+
+ GIMPLE_OMP_TARGET <BODY, CLAUSES, CHILD_FN> represents
+ #pragma omp target {,data,update}
+ BODY is the sequence of statements inside the target construct
+ (NULL for target update).
+ CLAUSES is an OMP_CLAUSE chain holding the associated clauses.
+ CHILD_FN is set when outlining the body of the target region.
+ All the statements in BODY are moved into this newly created
+ function when converting OMP constructs into low-GIMPLE.
+ DATA_ARG is a vec of 3 local variables in the parent function
+ containing data to be mapped to CHILD_FN. This is used to
+ implement the MAP clauses. */
+
+struct GTY(())
+ gimple_statement_omp_target : public gimple_statement_omp_parallel
+{
+ /* no additional fields; this uses the layout for GSS_OMP_PARALLEL. */
+};
+
+/* code == GIMPLE_OMP_TEAMS:
+
+ GIMPLE_OMP_TEAMS <BODY, CLAUSES> represents #pragma omp teams
+ BODY is the sequence of statements inside the single section.
+ CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */
+
+struct GTY(())
+ gimple_statement_omp_teams : public gimple_statement_omp_single
+{
+ /* no additional fields; this uses the layout for GSS_OMP_SINGLE. */
+};
+
+/* code = GIMPLE_PREDICT:
+
+ GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction.
+
+ PREDICT is one of the predictors from predict.def.
+
+ OUTCOME is NOT_TAKEN or TAKEN. */
-/* GIMPLE_OMP_ATOMIC_LOAD.
+struct GTY(())
+ gimple_predict : public gimple_statement_base
+{
+ /* no additional fields; this uses the layout for GSS_BASE. */
+};
+
+/* code == GIMPLE_OMP_ATOMIC_LOAD.
Note: This is based on gimple_statement_base, not g_s_omp, because g_s_omp
- contains a sequence, which we don't need here. */
+ contains a sequence, which we don't need here.
+
+ Tuples used for lowering of OMP_ATOMIC. Although the form of the OMP_ATOMIC
+ expression is very simple (just in form mem op= expr), various implicit
+ conversions may cause the expression to become more complex, so that it does
+ not fit the gimple grammar very well. To overcome this problem, OMP_ATOMIC
+ is rewritten as a sequence of two codes in gimplification:
+
+ GIMPLE_OMP_LOAD (tmp, mem)
+ val = some computations involving tmp;
+ GIMPLE_OMP_STORE (val). */
struct GTY((tag("GSS_OMP_ATOMIC_LOAD")))
gimple_statement_omp_atomic_load : public gimple_statement_base
@@ -660,7 +1078,8 @@ struct GTY((tag("GSS_OMP_ATOMIC_LOAD")))
tree rhs, lhs;
};
-/* GIMPLE_OMP_ATOMIC_STORE.
+/* code == GIMPLE_OMP_ATOMIC_STORE:
+
See note on GIMPLE_OMP_ATOMIC_LOAD. */
struct GTY((tag("GSS_OMP_ATOMIC_STORE")))
@@ -672,6 +1091,16 @@ struct GTY((tag("GSS_OMP_ATOMIC_STORE")))
tree val;
};
+/* code == OMP_RETURN:
+
+ OMP_RETURN marks the end of an OpenMP directive. */
+
+struct GTY(())
+ gimple_statement_omp_return : public gimple_statement_omp_atomic_store
+{
+ /* no additional fields; this uses the layout for GSS_OMP_ATOMIC_STORE. */
+};
+
/* GIMPLE_TRANSACTION. */
/* Bits to be stored in the GIMPLE_TRANSACTION subcode. */
@@ -700,6 +1129,16 @@ struct GTY((tag("GSS_OMP_ATOMIC_STORE")))
likely because it is guaranteed to go irrevocable upon entry. */
#define GTMA_HAS_NO_INSTRUMENTATION (1u << 7)
+
+/* code == GIMPLE_TRANSACTION:
+
+ GIMPLE_TRANSACTION <BODY, LABEL> represents __transaction_atomic and
+ __transaction_relaxed blocks.
+ BODY is the sequence of statements inside the transaction.
+ LABEL is a label for the statement immediately following the
+ transaction. This is before RETURN so that it has MEM_OPS,
+ so that it can clobber global memory. */
+
struct GTY((tag("GSS_TRANSACTION")))
gimple_statement_transaction : public gimple_statement_with_memory_ops_base
{
@@ -712,6 +1151,19 @@ struct GTY((tag("GSS_TRANSACTION")))
tree label;
};
+/* code == GIMPLE_RETURN:
+
+ GIMPLE_RETURN <RETVAL> represents return statements.
+
+ RETVAL is the value to return or NULL. If a value is returned it
+ must be accepted by is_gimple_operand. */
+
+struct GTY(())
+ gimple_statement_return : public gimple_statement_with_memory_ops
+{
+ /* no additional fields; this uses the layout for GSS_WITH_MEM_OPS. */
+};
+
#define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) SYM,
enum gimple_statement_structure_enum {
#include "gsstruct.def"