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][1/2] More cleanups after SFT code removal


This patch moves code to private space inside tree-ssa-structalias.c
since it is now the only user of that and simplifies
push_fields_onto_fieldstack as we now only need to deal with fields
that PTA uses (in particular I removed the field creation for anything
but RECORD_TYPE).  It also removes some now unused fields from
temporary data structures.

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

Richard.

2008-05-08  Richard Guenther  <rguenther@suse.de>

	* tree-flow-inline.h (var_can_have_subvars): Move ...
	* tree-ssa-structalias.c (var_can_have_subvars): ... here.
	* tree-flow.h (var_can_have_subvars): Remove.
	(push_fields_onto_fieldstack): Remove.
	(sort_fieldstack): Likewise.
	(struct fieldoff): Move ...
	* tree-ssa-structalias.c (struct fieldoff): ... here.  Remove
	alias_set and base_for_components fields.
	(sort_fieldstack): Make static.
	(push_fields_onto_fieldstack): Likewise.  Remove code that
	handles anything but RECORD_TYPEs.  Remove alias_set and
	base_for_components handling.
	(create_variable_info_for): Adjust.

Index: gcc/tree-flow-inline.h
===================================================================
*** gcc/tree-flow-inline.h	(revision 135077)
--- gcc/tree-flow-inline.h	(working copy)
*************** ref_contains_array_ref (const_tree ref)
*** 1581,1616 ****
    return false;
  }
  
- 
- /* Return true if V is a tree that we can have subvars for.
-    Normally, this is any aggregate type.  Also complex
-    types which are not gimple registers can have subvars.  */
- 
- static inline bool
- var_can_have_subvars (const_tree v)
- {
-   /* Volatile variables should never have subvars.  */
-   if (TREE_THIS_VOLATILE (v))
-     return false;
- 
-   /* Non decls or memory tags can never have subvars.  */
-   if (!DECL_P (v) || MTAG_P (v))
-     return false;
- 
-   /* Aggregates can have subvars.  */
-   if (AGGREGATE_TYPE_P (TREE_TYPE (v)))
-     return true;
- 
-   /* Complex types variables which are not also a gimple register can
-     have subvars. */
-   if (TREE_CODE (TREE_TYPE (v)) == COMPLEX_TYPE
-       && !DECL_GIMPLE_REG_P (v))
-     return true;
- 
-   return false;
- }
- 
- 
  /* Return true, if the two ranges [POS1, SIZE1] and [POS2, SIZE2]
     overlap.  SIZE1 and/or SIZE2 can be (unsigned)-1 in which case the
     range is open-ended.  Otherwise return false.  */
--- 1581,1586 ----
Index: gcc/tree-flow.h
===================================================================
*** gcc/tree-flow.h	(revision 135077)
--- gcc/tree-flow.h	(working copy)
*************** static inline bool ref_contains_array_re
*** 854,860 ****
  static inline bool array_ref_contains_indirect_ref (const_tree);
  extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,
  				     HOST_WIDE_INT *, HOST_WIDE_INT *);
- static inline bool var_can_have_subvars (const_tree);
  extern tree create_tag_raw (enum tree_code, tree, const char *);
  extern void delete_mem_ref_stats (struct function *);
  extern void dump_mem_ref_stats (FILE *);
--- 854,859 ----
*************** rtx addr_for_mem_ref (struct mem_address
*** 1169,1207 ****
  void get_address_description (tree, struct mem_address *);
  tree maybe_fold_tmr (tree);
  
- /* This structure is used during pushing fields onto the fieldstack
-    to track the offset of the field, since bitpos_of_field gives it
-    relative to its immediate containing type, and we want it relative
-    to the ultimate containing object.  */
- 
- struct fieldoff
- {
-   /* Type of the field.  */
-   tree type;
- 
-   /* Size, in bits, of the field.  */
-   tree size;
- 
-   /* Field.  */
-   tree decl;
- 
-   /* Offset from the base of the base containing object to this field.  */
-   HOST_WIDE_INT offset;  
- 
-   /* Alias set for the field.  */
-   alias_set_type alias_set;
- 
-   /* True, if this offset can be a base for further component accesses.  */
-   unsigned base_for_components : 1;
- };
- typedef struct fieldoff fieldoff_s;
- 
- DEF_VEC_O(fieldoff_s);
- DEF_VEC_ALLOC_O(fieldoff_s,heap);
- int push_fields_onto_fieldstack (tree, VEC(fieldoff_s,heap) **,
- 				 HOST_WIDE_INT, bool *, tree);
- void sort_fieldstack (VEC(fieldoff_s,heap) *);
- 
  void init_alias_heapvars (void);
  void delete_alias_heapvars (void);
  unsigned int execute_fixup_cfg (void);
--- 1168,1173 ----
Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c	(revision 135077)
--- gcc/tree-ssa-structalias.c	(working copy)
*************** insert_into_field_list_sorted (varinfo_t
*** 3994,3999 ****
--- 3994,4023 ----
      }
  }
  
