aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2008-05-09 09:32:51 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2008-05-09 09:32:51 +0000
commit31de5b771a7621f2e331e2839e8634dad0c6ee70 (patch)
treeba1aff86aaec6d938b63ca9a5e6aba055221e3b1 /gcc
parent3ee6cb3f69311ba36ca1faf2a25bb536e0acc038 (diff)
downloadgcc-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/ChangeLog16
-rw-r--r--gcc/tree-flow-inline.h30
-rw-r--r--gcc/tree-flow.h34
-rw-r--r--gcc/tree-ssa-structalias.c251
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. */