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][mem-ref2] Kill maybe_fold_offset_to_reference


This removes maybe_fold_offset_to_reference and all the fixups
for complications it causes.  With MEM_REF it is no longer of
use to try to represent constant offsets as COMPONENT_REFs
as they can be put into the MEM_REF offset operand.  Removing
this code makes improving and generalizing the ARRAY_REF
cases easier which are still useful because of the C frontend
behavior lowering array accesses.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to
the branch.

Richard.

2010-06-19  Richard Guenther  <rguenther@suse.de>

	* gimple.h (maybe_fold_offset_to_reference): Remove.
	* gimple-fold.c (maybe_fold_offset_to_component_ref): Remove.
	(maybe_fold_offset_to_reference): Simplify.
	(maybe_fold_offset_to_address): Likewise.
	(maybe_fold_stmt_indirect): Adjust comments.
	(maybe_fold_stmt_addition): Simplify.
	* tree-sra.c (build_ref_for_offset, build_ref_for_offset_1):
	Adjust comments.

Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h	(revision 161025)
--- gcc/gimple.h	(working copy)
*************** void gimplify_and_update_call_from_tree
*** 4805,4811 ****
  tree gimple_fold_builtin (gimple);
  bool fold_stmt (gimple_stmt_iterator *);
  bool fold_stmt_inplace (gimple);
- tree maybe_fold_offset_to_reference (location_t, tree, tree, tree);
  tree maybe_fold_offset_to_address (location_t, tree, tree, tree);
  tree maybe_fold_stmt_addition (location_t, tree, tree, tree);
  tree get_symbol_constant_value (tree);
--- 4805,4810 ----
Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c	(revision 161025)
--- gcc/gimple-fold.c	(working copy)
*************** maybe_fold_offset_to_array_ref (location
*** 256,379 ****
  }
  
  
- /* Attempt to fold *(S+O) to S.X.
-    BASE is a record type.  OFFSET is a byte displacement.  ORIG_TYPE
-    is the desired result type.
- 
-    LOC is the location of the original expression.  */
- 
- static tree
- maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
- 				    tree base, tree offset, tree orig_type)
- {
-   tree f, t, field_type, tail_array_field, field_offset;
-   tree ret;
-   tree new_base;
- 
-   if (TREE_CODE (record_type) != RECORD_TYPE
-       && TREE_CODE (record_type) != UNION_TYPE
-       && TREE_CODE (record_type) != QUAL_UNION_TYPE)
-     return NULL_TREE;
- 
-   /* Short-circuit silly cases.  */
-   if (useless_type_conversion_p (record_type, orig_type))
-     return NULL_TREE;
- 
-   tail_array_field = NULL_TREE;
-   for (f = TYPE_FIELDS (record_type); f ; f = TREE_CHAIN (f))
-     {
-       int cmp;
- 
-       if (TREE_CODE (f) != FIELD_DECL)
- 	continue;
-       if (DECL_BIT_FIELD (f))
- 	continue;
- 
-       if (!DECL_FIELD_OFFSET (f))
- 	continue;
-       field_offset = byte_position (f);
-       if (TREE_CODE (field_offset) != INTEGER_CST)
- 	continue;
- 
-       /* ??? Java creates "interesting" fields for representing base classes.
- 	 They have no name, and have no context.  With no context, we get into
- 	 trouble with nonoverlapping_component_refs_p.  Skip them.  */
-       if (!DECL_FIELD_CONTEXT (f))
- 	continue;
- 
-       /* The previous array field isn't at the end.  */
-       tail_array_field = NULL_TREE;
- 
-       /* Check to see if this offset overlaps with the field.  */
-       cmp = tree_int_cst_compare (field_offset, offset);
-       if (cmp > 0)
- 	continue;
- 
-       field_type = TREE_TYPE (f);
- 
-       /* Here we exactly match the offset being checked.  If the types match,
- 	 then we can return that field.  */
-       if (cmp == 0
- 	  && useless_type_conversion_p (orig_type, field_type))
- 	{
- 	  t = fold_build3 (COMPONENT_REF, field_type, base, f, NULL_TREE);
- 	  return t;
- 	}
- 
-       /* Don't care about offsets into the middle of scalars.  */
-       if (!AGGREGATE_TYPE_P (field_type))
- 	continue;
- 
-       /* Check for array at the end of the struct.  This is often
- 	 used as for flexible array members.  We should be able to
- 	 turn this into an array access anyway.  */
-       if (TREE_CODE (field_type) == ARRAY_TYPE)
- 	tail_array_field = f;
- 
-       /* Check the end of the field against the offset.  */
-       if (!DECL_SIZE_UNIT (f)
- 	  || TREE_CODE (DECL_SIZE_UNIT (f)) != INTEGER_CST)
- 	continue;
-       t = int_const_binop (MINUS_EXPR, offset, field_offset, 1);
-       if (!tree_int_cst_lt (t, DECL_SIZE_UNIT (f)))
- 	continue;
- 
-       /* If we matched, then set offset to the displacement into
- 	 this field.  */
-       new_base = fold_build3 (COMPONENT_REF, field_type, base, f, NULL_TREE);
-       SET_EXPR_LOCATION (new_base, loc);
- 
-       /* Recurse to possibly find the match.  */
-       ret = maybe_fold_offset_to_array_ref (loc, new_base, t, orig_type,
- 					    f == TYPE_FIELDS (record_type));
-       if (ret)
- 	return ret;
-       ret = maybe_fold_offset_to_component_ref (loc, field_type, new_base, t,
- 						orig_type);
-       if (ret)
- 	return ret;
-     }
- 
-   if (!tail_array_field)
-     return NULL_TREE;
- 
-   f = tail_array_field;
-   field_type = TREE_TYPE (f);
-   offset = int_const_binop (MINUS_EXPR, offset, byte_position (f), 1);
- 
-   /* If we get here, we've got an aggregate field, and a possibly
-      nonzero offset into them.  Recurse and hope for a valid match.  */
-   base = fold_build3 (COMPONENT_REF, field_type, base, f, NULL_TREE);
-   SET_EXPR_LOCATION (base, loc);
- 
-   t = maybe_fold_offset_to_array_ref (loc, base, offset, orig_type,
- 				      f == TYPE_FIELDS (record_type));
-   if (t)
-     return t;
-   return maybe_fold_offset_to_component_ref (loc, field_type, base, offset,
- 					     orig_type);
- }
- 
  /* Attempt to express (ORIG_TYPE)BASE+OFFSET as BASE->field_of_orig_type
     or BASE[index] or by combination of those.
  
--- 256,261 ----
*************** maybe_fold_offset_to_component_ref (loca
*** 382,432 ****
     Before attempting the conversion strip off existing ADDR_EXPRs and
     handled component refs.  */
  