+ /* This structure is used during pushing fields onto the fieldstack
+    to track the offset of the field, since bitpos_of_field gives it
+    relative to its immediate containing type, and we want it relative
+    to the ultimate containing object.  */
+ 
+ struct fieldoff
+ {
+   /* Type of the field.  */
+   tree type;
+ 
+   /* Size, in bits, of the field.  */
+   tree size;
+ 
+   /* Field.  */
+   tree decl;
+ 
+   /* Offset from the base of the base containing object to this field.  */
+   HOST_WIDE_INT offset;  
+ };
+ typedef struct fieldoff fieldoff_s;
+ 
+ DEF_VEC_O(fieldoff_s);
+ DEF_VEC_ALLOC_O(fieldoff_s,heap);
+ 
  /* qsort comparison function for two fieldoff's PA and PB */
  
  static int
*************** fieldoff_compare (const void *pa, const 
*** 4012,4018 ****
  }
  
  /* Sort a fieldstack according to the field offset and sizes.  */
! void
  sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
  {
    qsort (VEC_address (fieldoff_s, fieldstack),
--- 4036,4042 ----
  }
  
  /* Sort a fieldstack according to the field offset and sizes.  */
! static void
  sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
  {
    qsort (VEC_address (fieldoff_s, fieldstack),
*************** sort_fieldstack (VEC(fieldoff_s,heap) *f
*** 4021,4026 ****
--- 4045,4072 ----
  	 fieldoff_compare);
  }
  
+ /* Return true if V is a tree that we can have subvars for.
+    Normally, this is any aggregate type.  Also complex
+    types which are not gimple registers can have subvars.  */
+ 
+ static inline bool
+ var_can_have_subvars (const_tree v)
+ {
+   /* Volatile variables should never have subvars.  */
+   if (TREE_THIS_VOLATILE (v))
+     return false;
+ 
+   /* Non decls or memory tags can never have subvars.  */
+   if (!DECL_P (v) || MTAG_P (v))
+     return false;
+ 
+   /* Aggregates without overlapping fields can have subvars.  */
+   if (TREE_CODE (TREE_TYPE (v)) == RECORD_TYPE)
+     return true;
+ 
+   return false;
+ }
+ 
  /* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
     the fields of TYPE onto fieldstack, recording their offsets along
     the way.
*************** sort_fieldstack (VEC(fieldoff_s,heap) *f
*** 4030,4201 ****
     Returns the number of fields pushed.
  
     HAS_UNION is set to true if we find a union type as a field of
!    TYPE.
  
!    ADDRESSABLE_TYPE is the type of the outermost object that could
!    have its address taken.  */
! 
! int
  push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
! 			     HOST_WIDE_INT offset, bool *has_union,
! 			     tree addressable_type)
  {
    tree field;
    int count = 0;
!   unsigned int first_element = VEC_length (fieldoff_s, *fieldstack);
  
    /* If the vector of fields is growing too big, bail out early.
       Callers check for VEC_length <= MAX_FIELDS_FOR_FIELD_SENSITIVE, make
       sure this fails.  */
!   if (first_element > MAX_FIELDS_FOR_FIELD_SENSITIVE)
      return 0;
  
!   if (TREE_CODE (type) == COMPLEX_TYPE)
!     {
!       fieldoff_s *real_part, *img_part;
!       real_part = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
!       real_part->type = TREE_TYPE (type);
!       real_part->size = TYPE_SIZE (TREE_TYPE (type));
!       real_part->offset = offset;
!       real_part->decl = NULL_TREE;
!       real_part->alias_set = -1;
!       real_part->base_for_components = false;
! 
!       img_part = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
!       img_part->type = TREE_TYPE (type);
!       img_part->size = TYPE_SIZE (TREE_TYPE (type));
!       img_part->offset = offset + TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (type)));
!       img_part->decl = NULL_TREE;
!       img_part->alias_set = -1;
!       img_part->base_for_components = false;
! 
!       count = 2;
!     }
! 
!   else if (TREE_CODE (type) == ARRAY_TYPE)
!     {
!       tree sz = TYPE_SIZE (type);
!       tree elsz = TYPE_SIZE (TREE_TYPE (type));
!       HOST_WIDE_INT nr;
!       int i;
! 
!       if (! sz
! 	  || ! host_integerp (sz, 1)
! 	  || TREE_INT_CST_LOW (sz) == 0
! 	  || ! elsz
! 	  || ! host_integerp (elsz, 1)
! 	  || TREE_INT_CST_LOW (elsz) == 0)
! 	return 0;
! 
!       nr = TREE_INT_CST_LOW (sz) / TREE_INT_CST_LOW (elsz);
!       if (nr > SALIAS_MAX_ARRAY_ELEMENTS)
! 	return 0;
! 
!       for (i = 0; i < nr; ++i)
! 	{
! 	  bool push = false;
! 	  int pushed = 0;
! 
! 	  if (has_union
! 	      && (TREE_CODE (TREE_TYPE (type)) == QUAL_UNION_TYPE
! 		  || TREE_CODE (TREE_TYPE (type)) == UNION_TYPE))
! 	    *has_union = true;
! 
! 	  if (!AGGREGATE_TYPE_P (TREE_TYPE (type))) /* var_can_have_subvars */
! 	    push = true;
! 	  else if (!(pushed = push_fields_onto_fieldstack
! 		     (TREE_TYPE (type),
! 		      fieldstack,
! 		      offset + i * TREE_INT_CST_LOW (elsz),
! 		      has_union,
! 		      (TYPE_NONALIASED_COMPONENT (type)
! 		       ? addressable_type
! 		       : TREE_TYPE (type)))))
! 	    /* Empty structures may have actual size, like in C++. So
! 	       see if we didn't push any subfields and the size is
! 	       nonzero, push the field onto the stack */
! 	    push = true;
! 
! 	  if (push)
! 	    {
! 	      fieldoff_s *pair;
  
! 	      pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
! 	      pair->type = TREE_TYPE (type);
! 	      pair->size = elsz;
! 	      pair->decl = NULL_TREE;
! 	      pair->offset = offset + i * TREE_INT_CST_LOW (elsz);
! 	      if (TYPE_NONALIASED_COMPONENT (type))
! 		pair->alias_set = get_alias_set (addressable_type);
! 	      else
! 		pair->alias_set = -1;
! 	      pair->base_for_components = false;
! 	      count++;
! 	    }
! 	  else
! 	    count += pushed;
! 	}
!     }
! 
!   else
!     {
!       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
! 	if (TREE_CODE (field) == FIELD_DECL)
  	  {
! 	    bool push = false;
! 	    int pushed = 0;
  
! 	    if (has_union
! 	        && (TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
! 		    || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE))
! 	      *has_union = true;
! 
! 	    if (!var_can_have_subvars (field))
! 	      push = true;
! 	    else if (!(pushed = push_fields_onto_fieldstack
! 		       (TREE_TYPE (field),
! 		        fieldstack,
! 		        offset + bitpos_of_field (field),
! 		        has_union,
! 		        (DECL_NONADDRESSABLE_P (field)
! 		         ? addressable_type
! 		         : TREE_TYPE (field))))
! 		     && ((DECL_SIZE (field)
! 			  && !integer_zerop (DECL_SIZE (field)))
! 			 || (!DECL_SIZE (field)
! 			     && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)))
! 	      /* Empty structures may have actual size, like in C++.  So
! 	         see if we didn't push any subfields and the size is
! 	         nonzero, push the field onto the stack.  Trailing flexible
! 		 array members also need a representative to be able to
! 		 treat taking their address in PTA.  */
! 	      push = true;
! 
! 	    if (push)
! 	      {
! 	        fieldoff_s *pair;
! 
! 	        pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
! 	        pair->type = TREE_TYPE (field);
! 	        pair->size = DECL_SIZE (field);
! 	        pair->decl = field;
! 	        pair->offset = offset + bitpos_of_field (field);
! 	        if (DECL_NONADDRESSABLE_P (field))
! 	          pair->alias_set = get_alias_set (addressable_type);
! 	        else
! 	          pair->alias_set = -1;
! 	        pair->base_for_components = false;
! 	        count++;
! 	      }
! 	    else
! 	      count += pushed;
!           }
!     }
! 
!   /* Make sure the first pushed field is marked as eligible for
!      being a base for component references.  */
!   if (count > 0)
!     VEC_index (fieldoff_s, *fieldstack, first_element)->base_for_components = true;
  
    return count;
  }
