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  <rguent...@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))

Reply via email to