! tree
  maybe_fold_offset_to_reference (location_t loc, tree base, tree offset,
  				tree orig_type)
  {
-   tree ret;
-   tree type;
- 
    STRIP_NOPS (base);
    if (TREE_CODE (base) != ADDR_EXPR)
      return NULL_TREE;
  
    base = TREE_OPERAND (base, 0);
- 
-   /* Handle case where existing COMPONENT_REF pick e.g. wrong field of union,
-      so it needs to be removed and new COMPONENT_REF constructed.
-      The wrong COMPONENT_REF are often constructed by folding the
-      (type *)&object within the expression (type *)&object+offset  */
-   if (handled_component_p (base))
-     {
-       HOST_WIDE_INT sub_offset, size, maxsize;
-       tree newbase;
-       newbase = get_ref_base_and_extent (base, &sub_offset,
- 					 &size, &maxsize);
-       gcc_assert (newbase);
-       if (size == maxsize
- 	  && size != -1
- 	  && !(sub_offset & (BITS_PER_UNIT - 1)))
- 	{
- 	  base = newbase;
- 	  if (sub_offset)
- 	    offset = int_const_binop (PLUS_EXPR, offset,
- 				      build_int_cst (TREE_TYPE (offset),
- 						     sub_offset / BITS_PER_UNIT), 1);
- 	}
-     }
    if (useless_type_conversion_p (orig_type, TREE_TYPE (base))
        && integer_zerop (offset))
      return base;
-   type = TREE_TYPE (base);
  
!   ret = maybe_fold_offset_to_component_ref (loc, type, base, offset, orig_type);
!   if (!ret)
!     ret = maybe_fold_offset_to_array_ref (loc, base, offset, orig_type, true);
! 
!   return ret;
  }
  
  /* Attempt to express (ORIG_TYPE)&BASE+OFFSET as &BASE->field_of_orig_type
--- 264,283 ----
     Before attempting the conversion strip off existing ADDR_EXPRs and
     handled component refs.  */
  
