gcc/ * coretypes.h (gimple_omp_critical): New typedef. (const_gimple_omp_critical): New typedef.
* gimple-pretty-print.c (dump_gimple_omp_critical): Require a gimple_omp_critical rather than a plain gimple. (pp_gimple_stmt_1): Add a checked cast to gimple_omp_critical within GIMPLE_OMP_CRITICAL case of switch statement. * gimple-walk.c (walk_gimple_op): Likewise. * gimple.c (gimple_build_omp_critical): Return a gimple_omp_critical rather than a plain gimple. (gimple_copy): Add checked casts to gimple_omp_critical within GIMPLE_OMP_CRITICAL case of switch statement. * gimple.h (gimple_statement_base::as_a_gimple_omp_critical): New. (gimple_statement_base::dyn_cast_gimple_omp_critical): New. (gimple_debug): Likewise. (gimple_build_omp_critical): Return a gimple_omp_critical rather than a plain gimple. (gimple_omp_critical_name): Require a const_gimple_omp_critical rather than a plain const_gimple. (gimple_omp_critical_name_ptr): Require a gimple_omp_critical rather than a plain gimple. (gimple_omp_critical_set_name): Likewise. * omp-low.c (check_omp_nesting_restrictions): Add a checked cast to gimple_omp_critical within GIMPLE_OMP_CRITICAL case of switch statement, introducing a new local "other_crit" for type-safety. (lower_omp_critical): Strengthen local "stmt" to gimple_omp_critical. * tree-inline.c (remap_gimple_stmt): Add a checked cast to gimple_omp_critical within GIMPLE_OMP_CRITICAL case of switch statement. --- gcc/coretypes.h | 4 ++++ gcc/gimple-pretty-print.c | 7 ++++--- gcc/gimple-walk.c | 5 +++-- gcc/gimple.c | 10 ++++++---- gcc/gimple.h | 34 ++++++++++++++++++++-------------- gcc/omp-low.c | 26 +++++++++++++++----------- gcc/tree-inline.c | 6 ++++-- 7 files changed, 56 insertions(+), 36 deletions(-) diff --git a/gcc/coretypes.h b/gcc/coretypes.h index e2ad76e..f527da6 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -159,6 +159,10 @@ struct gimple_statement_omp_continue; typedef struct gimple_statement_omp_continue *gimple_omp_continue; typedef const struct gimple_statement_omp_continue *const_gimple_omp_continue; +struct gimple_statement_omp_critical; +typedef struct gimple_statement_omp_critical *gimple_omp_critical; +typedef const struct gimple_statement_omp_critical *const_gimple_omp_critical; + union section; typedef union section section; struct gcc_options; diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 3de01d0..8248c67 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1435,8 +1435,8 @@ dump_gimple_omp_block (pretty_printer *buffer, gimple gs, int spc, int flags) /* Dump a GIMPLE_OMP_CRITICAL tuple on the pretty_printer BUFFER. */ static void -dump_gimple_omp_critical (pretty_printer *buffer, gimple gs, int spc, - int flags) +dump_gimple_omp_critical (pretty_printer *buffer, gimple_omp_critical gs, + int spc, int flags) { if (flags & TDF_RAW) dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S> >", gs, @@ -2202,7 +2202,8 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags) break; case GIMPLE_OMP_CRITICAL: - dump_gimple_omp_critical (buffer, gs, spc, flags); + dump_gimple_omp_critical (buffer, gs->as_a_gimple_omp_critical (), spc, + flags); break; case GIMPLE_CATCH: diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c index f286748..ae43f45 100644 --- a/gcc/gimple-walk.c +++ b/gcc/gimple-walk.c @@ -313,8 +313,9 @@ walk_gimple_op (gimple stmt, walk_tree_fn callback_op, break; case GIMPLE_OMP_CRITICAL: - ret = walk_tree (gimple_omp_critical_name_ptr (stmt), callback_op, wi, - pset); + ret = walk_tree (gimple_omp_critical_name_ptr ( + stmt->as_a_gimple_omp_critical ()), + callback_op, wi, pset); if (ret) return ret; break; diff --git a/gcc/gimple.c b/gcc/gimple.c index a0fa31e..3b40884 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -815,10 +815,11 @@ gimple_build_debug_source_bind_stat (tree var, tree value, BODY is the sequence of statements for which only one thread can execute. NAME is optional identifier for this critical block. */ -gimple +gimple_omp_critical gimple_build_omp_critical (gimple_seq body, tree name) { - gimple p = gimple_alloc (GIMPLE_OMP_CRITICAL, 0); + gimple_omp_critical p = + gimple_alloc (GIMPLE_OMP_CRITICAL, 0)->as_a_gimple_omp_critical (); gimple_omp_critical_set_name (p, name); if (body) gimple_omp_set_body (p, body); @@ -1736,8 +1737,9 @@ gimple_copy (gimple stmt) goto copy_omp_body; case GIMPLE_OMP_CRITICAL: - t = unshare_expr (gimple_omp_critical_name (stmt)); - gimple_omp_critical_set_name (copy, t); + t = unshare_expr (gimple_omp_critical_name ( + stmt->as_a_gimple_omp_critical ())); + gimple_omp_critical_set_name (copy->as_a_gimple_omp_critical (), t); goto copy_omp_body; case GIMPLE_OMP_SECTIONS: diff --git a/gcc/gimple.h b/gcc/gimple.h index 5a3626e..525fb7b 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -354,6 +354,12 @@ public: return as_a <gimple_statement_omp_continue> (this); } + inline gimple_omp_critical + as_a_gimple_omp_critical () + { + return as_a <gimple_statement_omp_critical> (this); + } + /* Dynamic casting methods, where the cast returns NULL if the stmt is not of the required kind. @@ -440,6 +446,12 @@ public: return dyn_cast <gimple_statement_phi> (this); } + inline gimple_omp_critical + dyn_cast_gimple_omp_critical () + { + return dyn_cast <gimple_statement_omp_critical> (this); + } + }; @@ -1582,7 +1594,7 @@ gimple_debug gimple_build_debug_bind_stat (tree, tree, gimple MEM_STAT_DECL); gimple_debug gimple_build_debug_source_bind_stat (tree, tree, gimple MEM_STAT_DECL); #define gimple_build_debug_source_bind(var,val,stmt) \ gimple_build_debug_source_bind_stat ((var), (val), (stmt) MEM_STAT_INFO) -gimple gimple_build_omp_critical (gimple_seq, tree); +gimple_omp_critical gimple_build_omp_critical (gimple_seq, tree); gimple gimple_build_omp_for (gimple_seq, int, tree, size_t, gimple_seq); gimple gimple_build_omp_parallel (gimple_seq, tree, tree, tree); gimple gimple_build_omp_task (gimple_seq, tree, tree, tree, tree, tree, tree); @@ -4561,36 +4573,30 @@ gimple_omp_set_body (gimple gs, gimple_seq body) } -/* Return the name associated with OMP_CRITICAL statement GS. */ +/* Return the name associated with OMP_CRITICAL statement CRIT_STMT. */ static inline tree -gimple_omp_critical_name (const_gimple gs) +gimple_omp_critical_name (const_gimple_omp_critical crit_stmt) { - const gimple_statement_omp_critical *omp_critical_stmt = - as_a <const gimple_statement_omp_critical> (gs); - return omp_critical_stmt->name; + return crit_stmt->name; } /* Return a pointer to the name associated with OMP critical statement GS. */ static inline tree * -gimple_omp_critical_name_ptr (gimple gs) +gimple_omp_critical_name_ptr (gimple_omp_critical crit_stmt) { - gimple_statement_omp_critical *omp_critical_stmt = - as_a <gimple_statement_omp_critical> (gs); - return &omp_critical_stmt->name; + return &crit_stmt->name; } /* Set NAME to be the name associated with OMP critical statement GS. */ static inline void -gimple_omp_critical_set_name (gimple gs, tree name) +gimple_omp_critical_set_name (gimple_omp_critical crit_stmt, tree name) { - gimple_statement_omp_critical *omp_critical_stmt = - as_a <gimple_statement_omp_critical> (gs); - omp_critical_stmt->name = name; + crit_stmt->name = name; } diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 1cd4731..c2ab88a 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -2472,16 +2472,20 @@ check_omp_nesting_restrictions (gimple stmt, omp_context *ctx) } break; case GIMPLE_OMP_CRITICAL: - for (; ctx != NULL; ctx = ctx->outer) - if (gimple_code (ctx->stmt) == GIMPLE_OMP_CRITICAL - && (gimple_omp_critical_name (stmt) - == gimple_omp_critical_name (ctx->stmt))) - { - error_at (gimple_location (stmt), - "critical region may not be nested inside a critical " - "region with the same name"); - return false; - } + { + tree this_stmt_name = + gimple_omp_critical_name (stmt->as_a_gimple_omp_critical ()); + for (; ctx != NULL; ctx = ctx->outer) + if (gimple_omp_critical other_crit = + ctx->stmt->dyn_cast_gimple_omp_critical ()) + if (this_stmt_name == gimple_omp_critical_name (other_crit)) + { + error_at (gimple_location (stmt), + "critical region may not be nested inside a critical " + "region with the same name"); + return false; + } + } break; case GIMPLE_OMP_TEAMS: if (ctx == NULL @@ -8799,7 +8803,7 @@ lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx) { tree block; tree name, lock, unlock; - gimple stmt = gsi_stmt (*gsi_p); + gimple_omp_critical stmt = gsi_stmt (*gsi_p)->as_a_gimple_omp_critical (); gimple_bind bind; location_t loc = gimple_location (stmt); gimple_seq tbody; diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index f1d2791..34c399a 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1411,8 +1411,10 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id) case GIMPLE_OMP_CRITICAL: s1 = remap_gimple_seq (gimple_omp_body (stmt), id); - copy - = gimple_build_omp_critical (s1, gimple_omp_critical_name (stmt)); + copy = + gimple_build_omp_critical (s1, + gimple_omp_critical_name ( + stmt->as_a_gimple_omp_critical ())); break; case GIMPLE_TRANSACTION: -- 1.8.5.3