This corresponds to: [PATCH 28/89] Introduce gimple_eh_else https://gcc.gnu.org/ml/gcc-patches/2014-04/msg01156.html from the original 89-patch kit
That earlier patch was approved by Jeff: > OK after fixing up the naming/const stuff as discussed for prior > patches. > That applies to 22-30. Make sure to take care of > the pretty printers per Trevor's comments as well. He indicated those > were missing in a couple of those patches. in https://gcc.gnu.org/ml/gcc-patches/2014-05/msg00628.html gcc/ * coretypes.h (gimple_eh_else): New typedef. (const_gimple_eh_else): New typedef. * gimple.h (gimple_build_eh_else): Return a gimple_eh_else rather than a plain gimple. (gimple_eh_else_n_body_ptr): Require a gimple_eh_else rather than a plain gimple. (gimple_eh_else_n_body): Likewise. (gimple_eh_else_e_body_ptr): Likewise. (gimple_eh_else_e_body): Likewise. (gimple_eh_else_set_n_body): Likewise. (gimple_eh_else_set_e_body): Likewise. * gimple-low.c (lower_stmt): Add checked cast to gimple_eh_else within GIMPLE_EH_ELSE case of switch statement, introducing a new local. (gimple_stmt_may_fallthru): Likewise. * gimple-pretty-print.c (dump_gimple_eh_else): Require a gimple_eh_else rather than a plain gimple. (pp_gimple_stmt_1): Add checked cast to gimple_eh_else within GIMPLE_EH_ELSE case of switch statement * gimple-walk.c (walk_gimple_stmt): Add checked cast to gimple_eh_else within GIMPLE_EH_ELSE case of switch statement, introducing a new local. * gimple.c (gimple_build_eh_else): Return a gimple_eh_else rather than a plain gimple. (gimple_copy): Add checked casts to gimple_eh_else within GIMPLE_EH_ELSE case of switch statement, introducing new locals. * tree-cfg.c (verify_gimple_in_seq_2): Add checked cast to gimple_eh_else within GIMPLE_EH_ELSE case of switch statement, introducing a new local. * tree-eh.c (collect_finally_tree): Likewise. (replace_goto_queue_1): Likewise. (get_eh_else): Return a gimple_eh_else rather than a plain gimple. (honor_protect_cleanup_actions): Convert local "eh_else" from gimple to gimple_eh_else. (lower_try_finally_nofallthru): Likewise. (lower_try_finally_onedest): Introduce locals "eh_else" and "label_stmt", using them in favor of "x" for the gimple_eh_else and the gimple_label. (lower_try_finally_copy): Convert local "eh_else" from gimple to gimple_eh_else. (lower_try_finally_switch): Likewise. (decide_copy_try_finally): Likewise. (refactor_eh_r): Add checked cast to gimple_eh_else within GIMPLE_EH_ELSE case of switch statement, introducing a new local. --- gcc/ChangeLog.gimple-classes | 56 ++++++++++++++++++++++++++++++++++++++++++++ gcc/coretypes.h | 4 ++++ gcc/gimple-low.c | 15 ++++++++---- gcc/gimple-pretty-print.c | 5 ++-- gcc/gimple-walk.c | 19 ++++++++------- gcc/gimple.c | 16 ++++++++----- gcc/gimple.h | 26 +++++++------------- gcc/tree-cfg.c | 7 ++++-- gcc/tree-eh.c | 55 ++++++++++++++++++++++++++++--------------- 9 files changed, 145 insertions(+), 58 deletions(-) diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes index dd39ce6..fe3008a 100644 --- a/gcc/ChangeLog.gimple-classes +++ b/gcc/ChangeLog.gimple-classes @@ -1,5 +1,61 @@ 2014-10-24 David Malcolm <dmalc...@redhat.com> + Introduce gimple_eh_else + + * coretypes.h (gimple_eh_else): New typedef. + (const_gimple_eh_else): New typedef. + + * gimple.h (gimple_build_eh_else): Return a gimple_eh_else rather + than a plain gimple. + (gimple_eh_else_n_body_ptr): Require a gimple_eh_else rather than + a plain gimple. + (gimple_eh_else_n_body): Likewise. + (gimple_eh_else_e_body_ptr): Likewise. + (gimple_eh_else_e_body): Likewise. + (gimple_eh_else_set_n_body): Likewise. + (gimple_eh_else_set_e_body): Likewise. + + * gimple-low.c (lower_stmt): Add checked cast to gimple_eh_else + within GIMPLE_EH_ELSE case of switch statement, introducing a new + local. + (gimple_stmt_may_fallthru): Likewise. + + * gimple-pretty-print.c (dump_gimple_eh_else): Require a + gimple_eh_else rather than a plain gimple. + (pp_gimple_stmt_1): Add checked cast to gimple_eh_else within + GIMPLE_EH_ELSE case of switch statement + + * gimple-walk.c (walk_gimple_stmt): Add checked cast to + gimple_eh_else within GIMPLE_EH_ELSE case of switch statement, + introducing a new local. + + * gimple.c (gimple_build_eh_else): Return a gimple_eh_else + rather than a plain gimple. + (gimple_copy): Add checked casts to gimple_eh_else within + GIMPLE_EH_ELSE case of switch statement, introducing new locals. + + * tree-cfg.c (verify_gimple_in_seq_2): Add checked cast to + gimple_eh_else within GIMPLE_EH_ELSE case of switch statement, + introducing a new local. + + * tree-eh.c (collect_finally_tree): Likewise. + (replace_goto_queue_1): Likewise. + (get_eh_else): Return a gimple_eh_else rather than a plain gimple. + (honor_protect_cleanup_actions): Convert local "eh_else" from + gimple to gimple_eh_else. + (lower_try_finally_nofallthru): Likewise. + (lower_try_finally_onedest): Introduce locals "eh_else" and + "label_stmt", using them in favor of "x" for the gimple_eh_else + and the gimple_label. + (lower_try_finally_copy): Convert local "eh_else" from gimple to + gimple_eh_else. + (lower_try_finally_switch): Likewise. + (decide_copy_try_finally): Likewise. + (refactor_eh_r): Add checked cast to gimple_eh_else within + GIMPLE_EH_ELSE case of switch statement, introducing a new local. + +2014-10-24 David Malcolm <dmalc...@redhat.com> + Introduce gimple_eh_must_not_throw * coretypes.h (gimple_eh_must_not_throw): New typedef. diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 51b73f6..ba076ec 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -146,6 +146,10 @@ struct gimple_statement_eh_mnt; typedef struct gimple_statement_eh_mnt *gimple_eh_must_not_throw; typedef const struct gimple_statement_eh_mnt *const_gimple_eh_must_not_throw; +struct gimple_statement_eh_else; +typedef struct gimple_statement_eh_else *gimple_eh_else; +typedef const struct gimple_statement_eh_else *const_gimple_eh_else; + struct gimple_statement_phi; typedef struct gimple_statement_phi *gimple_phi; typedef const struct gimple_statement_phi *const_gimple_phi; diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index 9ac984e..b5dc823 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -288,8 +288,11 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data) return; case GIMPLE_EH_ELSE: - lower_sequence (gimple_eh_else_n_body_ptr (stmt), data); - lower_sequence (gimple_eh_else_e_body_ptr (stmt), data); + { + gimple_eh_else eh_else_stmt = as_a <gimple_eh_else> (stmt); + lower_sequence (gimple_eh_else_n_body_ptr (eh_else_stmt), data); + lower_sequence (gimple_eh_else_e_body_ptr (eh_else_stmt), data); + } break; case GIMPLE_NOP: @@ -597,8 +600,12 @@ gimple_stmt_may_fallthru (gimple stmt) && gimple_seq_may_fallthru (gimple_try_cleanup (stmt))); case GIMPLE_EH_ELSE: - return (gimple_seq_may_fallthru (gimple_eh_else_n_body (stmt)) - || gimple_seq_may_fallthru (gimple_eh_else_e_body (stmt))); + { + gimple_eh_else eh_else_stmt = as_a <gimple_eh_else> (stmt); + return (gimple_seq_may_fallthru (gimple_eh_else_n_body (eh_else_stmt)) + || gimple_seq_may_fallthru (gimple_eh_else_e_body ( + eh_else_stmt))); + } case GIMPLE_CALL: /* Functions that do not return do not fall through. */ diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 42f94a3..a82049f 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1038,7 +1038,8 @@ dump_gimple_eh_must_not_throw (pretty_printer *buffer, dumpfile.h). */ static void -dump_gimple_eh_else (pretty_printer *buffer, gimple gs, int spc, int flags) +dump_gimple_eh_else (pretty_printer *buffer, gimple_eh_else gs, int spc, + int flags) { if (flags & TDF_RAW) dump_gimple_fmt (buffer, spc, flags, @@ -2209,7 +2210,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags) break; case GIMPLE_EH_ELSE: - dump_gimple_eh_else (buffer, gs, spc, flags); + dump_gimple_eh_else (buffer, as_a <gimple_eh_else> (gs), spc, flags); break; case GIMPLE_RESX: diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c index fc74f49..d36263a 100644 --- a/gcc/gimple-walk.c +++ b/gcc/gimple-walk.c @@ -566,14 +566,17 @@ walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt, break; case GIMPLE_EH_ELSE: - ret = walk_gimple_seq_mod (gimple_eh_else_n_body_ptr (stmt), - callback_stmt, callback_op, wi); - if (ret) - return wi->callback_result; - ret = walk_gimple_seq_mod (gimple_eh_else_e_body_ptr (stmt), - callback_stmt, callback_op, wi); - if (ret) - return wi->callback_result; + { + gimple_eh_else eh_else_stmt = as_a <gimple_eh_else> (stmt); + ret = walk_gimple_seq_mod (gimple_eh_else_n_body_ptr (eh_else_stmt), + callback_stmt, callback_op, wi); + if (ret) + return wi->callback_result; + ret = walk_gimple_seq_mod (gimple_eh_else_e_body_ptr (eh_else_stmt), + callback_stmt, callback_op, wi); + if (ret) + return wi->callback_result; + } break; case GIMPLE_TRY: diff --git a/gcc/gimple.c b/gcc/gimple.c index a52d989..b3c663c 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -660,10 +660,10 @@ gimple_build_eh_must_not_throw (tree decl) /* Build a GIMPLE_EH_ELSE statement. */ -gimple +gimple_eh_else gimple_build_eh_else (gimple_seq n_body, gimple_seq e_body) { - gimple p = gimple_alloc (GIMPLE_EH_ELSE, 0); + gimple_eh_else p = as_a <gimple_eh_else> (gimple_alloc (GIMPLE_EH_ELSE, 0)); gimple_eh_else_set_n_body (p, n_body); gimple_eh_else_set_e_body (p, e_body); return p; @@ -1685,10 +1685,14 @@ gimple_copy (gimple stmt) break; case GIMPLE_EH_ELSE: - new_seq = gimple_seq_copy (gimple_eh_else_n_body (stmt)); - gimple_eh_else_set_n_body (copy, new_seq); - new_seq = gimple_seq_copy (gimple_eh_else_e_body (stmt)); - gimple_eh_else_set_e_body (copy, new_seq); + { + gimple_eh_else eh_else_stmt = as_a <gimple_eh_else> (stmt); + gimple_eh_else eh_else_copy = as_a <gimple_eh_else> (copy); + new_seq = gimple_seq_copy (gimple_eh_else_n_body (eh_else_stmt)); + gimple_eh_else_set_n_body (eh_else_copy, new_seq); + new_seq = gimple_seq_copy (gimple_eh_else_e_body (eh_else_stmt)); + gimple_eh_else_set_e_body (eh_else_copy, new_seq); + } break; case GIMPLE_TRY: diff --git a/gcc/gimple.h b/gcc/gimple.h index 445a1c0..9b73e00 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1328,7 +1328,7 @@ gimple_asm gimple_build_asm_vec (const char *, vec<tree, va_gc> *, gimple_catch gimple_build_catch (tree, gimple_seq); gimple_eh_filter gimple_build_eh_filter (tree, gimple_seq); gimple_eh_must_not_throw gimple_build_eh_must_not_throw (tree); -gimple gimple_build_eh_else (gimple_seq, gimple_seq); +gimple_eh_else gimple_build_eh_else (gimple_seq, gimple_seq); gimple_statement_try *gimple_build_try (gimple_seq, gimple_seq, enum gimple_try_flags); gimple gimple_build_wce (gimple_seq); @@ -3669,46 +3669,38 @@ gimple_eh_must_not_throw_set_fndecl (gimple_eh_must_not_throw eh_mnt_stmt, /* GIMPLE_EH_ELSE accessors. */ static inline gimple_seq * -gimple_eh_else_n_body_ptr (gimple gs) +gimple_eh_else_n_body_ptr (gimple_eh_else eh_else_stmt) { - gimple_statement_eh_else *eh_else_stmt = - as_a <gimple_statement_eh_else *> (gs); return &eh_else_stmt->n_body; } static inline gimple_seq -gimple_eh_else_n_body (gimple gs) +gimple_eh_else_n_body (gimple_eh_else eh_else_stmt) { - return *gimple_eh_else_n_body_ptr (gs); + return *gimple_eh_else_n_body_ptr (eh_else_stmt); } static inline gimple_seq * -gimple_eh_else_e_body_ptr (gimple gs) +gimple_eh_else_e_body_ptr (gimple_eh_else eh_else_stmt) { - gimple_statement_eh_else *eh_else_stmt = - as_a <gimple_statement_eh_else *> (gs); return &eh_else_stmt->e_body; } static inline gimple_seq -gimple_eh_else_e_body (gimple gs) +gimple_eh_else_e_body (gimple_eh_else eh_else_stmt) { - return *gimple_eh_else_e_body_ptr (gs); + return *gimple_eh_else_e_body_ptr (eh_else_stmt); } static inline void -gimple_eh_else_set_n_body (gimple gs, gimple_seq seq) +gimple_eh_else_set_n_body (gimple_eh_else eh_else_stmt, gimple_seq seq) { - gimple_statement_eh_else *eh_else_stmt = - as_a <gimple_statement_eh_else *> (gs); eh_else_stmt->n_body = seq; } static inline void -gimple_eh_else_set_e_body (gimple gs, gimple_seq seq) +gimple_eh_else_set_e_body (gimple_eh_else eh_else_stmt, gimple_seq seq) { - gimple_statement_eh_else *eh_else_stmt = - as_a <gimple_statement_eh_else *> (gs); eh_else_stmt->e_body = seq; } diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index d459228..10422c6 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -4639,8 +4639,11 @@ verify_gimple_in_seq_2 (gimple_seq stmts) break; case GIMPLE_EH_ELSE: - err |= verify_gimple_in_seq_2 (gimple_eh_else_n_body (stmt)); - err |= verify_gimple_in_seq_2 (gimple_eh_else_e_body (stmt)); + { + gimple_eh_else eh_else = as_a <gimple_eh_else> (stmt); + err |= verify_gimple_in_seq_2 (gimple_eh_else_n_body (eh_else)); + err |= verify_gimple_in_seq_2 (gimple_eh_else_e_body (eh_else)); + } break; case GIMPLE_CATCH: diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index d22eb45..fbb40e5 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -273,8 +273,11 @@ collect_finally_tree (gimple stmt, gimple region) break; case GIMPLE_EH_ELSE: - collect_finally_tree_1 (gimple_eh_else_n_body (stmt), region); - collect_finally_tree_1 (gimple_eh_else_e_body (stmt), region); + { + gimple_eh_else eh_else_stmt = as_a <gimple_eh_else> (stmt); + collect_finally_tree_1 (gimple_eh_else_n_body (eh_else_stmt), region); + collect_finally_tree_1 (gimple_eh_else_e_body (eh_else_stmt), region); + } break; default: @@ -529,8 +532,13 @@ replace_goto_queue_1 (gimple stmt, struct leh_tf_state *tf, replace_goto_queue_stmt_list (gimple_eh_filter_failure_ptr (stmt), tf); break; case GIMPLE_EH_ELSE: - replace_goto_queue_stmt_list (gimple_eh_else_n_body_ptr (stmt), tf); - replace_goto_queue_stmt_list (gimple_eh_else_e_body_ptr (stmt), tf); + { + gimple_eh_else eh_else_stmt = as_a <gimple_eh_else> (stmt); + replace_goto_queue_stmt_list (gimple_eh_else_n_body_ptr (eh_else_stmt), + tf); + replace_goto_queue_stmt_list (gimple_eh_else_e_body_ptr (eh_else_stmt), + tf); + } break; default: @@ -940,14 +948,14 @@ lower_try_finally_fallthru_label (struct leh_tf_state *tf) /* A subroutine of lower_try_finally. If FINALLY consits of a GIMPLE_EH_ELSE node, return it. */ -static inline gimple +static inline gimple_eh_else get_eh_else (gimple_seq finally) { gimple x = gimple_seq_first_stmt (finally); if (gimple_code (x) == GIMPLE_EH_ELSE) { gcc_assert (gimple_seq_singleton_p (finally)); - return x; + return as_a <gimple_eh_else> (x); } return NULL; } @@ -981,7 +989,8 @@ honor_protect_cleanup_actions (struct leh_state *outer_state, gimple_stmt_iterator gsi; bool finally_may_fallthru; gimple_seq finally; - gimple x, eh_else; + gimple x; + gimple_eh_else eh_else; /* First check for nothing to do. */ if (lang_hooks.eh_protect_cleanup_actions == NULL) @@ -1049,7 +1058,8 @@ lower_try_finally_nofallthru (struct leh_state *state, struct leh_tf_state *tf) { tree lab; - gimple x, eh_else; + gimple x; + gimple_eh_else eh_else; gimple_seq finally; struct goto_queue_node *q, *qe; @@ -1113,6 +1123,8 @@ static void lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf) { struct goto_queue_node *q, *qe; + gimple_eh_else eh_else; + gimple_label label_stmt; gimple x; gimple_seq finally; gimple_stmt_iterator gsi; @@ -1125,13 +1137,13 @@ lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf) /* Since there's only one destination, and the destination edge can only either be EH or non-EH, that implies that all of our incoming edges are of the same type. Therefore we can lower EH_ELSE immediately. */ - x = get_eh_else (finally); - if (x) + eh_else = get_eh_else (finally); + if (eh_else) { if (tf->may_throw) - finally = gimple_eh_else_e_body (x); + finally = gimple_eh_else_e_body (eh_else); else - finally = gimple_eh_else_n_body (x); + finally = gimple_eh_else_n_body (eh_else); } lower_eh_constructs_1 (state, &finally); @@ -1166,8 +1178,8 @@ lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf) } finally_label = create_artificial_label (loc); - x = gimple_build_label (finally_label); - gimple_seq_add_stmt (&tf->top_p_seq, x); + label_stmt = gimple_build_label (finally_label); + gimple_seq_add_stmt (&tf->top_p_seq, label_stmt); gimple_seq_add_seq (&tf->top_p_seq, finally); @@ -1215,7 +1227,8 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf) gimple_seq finally; gimple_seq new_stmt; gimple_seq seq; - gimple x, eh_else; + gimple x; + gimple_eh_else eh_else; tree tmp; location_t tf_loc = gimple_location (tf->try_finally_expr); @@ -1348,7 +1361,8 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf) tree last_case; vec<tree> case_label_vec; gimple_seq switch_body = NULL; - gimple x, eh_else; + gimple x; + gimple_eh_else eh_else; tree tmp; gimple switch_stmt; gimple_seq finally; @@ -1560,7 +1574,7 @@ static bool decide_copy_try_finally (int ndests, bool may_throw, gimple_seq finally) { int f_estimate, sw_estimate; - gimple eh_else; + gimple_eh_else eh_else; /* If there's an EH_ELSE involved, the exception path is separate and really doesn't come into play for this computation. */ @@ -3072,8 +3086,11 @@ refactor_eh_r (gimple_seq seq) refactor_eh_r (gimple_eh_filter_failure (one)); break; case GIMPLE_EH_ELSE: - refactor_eh_r (gimple_eh_else_n_body (one)); - refactor_eh_r (gimple_eh_else_e_body (one)); + { + gimple_eh_else eh_else_stmt = as_a <gimple_eh_else> (one); + refactor_eh_r (gimple_eh_else_n_body (eh_else_stmt)); + refactor_eh_r (gimple_eh_else_e_body (eh_else_stmt)); + } break; default: break; -- 1.8.5.3