This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fixup stdarg handling with &MEM_REF style pointer bumps


This fixes the fallout of executing forwprop after FRE which runs
before stdarg.  forwprop transforms series of pointer increments to
pointer increments of larger offset and uses &MEM[ptr + CST] as
canonical form for ptr + CST (the former is is_gimple_min_invariant).

Bootstrapped and tested on x86_64-unknown-linux-gnu together with
early FRE.  Now re-bootstrapping and testing w/o that.

I'm planning to commit this after that testing finished.

Thanks,
Richard.

2011-03-23  Richard Guenther  <rguenther@suse.de>

	* tree-stdarg.c (va_list_counter_bump): Handle bumps via
	MEM_REF.
	(check_va_list_escapes): Likewise.
	(check_all_va_list_escapes): Likewise.

Index: gcc/tree-stdarg.c
===================================================================
*** gcc/tree-stdarg.c	(revision 171340)
--- gcc/tree-stdarg.c	(working copy)
*************** va_list_counter_bump (struct stdarg_info
*** 133,138 ****
--- 133,139 ----
    while (lhs)
      {
        enum tree_code rhs_code;
+       tree rhs1;
  
        if (si->offsets[SSA_NAME_VERSION (lhs)] != -1)
  	{
*************** va_list_counter_bump (struct stdarg_info
*** 152,172 ****
  	return (unsigned HOST_WIDE_INT) -1;
  
        rhs_code = gimple_assign_rhs_code (stmt);
        if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
  	   || gimple_assign_cast_p (stmt))
! 	  && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
  	{
! 	  lhs = gimple_assign_rhs1 (stmt);
  	  continue;
  	}
  
        if ((rhs_code == POINTER_PLUS_EXPR
  	   || rhs_code == PLUS_EXPR)
! 	  && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
  	  && host_integerp (gimple_assign_rhs2 (stmt), 1))
  	{
  	  ret += tree_low_cst (gimple_assign_rhs2 (stmt), 1);
! 	  lhs = gimple_assign_rhs1 (stmt);
  	  continue;
  	}
  
--- 153,184 ----
  	return (unsigned HOST_WIDE_INT) -1;
  
        rhs_code = gimple_assign_rhs_code (stmt);
+       rhs1 = gimple_assign_rhs1 (stmt);
        if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
  	   || gimple_assign_cast_p (stmt))
! 	  && TREE_CODE (rhs1) == SSA_NAME)
  	{
! 	  lhs = rhs1;
  	  continue;
  	}
  
        if ((rhs_code == POINTER_PLUS_EXPR
  	   || rhs_code == PLUS_EXPR)
! 	  && TREE_CODE (rhs1) == SSA_NAME
  	  && host_integerp (gimple_assign_rhs2 (stmt), 1))
  	{
  	  ret += tree_low_cst (gimple_assign_rhs2 (stmt), 1);
! 	  lhs = rhs1;
! 	  continue;
! 	}
! 
!       if (rhs_code == ADDR_EXPR 
! 	  && TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
! 	  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0)) == SSA_NAME
! 	  && host_integerp (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1), 1))
! 	{
! 	  ret += tree_low_cst (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1), 1);
! 	  lhs = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
  	  continue;
  	}
  
