[tuples] Tuplify pass_stdarg

Jakub Jelinek jakub@redhat.com
Tue Jun 10 12:56:00 GMT 2008


Hi!

This patch tuplifies the stdarg pass.  Bootstrapped/regtested on
x86_64-linux (as an example of struct va_list) and regtested on i686-linux
(an example of char * va_list).  I've left out the alpha bits, because
apparently config/alpha/* isn't tuplified yet at all (and I don't have
access to alpha-linux).

Ok for tuples?

2008-06-10  Jakub Jelinek  <jakub@redhat.com>

	* tree-stdarg.c (va_list_counter_bump): Convert to tuples.
	(check_all_va_list_escapes): Likewise.
	(execute_optimize_stdarg): Likewise.
	(find_va_list_reference): Adjust for data being walk_stmt_info
	pointer.
	(check_va_list_escapes): Don't handle p+ or conversion here.
	(gate_optimize_stdarg): Reenable.
	* target.h (struct target): Pass gimple as second
	argument to stdarg_optimize_hook instead of lhs/rhs pair.
	* config/alpha/alpha.c (alpha_stdarg_optimize_hook): Adjust
	arguments.

--- gcc/tree-stdarg.c.jj	2008-06-09 09:59:29.000000000 +0200
+++ gcc/tree-stdarg.c	2008-06-10 11:42:35.000000000 +0200
@@ -31,8 +31,6 @@ along with GCC; see the file COPYING3.  
 #include "tree-pass.h"
 #include "tree-stdarg.h"
 
-/* FIXME tuples.  */
-#if 0
 /* A simple pass that attempts to optimize stdarg functions on architectures
    that need to save register arguments to stack on entry to stdarg functions.
    If the function doesn't use any va_start macros, no registers need to
@@ -114,7 +112,8 @@ static unsigned HOST_WIDE_INT
 va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
 		      bool gpr_p)
 {
-  tree stmt, lhs, orig_lhs;
+  tree lhs, orig_lhs;
+  gimple stmt;
   unsigned HOST_WIDE_INT ret = 0, val, counter_val;
   unsigned int max_size;
 
@@ -146,38 +145,31 @@ va_list_counter_bump (struct stdarg_info
 
       stmt = SSA_NAME_DEF_STMT (lhs);
 
-      if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
-	  || GIMPLE_STMT_OPERAND (stmt, 0) != lhs)
+      if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != lhs)
 	return (unsigned HOST_WIDE_INT) -1;
 
-      rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-      if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
-	rhs = TREE_OPERAND (rhs, 0);
-
-      if (TREE_CODE (rhs) == SSA_NAME)
+      if ((get_gimple_rhs_class (gimple_subcode (stmt)) == GIMPLE_SINGLE_RHS
+	   || IS_CONVERT_EXPR_CODE_P (gimple_subcode (stmt)))
+	  && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
 	{
-	  lhs = rhs;
+	  lhs = gimple_assign_rhs1 (stmt);
 	  continue;
 	}
 
-      if (CONVERT_EXPR_P (rhs)
-	  && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+      if ((gimple_subcode (stmt) == POINTER_PLUS_EXPR
+	   || gimple_subcode (stmt) == PLUS_EXPR)
+	  && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+	  && host_integerp (gimple_assign_rhs2 (stmt), 1))
 	{
-	  lhs = TREE_OPERAND (rhs, 0);
+	  ret += tree_low_cst (gimple_assign_rhs2 (stmt), 1);
+	  lhs = gimple_assign_rhs1 (stmt);
 	  continue;
 	}
 
-      if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR
-	   || TREE_CODE (rhs) == PLUS_EXPR)
-	  && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
-	  && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST
-	  && host_integerp (TREE_OPERAND (rhs, 1), 1))
-	{
-	  ret += tree_low_cst (TREE_OPERAND (rhs, 1), 1);
-	  lhs = TREE_OPERAND (rhs, 0);
-	  continue;
-	}
+      if (get_gimple_rhs_class (gimple_subcode (stmt)) != GIMPLE_SINGLE_RHS)
+	return (unsigned HOST_WIDE_INT) -1;
 
+      rhs = gimple_assign_rhs1 (stmt);
       if (TREE_CODE (counter) != TREE_CODE (rhs))
 	return (unsigned HOST_WIDE_INT) -1;
 
@@ -208,31 +200,21 @@ va_list_counter_bump (struct stdarg_info
 
       stmt = SSA_NAME_DEF_STMT (lhs);
 
-      rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-      if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
-	rhs = TREE_OPERAND (rhs, 0);
-
-      if (TREE_CODE (rhs) == SSA_NAME)
-	{
-	  lhs = rhs;
-	  continue;
-	}
-
-      if (CONVERT_EXPR_P (rhs)
-	  && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+      if ((get_gimple_rhs_class (gimple_subcode (stmt)) == GIMPLE_SINGLE_RHS
+	   || IS_CONVERT_EXPR_CODE_P (gimple_subcode (stmt)))
+	  && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
 	{
-	  lhs = TREE_OPERAND (rhs, 0);
+	  lhs = gimple_assign_rhs1 (stmt);
 	  continue;
 	}
 
-      if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR
-	   || TREE_CODE (rhs) == PLUS_EXPR)
-	  && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
-	  && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST
-	  && host_integerp (TREE_OPERAND (rhs, 1), 1))
+      if ((gimple_subcode (stmt) == POINTER_PLUS_EXPR
+	   || gimple_subcode (stmt) == PLUS_EXPR)
+	  && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+	  && host_integerp (gimple_assign_rhs2 (stmt), 1))
 	{
-	  val -= tree_low_cst (TREE_OPERAND (rhs, 1), 1);
-	  lhs = TREE_OPERAND (rhs, 0);
+	  val -= tree_low_cst (gimple_assign_rhs2 (stmt), 1);
+	  lhs = gimple_assign_rhs1 (stmt);
 	  continue;
 	}
 
@@ -249,7 +231,7 @@ static tree
 find_va_list_reference (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
 			void *data)
 {
-  bitmap va_list_vars = (bitmap) data;
+  bitmap va_list_vars = (bitmap) ((struct walk_stmt_info *) data)->info;
   tree var = *tp;
 
   if (TREE_CODE (var) == SSA_NAME)
@@ -444,12 +426,6 @@ check_va_list_escapes (struct stdarg_inf
   if (! POINTER_TYPE_P (TREE_TYPE (rhs)))
     return;
 
- if (((TREE_CODE (rhs) == POINTER_PLUS_EXPR
-       || TREE_CODE (rhs) == PLUS_EXPR)
-      && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
-     || CONVERT_EXPR_P (rhs))
-    rhs = TREE_OPERAND (rhs, 0);
-
   if (TREE_CODE (rhs) != SSA_NAME
       || ! bitmap_bit_p (si->va_list_escape_vars,
 			 DECL_UID (SSA_NAME_VAR (rhs))))
@@ -506,11 +482,12 @@ check_all_va_list_escapes (struct stdarg
 
   FOR_EACH_BB (bb)
     {
-      block_stmt_iterator i;
+      gimple_stmt_iterator i;
 
-      for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+      for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
 	{
-	  tree stmt = bsi_stmt (i), use;
+	  gimple stmt = gsi_stmt (i);
+	  tree use;
 	  ssa_op_iter iter;
 
 	  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES)
@@ -519,16 +496,12 @@ check_all_va_list_escapes (struct stdarg
 				  DECL_UID (SSA_NAME_VAR (use))))
 		continue;
 
-	      if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+	      if (is_gimple_assign (stmt))
 		{
-		  tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
-		  tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
-		  if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
-		    rhs = TREE_OPERAND (rhs, 0);
+		  tree rhs = gimple_assign_rhs1 (stmt);
 
 		  /* x = *ap_temp;  */
