From bda223fb18aefcb78709a6acd42bd47bdc4e0a07 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 20 Dec 2013 18:26:43 -0500
Subject: [PATCH 83/89] Concretize gimple_call_set_tail and gimple_call_tail_p

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

