Pointer Plus Patch

Paolo Bonzini bonzini@gnu.org
Wed Jun 13 10:28:00 GMT 2007


> +   /* Convert the two values into the same type, this is needed because
> +      sizetype causes sign extension even for unsigned types.  */

comma -> period

> ! 	     are varrying.  */

varying

> !   type1 = type;
> !   if (POINTER_TYPE_P (type))
> !     type1 = sizetype;

Quite a common idiom.  More on this later.

> + 
> +     case POINTER_PLUS_EXPR:
> +       return "p+";

Maybe we can print it as "+" since there's no ambiguity based on the types.

> ! 		build1 (NEGATE_EXPR, sizetype, TYPE_SIZE_UNIT (TREE_TYPE (obj))));

negate_expr (TYPE_SIZE_UNIT (TREE_TYPE (obj)))

> ! 	  /* Create (dst p+ strlen (dst)).  */
> ! 	  newdst = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
>   
>   	  newdst = builtin_save_expr (newdst);

I'd move the blank line above the new comment.

> + 	  low = fold_build1 (NEGATE_EXPR, sizetype, low);

negate_expr

> !       diff = fold_binary (MINUS_EXPR, ssizetype, ta1, ta);
> !       if (!diff || !integer_onep (diff))
> !         return NULL_TREE;
> !     }
> !   else
> !     {
> !       diff = fold_binary (MINUS_EXPR, typea, a1, a);
> !       if (!diff || !integer_onep (diff))
> !         return NULL_TREE;
> !     }



The second if is shared among the two branches.

> +       /* INT +p INT -> (PTR)(INT + INT), this happens because of stripping types. */

p+ and turn comma into period.

> + /* 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. */
> + long a = 10;

Just say "This variable is global to avoid that stores to it be 
optimized away".

Actually, I don't understand this change.  It seems to me that the 
compiler is wrong in optimizing away the store to a, unless this is because

   f((long)(&a)-1,0);

creates a pointer outside the object "a"?  If so, you should modify the 
test to use (long)(&a)+1 and correspondingly *((long *)(a-1).

> !   /* Vectorizable, before pointer plus we would get a redundant cast
> !      (caused by ponter arithmetics), alias analysis fails to distinguish
> !      between the pointers.  */

Who cares.  /* Vectorizable.  */ and that's it.

> !       /* Since the middle-end checks the type when doing a build2, we
> ! 	 need to build the tree in pieces. 

Not so disgusting, but it would be nicer if you built a 
non-type-checking code (e.g. MIN_EXPR) and replaced the code, instead of 
replacing operand 0.

> !       cookie_ptr = build1 (NEGATE_EXPR, sizetype, size_in_bytes (sizetype));

negate_expr.

> !       if (code == MINUS_EXPR)
> ! 	offset = build1 (NEGATE_EXPR, sizetype, offset);

Likewise.

> !       exp = build2 (POINTER_PLUS_EXPR, TREE_TYPE (exp), exp,
> ! 		    build1 (NEGATE_EXPR, sizetype,
> ! 			    TYPE_SIZE_UNIT (TREE_TYPE (exp))));

Likewise.

> !       offset = fold_convert (sizetype,
> ! 			     int_const_binop (PLUS_EXPR, offset, offset2, 1));

size_binop?  Actually, since you are at it you could try to simplify the 
code because the last parameter to maybe_fold_stmt_indirect (i.e. 
offset) is always integer_zero_node.

> !       /* Pointer adition is done solely using POINTER_PLUS_EXPR.  */

addition

> ! 				    build_int_cst (sizetype, 2000))) + 1;

size_int (there are several other cases in builtins.c).

> +     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 
> +          from the PLUS_EXPR code.  */

The comment is useless, the code seems pretty obvious even without it 
(it's not to you because you know the history of the code very well).

> ! 	      = convert (sizetype,
>   			 size_diffop (size_zero_node, gnu_pos));

Use fold_convert instead.

>   	      gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);

Well, I'd use it here too but that's your call.

> ! 	  return build_binary_op (POINTER_PLUS_EXPR, type, expr,
> ! 				  fold (convert (sizetype, byte_diff)));
>   	}

Just use fold_convert here too, as byte_diff is returned from 
size_diffop here too.

> +       /* FALL THROUGH */

lowercase.

>   	    inc = c_size_in_bytes (TREE_TYPE (result_type));
> + 	    inc = convert (sizetype, inc);

Return value of c_size_in_bytes should already be a sizetype.  Use 
fold_convert if this is not the case.

> ! 	    inc = integer_one_node;
> ! 	    inc = convert (argtype, inc);

I wonder if we should use build_int_cst here too, since convert could 
cause overflow.  Testcase:

   struct x {
     signed x:1;
   };

   void f(struct x *y)
   {
     y->x++;
   }

> +       if (arith_code == MINUS_EXPR)
> + 	rhs = fold_build1 (NEGATE_EXPR, TREE_TYPE (rhs), rhs);

Use negate_expr.

> !           && TREE_ADDRESSABLE (decl)
> ! 		    /* XXX: not sufficient: return-by-value structs! */

Irrelevant change, or move the comment together with the previous one. 
There are other whitespace changes in tree-mudflap.c.

>           ofs = convert (bitsizetype, TREE_OPERAND (t, 2));

Please turn this into fold_convert since you are at it.

>           addr = convert (ptr_type_node, addr);

Likewise.

>     /* If the use of the ADDR_EXPR must be a PLUS_EXPR, or else there
>        is nothing to do. */
> !   if (TREE_CODE (rhs) != POINTER_PLUS_EXPR)
>       return false;

If you can, please fix the English in this comment.

> ! 	/* Reuse a formely created dereference.  */

This hunk just introduces a spelling mistake. :-)

> !       if (POINTER_TYPE_P (TREE_TYPE (init_expr)))
> ! 	ni = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (init_expr), 
> ! 			  init_expr, 
> ! 			  fold_convert (sizetype, 
> ! 					fold_build2 (MULT_EXPR, TREE_TYPE (niters),
> ! 						     niters, step_expr)));
> !       else
> ! 	ni = fold_build2 (PLUS_EXPR, TREE_TYPE (init_expr),
> ! 			  fold_build2 (MULT_EXPR, TREE_TYPE (init_expr),
> ! 				       fold_convert (TREE_TYPE (init_expr),
> ! 						     niters),
> ! 				       step_expr),
> ! 			  init_expr);
> ! 
> ! 

I think I had already commented before that this is best placed in a 
separate function.  This function would also include the "common idiom" 
I pointed out above.

> !   /* FIXME: maybe add a POINTER_MINUS_EXPR ???  */
> !   if (resultcode == MINUS_EXPR)
> !     intop = fold_build1 (NEGATE_EXPR, TREE_TYPE (intop), intop);

negate_expr.

I didn't look at the config/ changes.

Paolo



More information about the Gcc-patches mailing list