*************** va_list_counter_bump (struct stdarg_info
*** 195,200 ****
--- 207,213 ----
    while (lhs)
      {
        enum tree_code rhs_code;
+       tree rhs1;
  
        if (si->offsets[SSA_NAME_VERSION (lhs)] != -1)
  	break;
*************** va_list_counter_bump (struct stdarg_info
*** 207,227 ****
        stmt = SSA_NAME_DEF_STMT (lhs);
  
        rhs_code = gimple_assign_rhs_code (stmt);
        if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
  	   || gimple_assign_cast_p (stmt))
! 	  && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
  	{
! 	  lhs = gimple_assign_rhs1 (stmt);
  	  continue;
  	}
  
        if ((rhs_code == POINTER_PLUS_EXPR
  	   || rhs_code == PLUS_EXPR)
! 	  && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
  	  && host_integerp (gimple_assign_rhs2 (stmt), 1))
  	{
  	  val -= tree_low_cst (gimple_assign_rhs2 (stmt), 1);
! 	  lhs = gimple_assign_rhs1 (stmt);
  	  continue;
  	}
  
--- 220,251 ----
        stmt = SSA_NAME_DEF_STMT (lhs);
  
        rhs_code = gimple_assign_rhs_code (stmt);
+       rhs1 = gimple_assign_rhs1 (stmt);
        if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
  	   || gimple_assign_cast_p (stmt))
! 	  && TREE_CODE (rhs1) == SSA_NAME)
  	{
! 	  lhs = rhs1;
  	  continue;
  	}
  
        if ((rhs_code == POINTER_PLUS_EXPR
  	   || rhs_code == PLUS_EXPR)
! 	  && TREE_CODE (rhs1) == SSA_NAME
  	  && host_integerp (gimple_assign_rhs2 (stmt), 1))
  	{
  	  val -= tree_low_cst (gimple_assign_rhs2 (stmt), 1);
! 	  lhs = rhs1;
! 	  continue;
! 	}
! 
!       if (rhs_code == ADDR_EXPR 
! 	  && TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
! 	  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0)) == SSA_NAME
! 	  && host_integerp (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1), 1))
! 	{
! 	  val -= tree_low_cst (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1), 1);
! 	  lhs = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
  	  continue;
  	}
  
*************** check_va_list_escapes (struct stdarg_inf
*** 433,441 ****
    if (! POINTER_TYPE_P (TREE_TYPE (rhs)))
      return;
  
!   if (TREE_CODE (rhs) != SSA_NAME
!       || ! bitmap_bit_p (si->va_list_escape_vars,
! 			 DECL_UID (SSA_NAME_VAR (rhs))))
      return;
  
    if (TREE_CODE (lhs) != SSA_NAME || is_global_var (SSA_NAME_VAR (lhs)))
--- 457,478 ----
    if (! POINTER_TYPE_P (TREE_TYPE (rhs)))
      return;
  
!   if (TREE_CODE (rhs) == SSA_NAME)
!     {
!       if (! bitmap_bit_p (si->va_list_escape_vars,
! 			  DECL_UID (SSA_NAME_VAR (rhs))))
! 	return;
!     }
!   else if (TREE_CODE (rhs) == ADDR_EXPR
! 	   && TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF
! 	   && TREE_CODE (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0)) == SSA_NAME)
!     {
!       if (! bitmap_bit_p (si->va_list_escape_vars,
! 			  DECL_UID (SSA_NAME_VAR (TREE_OPERAND
! 						  (TREE_OPERAND (rhs, 0), 0)))))
! 	return;
!     }
!   else
      return;
  
    if (TREE_CODE (lhs) != SSA_NAME || is_global_var (SSA_NAME_VAR (lhs)))
*************** check_all_va_list_escapes (struct stdarg
*** 512,518 ****
  		  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
  
  		  /* x = *ap_temp;  */
! 		  if (gimple_assign_rhs_code (stmt) == MEM_REF
  		      && TREE_OPERAND (rhs, 0) == use
  		      && TYPE_SIZE_UNIT (TREE_TYPE (rhs))
  		      && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (rhs)), 1)
--- 549,555 ----
  		  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
  
  		  /* x = *ap_temp;  */
! 		  if (rhs_code == MEM_REF
  		      && TREE_OPERAND (rhs, 0) == use
  		      && TYPE_SIZE_UNIT (TREE_TYPE (rhs))
  		      && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (rhs)), 1)
*************** check_all_va_list_escapes (struct stdarg
*** 557,562 ****
--- 594,609 ----
  					   DECL_UID (lhs)))
  			continue;
  		    }
+ 		  else if (rhs_code == ADDR_EXPR
+ 			   && TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF
+ 			   && TREE_OPERAND (TREE_OPERAND (rhs, 0), 0) == use)
+ 		    {
+ 		      tree lhs = gimple_assign_lhs (stmt);
+ 
+ 		      if (bitmap_bit_p (si->va_list_escape_vars,
+ 					DECL_UID (SSA_NAME_VAR (lhs))))
+ 			continue;
+ 		    }
  		}
  
  	      if (dump_file && (dump_flags & TDF_DETAILS))


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]