diff options
author | Richard Guenther <rguenther@suse.de> | 2008-05-09 09:32:51 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2008-05-09 09:32:51 +0000 |
commit | 31de5b771a7621f2e331e2839e8634dad0c6ee70 (patch) | |
tree | ba1aff86aaec6d938b63ca9a5e6aba055221e3b1 /gcc | |
parent | 3ee6cb3f69311ba36ca1faf2a25bb536e0acc038 (diff) | |
download | gcc-31de5b771a7621f2e331e2839e8634dad0c6ee70.zip gcc-31de5b771a7621f2e331e2839e8634dad0c6ee70.tar.gz gcc-31de5b771a7621f2e331e2839e8634dad0c6ee70.tar.bz2 |
tree-flow-inline.h (var_can_have_subvars): Move ...
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.
From-SVN: r135110
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/tree-flow-inline.h | 30 | ||||
-rw-r--r-- | gcc/tree-flow.h | 34 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 251 |
4 files changed, 109 insertions, 222 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6fb86b0..b20ba0f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +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. + 2008-05-08 Seongbae Park <seongbae.park@gmail.com> * common.opt (Wframe-larger-than=): Shorten the help message diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index 7b82ba3..f2fe01e 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -1581,36 +1581,6 @@ ref_contains_array_ref (const_tree ref) 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. */ diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index fa1522b..848a9d9 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -854,7 +854,6 @@ static inline bool ref_contains_array_ref (const_tree); 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 *); @@ -1169,39 +1168,6 @@ rtx addr_for_mem_ref (struct mem_address *, bool); 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); diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index b9afe3b..f368631 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -3994,6 +3994,30 @@ insert_into_field_list_sorted (varinfo_t base, varinfo_t field) } } +/* 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 @@ -4012,7 +4036,7 @@ fieldoff_compare (const void *pa, const void *pb) } /* Sort a fieldstack according to the field offset and sizes. */ -void +static void sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack) { qsort (VEC_address (fieldoff_s, fieldstack), @@ -4021,6 +4045,28 @@ sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack) 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. @@ -4030,172 +4076,63 @@ sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack) 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. */ + TYPE. */ -int +static int push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, - HOST_WIDE_INT offset, bool *has_union, - tree addressable_type) + HOST_WIDE_INT offset, bool *has_union) { tree field; int count = 0; - unsigned int first_element = VEC_length (fieldoff_s, *fieldstack); + + 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 (first_element > MAX_FIELDS_FOR_FIELD_SENSITIVE) + if (VEC_length (fieldoff_s, *fieldstack) > 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) + 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) { - 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; + 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; } @@ -4389,8 +4326,7 @@ create_variable_info_for (tree decl, const char *name) || 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); + push_fields_onto_fieldstack (decltype, &fieldstack, 0, &hasunion); if (hasunion) { VEC_free (fieldoff_s, heap, fieldstack); @@ -4398,7 +4334,6 @@ create_variable_info_for (tree decl, const char *name) } } - /* 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. */ |