gcc/ * gimple.h (gimple_call_set_tail): Require a gimple_call. (gimple_call_tail_p): Likewise.
* cfgexpand.c (expand_gimple_tailcall): Likewise. (expand_gimple_basic_block): Convert calls to is_gimple_call to a dyn_cast, introducing a new "call_stmt" local. * trans-mem.c (expand_block_edges): Likewise, for comparison against GIMPLE_CALL. * tree-tailcall.c (optimize_tail_call): Add checked cast to gimple_call for t->call_gsi. --- gcc/cfgexpand.c | 13 +++++++------ gcc/gimple.h | 6 ++---- gcc/trans-mem.c | 20 ++++++++++++-------- gcc/tree-tailcall.c | 2 +- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 4768a69..983cec0 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -3345,7 +3345,7 @@ expand_gimple_stmt (gimple stmt) tailcall) and the normal result happens via a sqrt instruction. */ static basic_block -expand_gimple_tailcall (basic_block bb, gimple stmt, bool *can_fallthru) +expand_gimple_tailcall (basic_block bb, gimple_call stmt, bool *can_fallthru) { rtx last2, last; edge e; @@ -5115,15 +5115,16 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) } else { - if (is_gimple_call (stmt) - && gimple_call_tail_p (stmt) + gimple_call call_stmt = stmt->dyn_cast_gimple_call (); + if (call_stmt + && gimple_call_tail_p (call_stmt) && disable_tail_calls) - gimple_call_set_tail (stmt, false); + gimple_call_set_tail (call_stmt, false); - if (is_gimple_call (stmt) && gimple_call_tail_p (stmt)) + if (call_stmt && gimple_call_tail_p (call_stmt)) { bool can_fallthru; - new_bb = expand_gimple_tailcall (bb, stmt, &can_fallthru); + new_bb = expand_gimple_tailcall (bb, call_stmt, &can_fallthru); if (new_bb) { if (can_fallthru) diff --git a/gcc/gimple.h b/gcc/gimple.h index 328fdf3..a7829a4 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -3086,9 +3086,8 @@ gimple_call_set_arg (gimple gs, unsigned index, tree arg) candidate for tail call optimization. */ static inline void -gimple_call_set_tail (gimple s, bool tail_p) +gimple_call_set_tail (gimple_call s, bool tail_p) { - GIMPLE_CHECK (s, GIMPLE_CALL); if (tail_p) s->subcode |= GF_CALL_TAILCALL; else @@ -3099,9 +3098,8 @@ gimple_call_set_tail (gimple s, bool tail_p) /* Return true if GIMPLE_CALL S is marked as a tail call. */ static inline bool -gimple_call_tail_p (gimple s) +gimple_call_tail_p (gimple_call s) { - GIMPLE_CHECK (s, GIMPLE_CALL); return (s->subcode & GF_CALL_TAILCALL) != 0; } diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index febc817..f336985 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -3131,23 +3131,26 @@ expand_block_edges (struct tm_region *const region, basic_block bb) for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi = next_gsi) { gimple stmt = gsi_stmt (gsi); + gimple_call call_stmt; next_gsi = gsi; gsi_next (&next_gsi); // ??? Shouldn't we split for any non-pure, non-irrevocable function? - if (gimple_code (stmt) != GIMPLE_CALL - || (gimple_call_flags (stmt) & ECF_TM_BUILTIN) == 0) + call_stmt = stmt->dyn_cast_gimple_call (); + if ((!call_stmt) + || (gimple_call_flags (call_stmt) & ECF_TM_BUILTIN) == 0) continue; - if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)) == BUILT_IN_TM_ABORT) + if (DECL_FUNCTION_CODE (gimple_call_fndecl (call_stmt)) + == BUILT_IN_TM_ABORT) { // If we have a ``_transaction_cancel [[outer]]'', there is only // one abnormal edge: to the transaction marked OUTER. // All compiler-generated instances of BUILT_IN_TM_ABORT have a // constant argument, which we can examine here. Users invoking // TM_ABORT directly get what they deserve. - tree arg = gimple_call_arg (stmt, 0); + tree arg = gimple_call_arg (call_stmt, 0); if (TREE_CODE (arg) == INTEGER_CST && (TREE_INT_CST_LOW (arg) & AR_OUTERABORT) != 0 && !decl_is_tm_clone (current_function_decl)) @@ -3156,7 +3159,7 @@ expand_block_edges (struct tm_region *const region, basic_block bb) for (struct tm_region *o = region; o; o = o->outer) if (o->original_transaction_was_outer) { - split_bb_make_tm_edge (stmt, o->restart_block, + split_bb_make_tm_edge (call_stmt, o->restart_block, gsi, &next_gsi); break; } @@ -3169,7 +3172,8 @@ expand_block_edges (struct tm_region *const region, basic_block bb) // Non-outer, TM aborts have an abnormal edge to the inner-most // transaction, the one being aborted; - split_bb_make_tm_edge (stmt, region->restart_block, gsi, &next_gsi); + split_bb_make_tm_edge (call_stmt, region->restart_block, gsi, + &next_gsi); } // All TM builtins have an abnormal edge to the outer-most transaction. @@ -3187,14 +3191,14 @@ expand_block_edges (struct tm_region *const region, basic_block bb) for (struct tm_region *o = region; o; o = o->outer) if (!o->outer) { - split_bb_make_tm_edge (stmt, o->restart_block, gsi, &next_gsi); + split_bb_make_tm_edge (call_stmt, o->restart_block, gsi, &next_gsi); break; } // Delete any tail-call annotation that may have been added. // The tail-call pass may have mis-identified the commit as being // a candidate because we had not yet added this restart edge. - gimple_call_set_tail (stmt, false); + gimple_call_set_tail (call_stmt, false); } } diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index d3f2504..8aed535 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -910,7 +910,7 @@ optimize_tail_call (struct tailcall *t, bool opt_tailcalls) if (opt_tailcalls) { - gimple stmt = gsi_stmt (t->call_gsi); + gimple_call stmt = gsi_stmt (t->call_gsi)->as_a_gimple_call (); gimple_call_set_tail (stmt, true); cfun->tail_call_marked = true; -- 1.8.5.3