! static tree
  maybe_fold_offset_to_reference (location_t loc, tree base, tree offset,
  				tree orig_type)
  {
    STRIP_NOPS (base);
    if (TREE_CODE (base) != ADDR_EXPR)
      return NULL_TREE;
  
    base = TREE_OPERAND (base, 0);
    if (useless_type_conversion_p (orig_type, TREE_TYPE (base))
        && integer_zerop (offset))
      return base;
  
!   return maybe_fold_offset_to_array_ref (loc, base, offset, orig_type, true);
  }
  
  /* Attempt to express (ORIG_TYPE)&BASE+OFFSET as &BASE->field_of_orig_type
*************** maybe_fold_offset_to_address (location_t
*** 449,485 ****
  				      TREE_TYPE (orig_type));
    if (t != NULL_TREE)
      {
-       tree orig = addr;
        tree ptr_type;
- 
-       /* For __builtin_object_size to function correctly we need to
-          make sure not to fold address arithmetic so that we change
- 	 reference from one array to another.  This would happen for
- 	 example for
- 
- 	   struct X { char s1[10]; char s2[10] } s;
- 	   char *foo (void) { return &s.s2[-4]; }
- 
- 	 where we need to avoid generating &s.s1[6].  As the C and
- 	 C++ frontends create different initial trees
- 	 (char *) &s.s1 + -4  vs.  &s.s1[-4]  we have to do some
- 	 sophisticated comparisons here.  Note that checking for the
- 	 condition after the fact is easier than trying to avoid doing
- 	 the folding.  */
-       STRIP_NOPS (orig);
-       if (TREE_CODE (orig) == ADDR_EXPR)
- 	orig = TREE_OPERAND (orig, 0);
-       if ((TREE_CODE (orig) == ARRAY_REF
- 	   || (TREE_CODE (orig) == COMPONENT_REF
- 	       && TREE_CODE (TREE_TYPE (TREE_OPERAND (orig, 1))) == ARRAY_TYPE))
- 	  && (TREE_CODE (t) == ARRAY_REF
- 	      || TREE_CODE (t) == COMPONENT_REF)
- 	  && !operand_equal_p (TREE_CODE (orig) == ARRAY_REF
- 			       ? TREE_OPERAND (orig, 0) : orig,
- 			       TREE_CODE (t) == ARRAY_REF
- 			       ? TREE_OPERAND (t, 0) : t, 0))
- 	return NULL_TREE;
- 
        ptr_type = build_pointer_type (TREE_TYPE (t));
        if (!useless_type_conversion_p (orig_type, ptr_type))
  	return NULL_TREE;
--- 300,306 ----
*************** maybe_fold_stmt_indirect (tree expr, tre
*** 541,547 ****
        if (integer_zerop (offset))
  	return base;
  
!       /* Try folding *(&B+O) to B.X.  */
        t = maybe_fold_offset_to_reference (loc, base_addr, offset,
  					  TREE_TYPE (expr));
        if (t)
--- 362,368 ----
        if (integer_zerop (offset))
  	return base;
  
!       /* Try folding *(&B+O) to B[X].  */
        t = maybe_fold_offset_to_reference (loc, base_addr, offset,
  					  TREE_TYPE (expr));
        if (t)
*************** maybe_fold_stmt_indirect (tree expr, tre
*** 578,584 ****
  	  return integer_zero_node;
  	}
  
!       /* Try folding *(B+O) to B->X.  Still an improvement.  */
        if (POINTER_TYPE_P (TREE_TYPE (base)))
  	{
            t = maybe_fold_offset_to_reference (loc, base, offset,
--- 399,405 ----
  	  return integer_zero_node;
  	}
  
!       /* Try folding *(B+O) to (*B)[X].  Still an improvement.  */
        if (POINTER_TYPE_P (TREE_TYPE (base)))
  	{
            t = maybe_fold_offset_to_reference (loc, base, offset,
*************** maybe_fold_stmt_addition (location_t loc
*** 716,724 ****
  
    /* At which point we can try some of the same things as for indirects.  */
    t = maybe_fold_offset_to_array_ref (loc, op0, op1, ptd_type, true);
-   if (!t)
-     t = maybe_fold_offset_to_component_ref (loc, TREE_TYPE (op0), op0, op1,
- 					    ptd_type);
    if (t)
      {
        t = build1 (ADDR_EXPR, res_type, t);
--- 537,542 ----
Index: gcc/tree-sra.c
===================================================================
*** gcc/tree-sra.c	(revision 161025)
--- gcc/tree-sra.c	(working copy)
*************** make_fancy_name (tree expr)
*** 1319,1325 ****
    return XOBFINISH (&name_obstack, char *);
  }
  
! /* Helper function for build_ref_for_offset.  */
  
  static bool
  build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
--- 1319,1329 ----
    return XOBFINISH (&name_obstack, char *);
  }
  
! /* Helper function for build_ref_for_offset.
! 
!    FIXME: Eventually this should be rewritten to either re-use the
!    original access expression unshared (which is good for alias
!    analysis) or to build a MEM_REF expression.  */
  
  static bool
  build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
*************** build_ref_for_offset_1 (tree *res, tree
*** 1417,1428 ****
     type TYPE at the given OFFSET of the type EXP_TYPE.  If EXPR is NULL, the
     function only determines whether it can build such a reference without
     actually doing it, otherwise, the tree it points to is unshared first and
!    then used as a base for furhter sub-references.
! 
!    FIXME: Eventually this should be replaced with
!    maybe_fold_offset_to_reference() from tree-ssa-ccp.c but that requires a
!    minor rewrite of fold_stmt.
!  */
  
  bool
  build_ref_for_offset (tree *expr, tree type, HOST_WIDE_INT offset,
--- 1421,1427 ----
     type TYPE at the given OFFSET of the type EXP_TYPE.  If EXPR is NULL, the
     function only determines whether it can build such a reference without
     actually doing it, otherwise, the tree it points to is unshared first and
!    then used as a base for furhter sub-references.  */
  
  bool
  build_ref_for_offset (tree *expr, tree type, HOST_WIDE_INT offset,


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