gcc/ * coretypes.h (gimple_return): New typedef. (const_gimple_return): New typedef.
* gimple.h (gimple_statement_return): New subclass of gimple_statement_with_memory_ops, adding the invariant that stmt->code == GIMPLE_RETURN. (gimple_statement_base::as_a_gimple_return): New. (gimple_statement_base::dyn_cast_gimple_return): New. (is_a_helper <gimple_statement_return>::test): New. (gimple_build_return): Return a gimple_return rather than a plain gimple. * gimple.c (gimple_build_return): Return a gimple_return rather than a plain gimple. * cgraphunit.c (expand_thunk): Convert local from a gimple to a gimple_return. * gimple-low.c (struct return_statements_t): Convert field "stmt" from a gimple to a gimple_return. (lower_gimple_return): Convert local from a gimple to a gimple_return. * gimple-pretty-print.c (dump_gimple_return): Require a gimple_return rather than a plain gimple. (pp_gimple_stmt_1): Add a checked cast to gimple_return within case GIMPLE_RETURN of switch statement. * gimplify.c (gimplify_return_expr): Convert locals from gimple to gimple_return. * ipa-split.c (split_function): Likewise. * tree-cfg.c (verify_gimple_assign): Require a gimple_return rather than a plain gimple. (verify_gimple_stmt): Add checked cast to gimple_return within case GIMPLE_RETURN of switch statement. * tree-tailcall.c (adjust_return_value): Convert local from gimple to gimple_return. --- gcc/cgraphunit.c | 2 +- gcc/coretypes.h | 4 ++++ gcc/gimple-low.c | 4 ++-- gcc/gimple-pretty-print.c | 4 ++-- gcc/gimple.c | 5 +++-- gcc/gimple.h | 32 +++++++++++++++++++++++++++++++- gcc/gimplify.c | 4 ++-- gcc/ipa-split.c | 2 +- gcc/tree-cfg.c | 4 ++-- gcc/tree-tailcall.c | 3 ++- 10 files changed, 50 insertions(+), 14 deletions(-) diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 588fe13..dea6335 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1532,7 +1532,7 @@ expand_thunk (struct cgraph_node *node, bool output_asm_thunks) tree restmp = NULL; gimple_call call; - gimple ret; + gimple_return ret; if (in_lto_p) cgraph_get_body (node); diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 0f884fd..d5c62b9 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -93,6 +93,10 @@ struct gimple_statement_call; typedef struct gimple_statement_call *gimple_call; typedef const struct gimple_statement_call *const_gimple_call; +struct gimple_statement_return; +typedef struct gimple_statement_return *gimple_return; +typedef const struct gimple_statement_return *const_gimple_return; + struct gimple_statement_bind; typedef struct gimple_statement_bind *gimple_bind; typedef const struct gimple_statement_bind *const_gimple_bind; diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index d56ff0a..98e001d 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -60,7 +60,7 @@ along with GCC; see the file COPYING3. If not see struct return_statements_t { tree label; - gimple stmt; + gimple_return stmt; }; typedef struct return_statements_t return_statements_t; @@ -621,7 +621,7 @@ gimple_seq_may_fallthru (gimple_seq seq) static void lower_gimple_return (gimple_stmt_iterator *gsi, struct lower_data *data) { - gimple stmt = gsi_stmt (*gsi); + gimple_return stmt = gsi_stmt (*gsi)->as_a_gimple_return (); gimple t; int i; return_statements_t tmp_rs; diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 6b903aa..90baded 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -545,7 +545,7 @@ dump_gimple_assign (pretty_printer *buffer, gimple_assign gs, int spc, int flags pp_gimple_stmt_1. */ static void -dump_gimple_return (pretty_printer *buffer, gimple gs, int spc, int flags) +dump_gimple_return (pretty_printer *buffer, gimple_return gs, int spc, int flags) { tree t; @@ -2123,7 +2123,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags) break; case GIMPLE_RETURN: - dump_gimple_return (buffer, gs, spc, flags); + dump_gimple_return (buffer, gs->as_a_gimple_return (), spc, flags); break; case GIMPLE_SWITCH: diff --git a/gcc/gimple.c b/gcc/gimple.c index 6acf60b..222c068 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -177,10 +177,11 @@ gimple_build_with_ops_stat (enum gimple_code code, unsigned subcode, /* Build a GIMPLE_RETURN statement returning RETVAL. */ -gimple +gimple_return gimple_build_return (tree retval) { - gimple s = gimple_build_with_ops (GIMPLE_RETURN, ERROR_MARK, 1); + gimple_return s = gimple_build_with_ops (GIMPLE_RETURN, ERROR_MARK, + 1)->as_a_gimple_return (); if (retval) gimple_return_set_retval (s, retval); return s; diff --git a/gcc/gimple.h b/gcc/gimple.h index 4e0be1f..39ac2dc 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -246,6 +246,12 @@ public: return as_a <gimple_statement_call> (this); } + inline gimple_return + as_a_gimple_return () + { + return as_a <gimple_statement_return> (this); + } + inline const_gimple_call as_a_gimple_call () const { @@ -308,6 +314,12 @@ public: return dyn_cast <gimple_statement_call> (this); } + inline gimple_return + dyn_cast_gimple_return () + { + return dyn_cast <gimple_statement_return> (this); + } + inline gimple_bind dyn_cast_gimple_bind () { @@ -943,6 +955,16 @@ struct GTY((tag("GSS_WITH_MEM_OPS"))) /* no additional fields; this uses the layout for GSS_WITH_MEM_OPS. */ }; +/* A statement with the invariant that + stmt->code == GIMPLE_RETURN + i.e. a return statement. */ + +struct GTY((tag("GSS_WITH_MEM_OPS"))) + gimple_statement_return : public gimple_statement_with_memory_ops +{ + /* no additional fields; this uses the layout for GSS_WITH_MEM_OPS. */ +}; + template <> template <> inline bool @@ -1162,6 +1184,14 @@ is_a_helper <gimple_statement_phi>::test (gimple gs) template <> template <> inline bool +is_a_helper <gimple_statement_return>::test (gimple gs) +{ + return gs->code == GIMPLE_RETURN; +} + +template <> +template <> +inline bool is_a_helper <gimple_statement_switch>::test (gimple gs) { return gs->code == GIMPLE_SWITCH; @@ -1380,7 +1410,7 @@ extern gimple currently_expanding_gimple_stmt; #define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO) gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL); -gimple gimple_build_return (tree); +gimple_return gimple_build_return (tree); void gimple_call_reset_alias_info (gimple_call); gimple_call gimple_build_call_vec (tree, vec<tree> ); gimple_call gimple_build_call (tree, unsigned, ...); diff --git a/gcc/gimplify.c b/gcc/gimplify.c index bfb8f98..b24ce70 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1153,7 +1153,7 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) static enum gimplify_status gimplify_return_expr (tree stmt, gimple_seq *pre_p) { - gimple ret; + gimple_return ret; tree ret_expr = TREE_OPERAND (stmt, 0); tree result_decl, result; @@ -1173,7 +1173,7 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p) || TREE_CODE (ret_expr) == RESULT_DECL || ret_expr == error_mark_node) { - gimple ret = gimple_build_return (ret_expr); + gimple_return ret = gimple_build_return (ret_expr); gimple_set_no_warning (ret, TREE_NO_WARNING (stmt)); gimplify_seq_add_stmt (pre_p, ret); return GS_ALL_DONE; diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index dbcc787..e5d1368 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -1465,7 +1465,7 @@ split_function (struct split_point *split_point) */ else { - gimple ret; + gimple_return ret; if (split_point->split_part_set_retval && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) { diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 8168d97..1bfed7d 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -4187,7 +4187,7 @@ verify_gimple_assign (gimple_assign stmt) is a problem, otherwise false. */ static bool -verify_gimple_return (gimple stmt) +verify_gimple_return (gimple_return stmt) { tree op = gimple_return_retval (stmt); tree restype = TREE_TYPE (TREE_TYPE (cfun->decl)); @@ -4435,7 +4435,7 @@ verify_gimple_stmt (gimple stmt) return verify_gimple_switch (stmt->as_a_gimple_switch ()); case GIMPLE_RETURN: - return verify_gimple_return (stmt); + return verify_gimple_return (stmt->as_a_gimple_return ()); case GIMPLE_ASM: return false; diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index 71e3c3b..e89f9ba 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -737,7 +737,8 @@ static void adjust_return_value (basic_block bb, tree m, tree a) { tree retval; - gimple ret_stmt = gimple_seq_last_stmt (bb_seq (bb)); + gimple_return ret_stmt = + gimple_seq_last_stmt (bb_seq (bb))->as_a_gimple_return (); gimple_stmt_iterator gsi = gsi_last_bb (bb); gcc_assert (gimple_code (ret_stmt) == GIMPLE_RETURN); -- 1.8.5.3