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