This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][1/2] More cleanups after SFT code removal
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 9 May 2008 11:26:24 +0200 (CEST)
- Subject: [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 ----