--- 4076,4138 ----
     Returns the number of fields pushed.
  
     HAS_UNION is set to true if we find a union type as a field of
!    TYPE.  */
  
! static int
  push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
! 			     HOST_WIDE_INT offset, bool *has_union)
  {
    tree field;
    int count = 0;
! 
!   if (TREE_CODE (type) != RECORD_TYPE)
!     return 0;
  
    /* If the vector of fields is growing too big, bail out early.
       Callers check for VEC_length <= MAX_FIELDS_FOR_FIELD_SENSITIVE, make
       sure this fails.  */
!   if (VEC_length (fieldoff_s, *fieldstack) > MAX_FIELDS_FOR_FIELD_SENSITIVE)
      return 0;
  
!   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
!     if (TREE_CODE (field) == FIELD_DECL)
!       {
! 	bool push = false;
! 	int pushed = 0;
! 
! 	if (has_union
! 	    && (TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
! 		|| TREE_CODE (TREE_TYPE (field)) == UNION_TYPE))
! 	  *has_union = true;
! 
! 	if (!var_can_have_subvars (field))
! 	  push = true;
! 	else if (!(pushed = push_fields_onto_fieldstack
! 		   (TREE_TYPE (field),
! 		    fieldstack,
! 		    offset + bitpos_of_field (field),
! 		    has_union))
! 		 && (DECL_SIZE (field)
! 		     && !integer_zerop (DECL_SIZE (field))))
! 	  /* Empty structures may have actual size, like in C++.  So
! 	     see if we didn't push any subfields and the size is
! 	     nonzero, push the field onto the stack.  */
! 	  push = true;
  
! 	if (push)
  	  {
! 	    fieldoff_s *pair;
  
! 	    pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
! 	    pair->type = TREE_TYPE (field);
! 	    pair->size = DECL_SIZE (field);
! 	    pair->decl = field;
! 	    pair->offset = offset + bitpos_of_field (field);
! 	    count++;
! 	  }
! 	else
! 	  count += pushed;
!       }
  
    return count;
  }
*************** create_variable_info_for (tree decl, con
*** 4389,4396 ****
  	     || TREE_CODE (decltype) == QUAL_UNION_TYPE;
    if (var_can_have_subvars (decl) && use_field_sensitive && !hasunion)
      {
!       push_fields_onto_fieldstack (decltype, &fieldstack, 0, &hasunion,
! 				   decltype);
        if (hasunion)
  	{
  	  VEC_free (fieldoff_s, heap, fieldstack);
--- 4326,4332 ----
  	     || TREE_CODE (decltype) == QUAL_UNION_TYPE;
    if (var_can_have_subvars (decl) && use_field_sensitive && !hasunion)
      {
!       push_fields_onto_fieldstack (decltype, &fieldstack, 0, &hasunion);
        if (hasunion)
  	{
  	  VEC_free (fieldoff_s, heap, fieldstack);
*************** create_variable_info_for (tree decl, con
*** 4398,4404 ****
  	}
      }
  
- 
    /* If the variable doesn't have subvars, we may end up needing to
       sort the field list and create fake variables for all the
       fields.  */
--- 4334,4339 ----


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