Pointer Plus Patch

Bernhard Fischer rep.dot.nop@gmail.com
Wed Jun 13 12:33:00 GMT 2007


On Wed, Jun 13, 2007 at 01:47:15AM -0700, Andrew Pinski wrote:

>Should I just go ahead and merge it tomorrow or wait for review of the 
>patch?

A few cosmetic commentary typos below, fwiw.

>Index: tree-vrp.c
>===================================================================
>*** tree-vrp.c	(.../trunk/gcc)	(revision 125658)
>--- tree-vrp.c	(.../branches/pointer_plus/gcc)	(revision 125672)

>*************** extract_range_from_binary_expr (value_ra
>*** 1763,1788 ****
>        || POINTER_TYPE_P (TREE_TYPE (op0))
>        || POINTER_TYPE_P (TREE_TYPE (op1)))
>      {
>!       /* For pointer types, we are really only interested in asserting
>! 	 whether the expression evaluates to non-NULL.  FIXME, we used
>! 	 to gcc_assert (code == PLUS_EXPR || code == MINUS_EXPR), but
>! 	 ivopts is generating expressions with pointer multiplication
>! 	 in them.  */
>!       if (code == PLUS_EXPR)
>  	{
>! 	  if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1))
>  	    set_value_range_to_nonnull (vr, TREE_TYPE (expr));
>  	  else if (range_is_null (&vr0) && range_is_null (&vr1))
>  	    set_value_range_to_null (vr, TREE_TYPE (expr));
>  	  else
>  	    set_value_range_to_varying (vr);
>  	}
>        else
>! 	{
>! 	  /* Subtracting from a pointer, may yield 0, so just drop the
>! 	     resulting range to varying.  */
>! 	  set_value_range_to_varying (vr);
>! 	}
>  
>        return;
>      }
>--- 1772,1801 ----
>        || POINTER_TYPE_P (TREE_TYPE (op0))
>        || POINTER_TYPE_P (TREE_TYPE (op1)))
>      {
>!       if (code == MIN_EXPR || code == MAX_EXPR)
>  	{
>! 	  /* For MIN/MAX expressions with pointers, we only care about
>! 	     nullness, if both are non null, then the result is nonnull.
>! 	     If both are null, then the result is null. Other wise they
>! 	     are varrying.  */

s/Other wise/Otherwise/
s/varrying/varying

>Index: doc/c-tree.texi
>===================================================================
>*** doc/c-tree.texi	(.../trunk/gcc)	(revision 125658)
>--- doc/c-tree.texi	(.../branches/pointer_plus/gcc)	(revision 125672)
>*************** generate these expressions anyhow, if it
>*** 2292,2297 ****
>--- 2293,2304 ----
>  not matter.  The type of the operands and that of the result are
>  always of @code{BOOLEAN_TYPE} or @code{INTEGER_TYPE}.
>  
>+ @itemx POINTER_PLUS_EXPR
>+ This node represents pointer arithmetic.  The first operand is always
>+ a pointer/reference type.  The second operand is always an unsigned
>+ integer type compatiable with sizetype.  This is the only binary

s/compatiable/compatible/

>+ arthemetic operand that can operate on pointer types.

s/arthemetic/arithmetic/

>Index: fold-const.c
>===================================================================
>*** fold-const.c	(.../trunk/gcc)	(revision 125658)
>--- fold-const.c	(.../branches/pointer_plus/gcc)	(revision 125672)
>*************** extract_array_ref (tree expr, tree *base
>*** 6000,6020 ****
>    /* One canonical form is a PLUS_EXPR with the first
>       argument being an ADDR_EXPR with a possible NOP_EXPR
>       attached.  */
>!   if (TREE_CODE (expr) == PLUS_EXPR)
>      {
>        tree op0 = TREE_OPERAND (expr, 0);
>        tree inner_base, dummy1;
>        /* Strip NOP_EXPRs here because the C frontends and/or
>! 	 folders present us (int *)&x.a + 4B possibly.  */
>        STRIP_NOPS (op0);
>        if (extract_array_ref (op0, &inner_base, &dummy1))
>  	{
>  	  *base = inner_base;
>! 	  if (dummy1 == NULL_TREE)
>! 	    *offset = TREE_OPERAND (expr, 1);
>! 	  else
>! 	    *offset = fold_build2 (PLUS_EXPR, TREE_TYPE (expr),
>! 				   dummy1, TREE_OPERAND (expr, 1));
>  	  return true;
>  	}
>      }
>--- 6014,6033 ----
>    /* One canonical form is a PLUS_EXPR with the first
>       argument being an ADDR_EXPR with a possible NOP_EXPR
>       attached.  */
>!   if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
>      {
>        tree op0 = TREE_OPERAND (expr, 0);
>        tree inner_base, dummy1;
>        /* Strip NOP_EXPRs here because the C frontends and/or
>! 	 folders present us (int *)&x.a p+ 4 possibly.  */

Perhaps naming it PTR_PLUS instead of p+ in this file is easier to understand?

>*************** fold_binary (enum tree_code code, tree t
>*** 9066,9072 ****
>--- 9095,9162 ----
>  
>    switch (code)
>      {
>+     case POINTER_PLUS_EXPR:
>+       /* 0 +p index -> (type)index */

here you call it plus ptr
>--- 9263,9268 ----
>*************** fold_binary (enum tree_code code, tree t
>*** 9465,9470 ****
>--- 9539,9569 ----
>        return NULL_TREE;
>  
>      case MINUS_EXPR:
>+       /* Pointer simplifications for subtraction, simple reassiocations. */

What is "reassiocations" ?

>+       if (POINTER_TYPE_P (TREE_TYPE (arg1)) && POINTER_TYPE_P (TREE_TYPE (arg0)))
>+ 	{
>+ 	  /* (PTR0 p+ A) - (PTR1 p+ B) -> (PTR0 - PTR1) + (A - B) */

>Index: testsuite/gcc.dg/max-1.c
>===================================================================
>*** testsuite/gcc.dg/max-1.c	(.../trunk/gcc)	(revision 125658)
>--- testsuite/gcc.dg/max-1.c	(.../branches/pointer_plus/gcc)	(revision 125672)
>*************** void f(long a, long b)
>*** 24,33 ****
>     fff[i] = a;
>  }
>  
>  int main(void)
>  {
>    int i;
>-   long a = 10;
>    f((long)(&a)-1,0);
>    for(i = 0;i<10;i++)
>     if (fff[i]!=10)
>--- 24,36 ----
>     fff[i] = a;
>  }
>  
>+ /* The variable a cannot be a local variable as we get better aliasing
>+    now and decide that the store to a is dead.  The better aliasing comes
>+    from better representation of pointer arthimetic. */

s/arthimetic/arithmetic/

>Index: testsuite/gcc.dg/vect/vect-106.c
>===================================================================
>*** testsuite/gcc.dg/vect/vect-106.c	(.../trunk/gcc)	(revision 125658)
>--- testsuite/gcc.dg/vect/vect-106.c	(.../branches/pointer_plus/gcc)	(revision 125672)
>*************** int main1 () {
>*** 17,25 ****
>  
>    p1 = p; q1 = q;
>  
>!   /* Not vectorizable: because of the redundant cast (caused by ponter
>!      arithmetics), alias analysis fails to distinguish between 
>!      the pointers.  */
>    for (i = 0; i < N; i++)
>      {
>        *(q + i) = a[i];
>--- 17,25 ----
>  
>    p1 = p; q1 = q;
>  
>!   /* Vectorizable, before pointer plus we would get a redundant cast
>!      (caused by ponter arithmetics), alias analysis fails to distinguish

s/ponter/pointer/


>Index: cp/ChangeLog.ptr
>===================================================================
>*** cp/ChangeLog.ptr	(.../trunk/gcc)	(revision 0)
>--- cp/ChangeLog.ptr	(.../branches/pointer_plus/gcc)	(revision 125672)
>***************
>*** 0 ****
>--- 1,60 ----
>+ 2007-05-28  Andrew Pinski  <andrew_pinski@playstation.sony.com>
>+ 
>+ 	* typeck.c (build_binary_op): Add a comment on why creating
>+ 	the tree in pieces while processing templates.
>+ 
>+ 2007-05-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
>+ 
>+ 	* except.c (expand_start_catch_block):  Do a
>+ 	NEGATIVE and then a POINTER_PLUS_EXPR instead
>+ 	of a MINUS_EXPR.
>+ 
>+ 2007-05-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
>+ 
>+ 	* cp-gimplify.c (cxx_omp_clause_apply_fn): Convert
>+ 	PLUS_EXPR on pointer types over to use
>+ 	POINTER_PLUS_EXPR and remove the conversion
>+ 	to the pointer types.
>+ 
>+ 2007-05-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
>+ 
>+ 	* typeck.c (build_unary_op): Remove code that used to
>+ 	handle non lvalue increments/decrements as we now error
>+ 	out all ways.

s/all ways/allways/

>Index: expr.c
>===================================================================
>*** expr.c	(.../trunk/gcc)	(revision 125658)
>--- expr.c	(.../branches/pointer_plus/gcc)	(revision 125672)
>*************** expand_expr_real_1 (tree exp, rtx target
>*** 8036,8042 ****
>--- 8036,8047 ----
>  
>        return op0;
>  
>+     case POINTER_PLUS_EXPR: 
>+       /* Even though the sizetype mode and the pointer's mode can be different
>+          expand is able to handle this correct and get the correct result out 

s/this correct/this correctly/

>+          from the PLUS_EXPR code.  */

I'd say "out of" instead of "out from", perhaps.

>Index: ChangeLog.ptr
>===================================================================
>*** ChangeLog.ptr	(.../trunk/gcc)	(revision 0)
>--- ChangeLog.ptr	(.../branches/pointer_plus/gcc)	(revision 125672)
>***************
>*** 0 ****
>--- 1,498 ----
>+ 2007-06-13  Andrew Pinski  <andrew_pinski@playstation.sony.com>
>+ 
>+ 	* expr.c (expand_expr_real_1 <case POINTER_PLUS_EXPR>): Remove assert
>+ 	for checking the modes of the operands are the same.
>+ 
>+ 2007-06-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
>+ 
>+ 	* config/sparc/sparc.c (sparc_gimplify_va_arg): Use POINTER_PLUS_EXPR
>+ 	instead of PLUS_EXPR when the operand was a pointer.  Don't create a
>+ 	BIT_AND_EXPR for pointer types.
>+ 
>+ 2007-06-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
>+ 
>+ 	* config/mips/mips.c (mips_va_start): Use POINTER_PLUS_EXPR
>+ 	for pointers.
>+ 	(mips_gimplify_va_arg_expr): Likewise.
>+ 	Don't create BIT_AND_EXPR in a pointer type.
>+ 
>+ 2007-06-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
>+ 
>+ 	Merge mainline, revision 125658 
>+ 
>+ 2007-06-11  Andrew Pinski  <andrew_pinski@playstation.sony.com>
>+ 
>+ 	Merge mainline, revision 125611
>+ 
>+ 2007-06-07  Andrew Pinski  <andrew_pinski@playstation.sony.com>
>+ 
>+ 	* matrix-reorg.c (collect_data_for_malloc_call): Stmt
>+ 	will now only be either INDIRECT_REF and POINTER_PLUS_EXPR.
>+ 	Offset only holds something for PLUS_EXPR.
>+ 	(ssa_accessed_in_tree): Handle POINTER_PLUS_EXPR just as
>+ 	a PLUS_EXPR.
>+ 	(analyze_transpose): POINTER_PLUS_EXPR will only show up now
>+ 	and not PLUS_EXPR.
>+ 	(analyze_accesses_for_modify_stmt): Likewise.
>+ 	Remove comment about the type being integral type as it is
>+ 	wrong now.
>+ 	(analyze_matrix_accesses): Handle POINTER_PLUS_EXPR as
>+ 	PLUS_EXPR.
>+ 	(transform_access_sites): POINTER_PLUS_EXPR will only show up now
>+ 	and not PLUS_EXPR.
>+ 	Correct the type which the artimentic is done in (is now

s/artimentic/arithmetic/

>Index: c-typeck.c
>===================================================================
>*** c-typeck.c	(.../trunk/gcc)	(revision 125658)
>--- c-typeck.c	(.../branches/pointer_plus/gcc)	(revision 125672)
>*************** build_unary_op (enum tree_code code, tre
>*** 2959,2969 ****
>  	      }
>  
>  	    inc = c_size_in_bytes (TREE_TYPE (result_type));
>  	  }
>  	else
>! 	  inc = integer_one_node;
>! 
>! 	inc = convert (argtype, inc);
>  
>  	/* Complain about anything else that is not a true lvalue.  */
>  	if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
>--- 2959,2971 ----
>  	      }
>  
>  	    inc = c_size_in_bytes (TREE_TYPE (result_type));
>+ 	    inc = convert (sizetype, inc);
>  	  }
>  	else
>! 	  {
>! 	    inc = integer_one_node;
>! 	    inc = convert (argtype, inc);

Why not inc = convert (argtype, integer_one_node) ?

>Index: tree-ssa-forwprop.c
>===================================================================
>*** tree-ssa-forwprop.c	(.../trunk/gcc)	(revision 125658)
>--- tree-ssa-forwprop.c	(.../branches/pointer_plus/gcc)	(revision 125672)
>*************** forward_propagate_addr_expr_1 (tree name
>*** 644,653 ****
>  
>    /* If the use of the ADDR_EXPR must be a PLUS_EXPR, or else there
>       is nothing to do. */
>!   if (TREE_CODE (rhs) != PLUS_EXPR)
>      return false;
>  
>!   /* Try to optimize &x[0] + C where C is a multiple of the size
>       of the elements in X into &x[C/element size].  */
>    if (TREE_OPERAND (rhs, 0) == name
>        && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
>--- 635,644 ----
>  
>    /* If the use of the ADDR_EXPR must be a PLUS_EXPR, or else there

Perhaps also adjust the comment here.

>       is nothing to do. */
>!   if (TREE_CODE (rhs) != POINTER_PLUS_EXPR)
>      return false;
>  
>!   /* Try to optimize &x[0] p+ C where C is a multiple of the size
>       of the elements in X into &x[C/element size].  */
>    if (TREE_OPERAND (rhs, 0) == name
>        && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)

>*************** phiprop_insert_phi (basic_block bb, tree
>*** 1174,1180 ****
>  	}
>  
>        if (TREE_CODE (old_arg) == SSA_NAME)
>! 	/* Reuse a formerly created dereference.  */
>  	new_var = phivn[SSA_NAME_VERSION (old_arg)].value;
>        else
>  	{
>--- 1149,1155 ----
>  	}
>  
>        if (TREE_CODE (old_arg) == SSA_NAME)
>! 	/* Reuse a formely created dereference.  */
>  	new_var = phivn[SSA_NAME_VERSION (old_arg)].value;
>        else
>  	{

Drop this hunk. It introduces a typo (s/formely/formerly/).

>Index: c-common.c
>===================================================================
>*** c-common.c	(.../trunk/gcc)	(revision 125658)
>--- c-common.c	(.../branches/pointer_plus/gcc)	(revision 125672)
>*************** pointer_int_sum (enum tree_code resultco
>*** 2700,2711 ****
>       Do this multiplication as signed, then convert to the appropriate
>       pointer type (actually unsigned integral).  */
>  
>!   intop = convert (result_type,
>! 		   build_binary_op (MULT_EXPR, intop,
>! 				    convert (TREE_TYPE (intop), size_exp), 1));
>  
>    /* Create the sum or difference.  */
>!   ret = fold_build2 (resultcode, result_type, ptrop, intop);
>  
>    fold_undefer_and_ignore_overflow_warnings ();
>  
>--- 2700,2716 ----
>       Do this multiplication as signed, then convert to the appropriate
>       pointer type (actually unsigned integral).  */
>  
>!   intop = build_binary_op (MULT_EXPR, intop,
>! 			   convert (TREE_TYPE (intop), size_exp), 1);
>! 
>!   /* FIXME: maybe add a POINTER_MINUS_EXPR ???  */

Isn't a POINTER_MINUS_EXPR just a negative PTR_PLUS_EXPR? Just curious..

>!   if (resultcode == MINUS_EXPR)
>!     intop = fold_build1 (NEGATE_EXPR, TREE_TYPE (intop), intop);
>! 
>!   intop = convert (sizetype, intop);
>  
>    /* Create the sum or difference.  */
>!   ret = fold_build2 (POINTER_PLUS_EXPR, result_type, ptrop, intop);
>  
>    fold_undefer_and_ignore_overflow_warnings ();

cheers,



More information about the Gcc-patches mailing list