On Sat, Jul 20, 2024 at 02:42:21PM -0600, Sandra Loosemore wrote:
> --- a/gcc/cgraph.h
> +++ b/gcc/cgraph.h
> @@ -900,6 +900,7 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node :
> public symtab_node
> ipcp_clone (false), declare_variant_alt (false),
> calls_declare_variant_alt (false), gc_candidate (false),
> called_by_ifunc_resolver (false),
> + has_metadirectives (false),
has_omp_metadirectives please. People unfamiliar with OpenMP will have no
idea what it is about.
> m_uid (uid), m_summary_id (-1)
> {}
>
> @@ -1501,6 +1502,8 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node :
> public symtab_node
> unsigned gc_candidate : 1;
> /* Set if the function is called by an IFUNC resolver. */
> unsigned called_by_ifunc_resolver : 1;
> + /* True if the function contains unresolved metadirectives. */
And OpenMP before metadirectives in the comment.
> + unsigned has_metadirectives : 1;
> + unsigned i;
> +
> + /* The variants are not used after lowering. */
> + gimple_omp_metadirective_set_variants (stmt, NULL);
> +
> + for (i = 0; i < gimple_num_ops (stmt); i++)
Nothing uses i before or after the loop, so please do
for (unsigned i = 0; i < gimple_num_ops (stmt); i++)
> +gomp_variant *
> +gimple_build_omp_variant (gimple_seq body)
> +{
> + gomp_variant *variant = as_a <gomp_variant *>
> + (gimple_alloc (GIMPLE_OMP_METADIRECTIVE_VARIANT, 0));
gomp_variant *variant
= as_a <gomp_variant *> (gimple_alloc (GIMPLE_OMP_METADIRECTIVE_VARIANT,
0));
please instead.
> --- a/gcc/gimple.def
> +++ b/gcc/gimple.def
> @@ -398,6 +398,13 @@ DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams",
> GSS_OMP_PARALLEL_LAYOUT)
> CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */
> DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP_SINGLE_LAYOUT)
>
> +/* GIMPLE_OMP_METADIRECTIVE represents #pragma omp metadirective. */
> +DEFGSCODE(GIMPLE_OMP_METADIRECTIVE, "gimple_omp_metadirective",
> + GSS_OMP_METADIRECTIVE)
This one is misplaced.
> +
> +DEFGSCODE(GIMPLE_OMP_METADIRECTIVE_VARIANT,
> + "gimple_omp_variant", GSS_OMP_METADIRECTIVE_VARIANT)
> +
> /* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction.
>
> PREDICT is one of the predictors from predict.def.
> @@ -2149,7 +2209,8 @@ gimple_init_singleton (gimple *g)
> inline bool
> gimple_has_ops (const gimple *g)
> {
> - return gimple_code (g) >= GIMPLE_COND && gimple_code (g) <= GIMPLE_RETURN;
> + return (gimple_code (g) >= GIMPLE_COND && gimple_code (g) <= GIMPLE_RETURN)
> + || gimple_code (g) == GIMPLE_OMP_METADIRECTIVE;
> }
>
> template <>
As can be seen on the need to change gimple_has_ops. gimple_has_ops
shouldn't be changed, instead GIMPLE_OMP_DIRECTIVE should go before
GIMPLE_RETURN.
> + selectors.safe_push (selector);
> + gomp_variant *omp_variant
> + = gimple_build_omp_variant (NULL);
This surely fits on one line:
gomp_variant *omp_variant = gimple_build_omp_variant (NULL);
> @@ -10752,6 +10754,10 @@ build_omp_regions_1 (basic_block bb, struct
> omp_region *parent,
> /* GIMPLE_OMP_SECTIONS_SWITCH is part of
> GIMPLE_OMP_SECTIONS, and we do nothing for it. */
> }
> + else if (code == GIMPLE_OMP_METADIRECTIVE)
> + {
> + /* Do nothing for metadirectives. */
> + }
Better just change the following else
> else
/* Do nothing for metadirectives; otherwise: */
else if (code != GIMPLE_OMP_METADIRECTIVES)
> {
> region = new_omp_region (bb, code, parent);
> @@ -1003,6 +1008,18 @@ new_omp_context (gimple *stmt, omp_context *outer_ctx)
> return ctx;
> }
>
Add function comment here?
> +static omp_context *
> +clone_omp_context (omp_context *ctx)
> +{
> + omp_context *clone_ctx = XCNEW (omp_context);
If you memcpy over it all, XCNEW makes no sense, just XNEW?
> +
> + memcpy (clone_ctx, ctx, sizeof (omp_context));
> --- a/gcc/tree-cfg.cc
> +++ b/gcc/tree-cfg.cc
> @@ -1752,6 +1752,18 @@ cleanup_dead_labels (void)
> }
> break;
>
> + case GIMPLE_OMP_METADIRECTIVE:
> + {
> + for (unsigned i = 0; i < gimple_num_ops (stmt); i++)
> + {
> + label = gimple_omp_metadirective_label (stmt, i);
> + new_label = main_block_label (label, label_for_bb);
> + if (new_label != label)
> + gimple_omp_metadirective_set_label (stmt, i, new_label);
> + }
> + }
Why the {}s around this all? Just the for loop would do.
> + break;
> @@ -6329,6 +6341,18 @@ gimple_redirect_edge_and_branch (edge e, basic_block
> dest)
> gimple_block_label (dest));
> break;
>
> + case GIMPLE_OMP_METADIRECTIVE:
> + {
> + for (unsigned i = 0; i < gimple_num_ops (stmt); i++)
> + {
> + tree label = gimple_omp_metadirective_label (stmt, i);
> + if (label_to_block (cfun, label) == e->dest)
> + gimple_omp_metadirective_set_label (stmt, i,
> + gimple_block_label (dest));
> + }
> + }
Likewise.
> + break;
> + case GIMPLE_OMP_METADIRECTIVE:
> + /* The actual instruction will disappear eventually, so metadirective
> + statements have zero additional cost (if only static selectors
> + are used). */
> + /* TODO: Estimate the cost of evaluating dynamic selectors */
Missing . after selectors
> + return 0;
> +
Jakub