-		  if (TREE_CODE (rhs) == INDIRECT_REF
+		  if (gimple_assign_rhs_code (stmt) == INDIRECT_REF
 		      && TREE_OPERAND (rhs, 0) == use
 		      && TYPE_SIZE_UNIT (TREE_TYPE (rhs))
 		      && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (rhs)), 1)
@@ -552,13 +525,16 @@ check_all_va_list_escapes (struct stdarg
 		     other_ap_temp = (some_type *) ap_temp;
 		     ap = ap_temp;
 		     statements.  */
-		  if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR
-		       && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
-		      || CONVERT_EXPR_P (rhs))
-		    rhs = TREE_OPERAND (rhs, 0);
-
-		  if (rhs == use)
+		  if (rhs == use
+		      && ((gimple_subcode (stmt) == POINTER_PLUS_EXPR
+			   && (TREE_CODE (gimple_assign_rhs2 (stmt))
+			       == INTEGER_CST))
+			  || IS_CONVERT_EXPR_CODE_P (gimple_subcode (stmt))
+			  || (get_gimple_rhs_class (gimple_subcode (stmt))
+			      == GIMPLE_SINGLE_RHS)))
 		    {
+		      tree lhs = gimple_assign_lhs (stmt);
+
 		      if (TREE_CODE (lhs) == SSA_NAME
 			  && bitmap_bit_p (si->va_list_escape_vars,
 					   DECL_UID (SSA_NAME_VAR (lhs))))
@@ -574,7 +550,7 @@ check_all_va_list_escapes (struct stdarg
 	      if (dump_file && (dump_flags & TDF_DETAILS))
 		{
 		  fputs ("va_list escapes in ", dump_file);
-		  print_generic_expr (dump_file, stmt, dump_flags);
+		  print_gimple_stmt (dump_file, stmt, 0, dump_flags);
 		  fputc ('\n', dump_file);
 		}
 	      return true;
@@ -584,7 +560,7 @@ check_all_va_list_escapes (struct stdarg
 
   return false;
 }
-#endif
+
 
 /* Return true if this optimization pass should be done.
    It makes only sense for stdarg functions.  */
@@ -592,13 +568,8 @@ check_all_va_list_escapes (struct stdarg
 static bool
 gate_optimize_stdarg (void)
 {
-  /* FIXME tuples */
-#if 0
   /* This optimization is only for stdarg functions.  */
   return cfun->stdarg != 0;
-#else
-  return 0;
-#endif
 }
 
 
@@ -607,12 +578,11 @@ gate_optimize_stdarg (void)
 static unsigned int
 execute_optimize_stdarg (void)
 {
-  /* FIXME tuples */
-#if 0
   basic_block bb;
   bool va_list_escapes = false;
   bool va_list_simple_ptr;
   struct stdarg_info si;
+  struct walk_stmt_info wi;
   const char *funcname = NULL;
 
   cfun->va_list_gpr_size = 0;
@@ -631,18 +601,17 @@ execute_optimize_stdarg (void)
 
   FOR_EACH_BB (bb)
     {
-      block_stmt_iterator i;
+      gimple_stmt_iterator i;
 
-      for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+      for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
 	{
-	  tree stmt = bsi_stmt (i);
-	  tree call = get_call_expr_in (stmt), callee;
-	  tree ap;
+	  gimple stmt = gsi_stmt (i);
+	  tree callee, ap;
 
-	  if (!call)
+	  if (!is_gimple_call (stmt))
 	    continue;
 
-	  callee = get_callee_fndecl (call);
+	  callee = gimple_call_fndecl (stmt);
 	  if (!callee
 	      || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
 	    continue;
@@ -662,7 +631,7 @@ execute_optimize_stdarg (void)
 	    }
 
 	  si.va_start_count++;
-	  ap = CALL_EXPR_ARG (call, 0);
+	  ap = gimple_call_arg (stmt, 0);
 
 	  if (TREE_CODE (ap) != ADDR_EXPR)
 	    {
@@ -738,10 +707,12 @@ execute_optimize_stdarg (void)
     cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
 
   calculate_dominance_info (CDI_DOMINATORS);
+  memset (&wi, 0, sizeof (wi));
+  wi.info = si.va_list_vars;
 
   FOR_EACH_BB (bb)
     {
-      block_stmt_iterator i;
+      gimple_stmt_iterator i;
 
       si.compute_sizes = -1;
       si.bb = bb;
@@ -752,12 +723,13 @@ execute_optimize_stdarg (void)
 	 any real data movement.  */
       if (va_list_simple_ptr)
 	{
-	  tree phi, lhs, rhs;
+	  tree lhs, rhs;
 	  use_operand_p uop;
 	  ssa_op_iter soi;
 
-	  for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+	  for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
 	    {
+	      gimple phi = gsi_stmt (i);
 	      lhs = PHI_RESULT (phi);
 
 	      if (!is_gimple_reg (lhs))
@@ -773,14 +745,12 @@ execute_optimize_stdarg (void)
 		  else
 		    check_va_list_escapes (&si, lhs, rhs);
 
-		  if (si.va_list_escapes
-		      || walk_tree (&phi, find_va_list_reference,
-				    si.va_list_vars, NULL))
+		  if (si.va_list_escapes)
 		    {
 		      if (dump_file && (dump_flags & TDF_DETAILS))
 			{
 			  fputs ("va_list escapes in ", dump_file);
-			  print_generic_expr (dump_file, phi, dump_flags);
+			  print_gimple_stmt (dump_file, phi, 0, dump_flags);
 			  fputc ('\n', dump_file);
 			}
 		      va_list_escapes = true;
@@ -789,18 +759,16 @@ execute_optimize_stdarg (void)
 	    }
 	}
 
-      for (i = bsi_start (bb);
-	   !bsi_end_p (i) && !va_list_escapes;
-	   bsi_next (&i))
+      for (i = gsi_start_bb (bb);
+	   !gsi_end_p (i) && !va_list_escapes;
+	   gsi_next (&i))
 	{
-	  tree stmt = bsi_stmt (i);
-	  tree call;
+	  gimple stmt = gsi_stmt (i);
 
 	  /* Don't look at __builtin_va_{start,end}, they are ok.  */
-	  call = get_call_expr_in (stmt);
-	  if (call)
+	  if (is_gimple_call (stmt))
 	    {
-	      tree callee = get_callee_fndecl (call);
+	      tree callee = gimple_call_fndecl (stmt);
 
 	      if (callee
 		  && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
@@ -809,44 +777,54 @@ execute_optimize_stdarg (void)
 		continue;
 	    }
 
-	  if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+	  if (is_gimple_assign (stmt))
 	    {
-	      tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
-	      tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
-	      if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
-		rhs = TREE_OPERAND (rhs, 0);
+	      tree lhs = gimple_assign_lhs (stmt);
+	      tree rhs = gimple_assign_rhs1 (stmt);
 
 	      if (va_list_simple_ptr)
 		{
-		  /* Check for tem = ap.  */
-		  if (va_list_ptr_read (&si, rhs, lhs))
-		    continue;
+		  if (get_gimple_rhs_class (gimple_subcode (stmt))
+		      == GIMPLE_SINGLE_RHS)
+		    {
+		      /* Check for tem = ap.  */
+		      if (va_list_ptr_read (&si, rhs, lhs))
+			continue;
 
-		  /* Check for the last insn in:
-		     tem1 = ap;
-		     tem2 = tem1 + CST;
-		     ap = tem2;
-		     sequence.  */
-		  else if (va_list_ptr_write (&si, lhs, rhs))
-		    continue;
+		      /* Check for the last insn in:
+			 tem1 = ap;
+			 tem2 = tem1 + CST;
+			 ap = tem2;
+			 sequence.  */
+		      else if (va_list_ptr_write (&si, lhs, rhs))
+			continue;
+		    }
 
-		  else
+		  if ((gimple_subcode (stmt) == POINTER_PLUS_EXPR
+		       && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST)
+		      || IS_CONVERT_EXPR_CODE_P (gimple_subcode (stmt))
+		      || (get_gimple_rhs_class (gimple_subcode (stmt))
+			  == GIMPLE_SINGLE_RHS))
 		    check_va_list_escapes (&si, lhs, rhs);
 		}
 	      else
 		{
-		  /* Check for ap[0].field = temp.  */
-		  if (va_list_counter_struct_op (&si, lhs, rhs, true))
-		    continue;
+		  if (get_gimple_rhs_class (gimple_subcode (stmt))
+		      == GIMPLE_SINGLE_RHS)
+		    {
+		      /* Check for ap[0].field = temp.  */
+		      if (va_list_counter_struct_op (&si, lhs, rhs, true))
+			continue;
 
-		  /* Check for temp = ap[0].field.  */
-		  else if (va_list_counter_struct_op (&si, rhs, lhs, false))
-		    continue;
+		      /* Check for temp = ap[0].field.  */
+		      else if (va_list_counter_struct_op (&si, rhs, lhs,
+							  false))
+			continue;
+		    }
 
 		  /* Do any architecture specific checking.  */
-		  else if (targetm.stdarg_optimize_hook
-			   && targetm.stdarg_optimize_hook (&si, lhs, rhs))
+		  if (targetm.stdarg_optimize_hook
+		      && targetm.stdarg_optimize_hook (&si, stmt))
 		    continue;
 		}
 	    }
@@ -858,13 +836,12 @@ execute_optimize_stdarg (void)
 	     fully), or some unexpected use of va_list.  None of these should
 	     happen in a gimplified VA_ARG_EXPR.  */
 	  if (si.va_list_escapes
-	      || walk_tree (&stmt, find_va_list_reference,
-			    si.va_list_vars, NULL))
+	      || walk_gimple_op (stmt, find_va_list_reference, &wi))
 	    {
 	      if (dump_file && (dump_flags & TDF_DETAILS))
 		{
 		  fputs ("va_list escapes in ", dump_file);
-		  print_generic_expr (dump_file, stmt, dump_flags);
+		  print_gimple_stmt (dump_file, stmt, 0, dump_flags);
 		  fputc ('\n', dump_file);
 		}
 	      va_list_escapes = true;
@@ -906,9 +883,6 @@ finish:
       fputs (" FPR units.\n", dump_file);
     }
   return 0;
-#else
-  gcc_unreachable ();
-#endif
 }
 
 
--- gcc/target.h.jj	2008-06-09 09:59:29.000000000 +0200
+++ gcc/target.h	2008-06-10 10:37:01.000000000 +0200
@@ -745,10 +745,9 @@ struct gcc_target
   void (* dwarf_handle_frame_unspec) (const char *, rtx, int);
 
   /* Perform architecture specific checking of statements gimplified
-     from VA_ARG_EXPR.  LHS is left hand side of MODIFY_EXPR, RHS
-     is right hand side.  Returns true if the statements doesn't need
-     to be checked for va_list references.  */
-  bool (* stdarg_optimize_hook) (struct stdarg_info *ai, const_tree lhs, const_tree rhs);
+     from VA_ARG_EXPR.  STMT is the statement.  Returns true if the statement
+     doesn't need to be checked for va_list references.  */
+  bool (* stdarg_optimize_hook) (struct stdarg_info *ai, const_gimple stmt);
 
   /* This target hook allows the operating system to override the DECL
      that represents the external variable that contains the stack
--- gcc/config/alpha/alpha.c.jj	2008-06-09 09:59:11.000000000 +0200
+++ gcc/config/alpha/alpha.c	2008-06-10 10:47:59.000000000 +0200
@@ -5856,11 +5856,17 @@ va_list_skip_additions (tree lhs)
    current statement.  */
 
 static bool
-alpha_stdarg_optimize_hook (struct stdarg_info *si, const_tree lhs, const_tree rhs)
+alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
 {
   tree base, offset, arg1, arg2;
   int offset_arg = 1;
 
+#if 1
+  /* FIXME tuples.  */
+  (void) si;
+  (void) stmt;
+  return false;
+#else
   while (handled_component_p (rhs))
     rhs = TREE_OPERAND (rhs, 0);
   if (TREE_CODE (rhs) != INDIRECT_REF
@@ -5953,6 +5959,7 @@ alpha_stdarg_optimize_hook (struct stdar
 escapes:
   si->va_list_escapes = true;
   return false;
+#endif
 }
 #endif
 

	Jakub



More information about the Gcc-patches mailing list