aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2008-07-06 18:38:15 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2008-07-06 18:38:15 +0000
commitee7d4b57a56be0420460691d7cfc92f5028a6aca (patch)
tree7d9c3e25895221d22c35c7113f4770ce918e5d15
parentc9faf4654f49b100b597bb3efbc9cd161c92e94f (diff)
downloadgcc-ee7d4b57a56be0420460691d7cfc92f5028a6aca.zip
gcc-ee7d4b57a56be0420460691d7cfc92f5028a6aca.tar.gz
gcc-ee7d4b57a56be0420460691d7cfc92f5028a6aca.tar.bz2
tree-ssa-structalias.c (struct variable_info): Remove has_union.
2008-07-06 Richard Guenther <rguenther@suse.de> * tree-ssa-structalias.c (struct variable_info): Remove has_union. (new_var_info): Deal with it. (solution_set_add): Likewise. (bitpos_of_field): Make signed, fix. (struct fieldoff): Remove type and decl fields. Make size field unsigned HOST_WIDE_INT. Add has_unknown_size and may_have_pointers flags. (fieldoff_compare): Deal with it. (push_fields_onto_fieldstack): Remove has_union argument, glob adjacent non-pointer fields together. (create_function_info_for): Do not set has_union. (create_variable_info_for): Simplify. * gcc.dg/tree-ssa/pta-callused.c: Adjust testcase. From-SVN: r137530
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c2
-rw-r--r--gcc/tree-ssa-structalias.c139
4 files changed, 84 insertions, 76 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9ee6347..3dd4618 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2008-07-06 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-structalias.c (struct variable_info): Remove has_union.
+ (new_var_info): Deal with it.
+ (solution_set_add): Likewise.
+ (bitpos_of_field): Make signed, fix.
+ (struct fieldoff): Remove type and decl fields. Make size field
+ unsigned HOST_WIDE_INT. Add has_unknown_size and may_have_pointers
+ flags.
+ (fieldoff_compare): Deal with it.
+ (push_fields_onto_fieldstack): Remove has_union argument, glob
+ adjacent non-pointer fields together.
+ (create_function_info_for): Do not set has_union.
+ (create_variable_info_for): Simplify.
+
2008-07-06 Kai Tietz <kai.tietz@onevision.com>
* config.gcc (extra_headers): Add cross-stdarg.h for target
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cf6ba6b..25c118e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2008-07-06 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/pta-callused.c: Adjust testcase.
+
2008-07-06 Kai Tietz <kai.tietz@onevision.com>
* gcc.dg/callabi/callabi.h: New.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c
index 44d095a..c2b512a 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c
@@ -22,6 +22,6 @@ int bar (int b)
return foo (&q);
}
-/* { dg-final { scan-tree-dump "CALLUSED = { f f.q i q }" "alias" } } */
+/* { dg-final { scan-tree-dump "CALLUSED = { f.* i q }" "alias" } } */
/* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 0b68b84..266538c 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -220,9 +220,6 @@ struct variable_info
/* True for variables whose size is not known or variable. */
unsigned int is_unknown_size_var:1;
- /* True for variables that have unions somewhere in them. */
- unsigned int has_union:1;
-
/* True if this is a heap variable. */
unsigned int is_heap_var:1;
@@ -376,7 +373,6 @@ new_var_info (tree t, unsigned int id, const char *name)
ret->is_heap_var = false;
ret->is_special_var = false;
ret->is_unknown_size_var = false;
- ret->has_union = false;
var = t;
if (TREE_CODE (var) == SSA_NAME)
var = SSA_NAME_VAR (var);
@@ -769,7 +765,6 @@ solution_set_add (bitmap set, unsigned HOST_WIDE_INT offset)
bitmap_set_bit (result, v->id);
}
else if (get_varinfo (i)->is_artificial_var
- || get_varinfo (i)->has_union
|| get_varinfo (i)->is_unknown_size_var)
{
bitmap_set_bit (result, i);
@@ -2670,16 +2665,16 @@ could_have_pointers (tree t)
/* Return the position, in bits, of FIELD_DECL from the beginning of its
structure. */
-static unsigned HOST_WIDE_INT
+static HOST_WIDE_INT
bitpos_of_field (const tree fdecl)
{
- if (TREE_CODE (DECL_FIELD_OFFSET (fdecl)) != INTEGER_CST
- || TREE_CODE (DECL_FIELD_BIT_OFFSET (fdecl)) != INTEGER_CST)
+ if (!host_integerp (DECL_FIELD_OFFSET (fdecl), 0)
+ || !host_integerp (DECL_FIELD_BIT_OFFSET (fdecl), 0))
return -1;
- return (tree_low_cst (DECL_FIELD_OFFSET (fdecl), 1) * 8)
- + tree_low_cst (DECL_FIELD_BIT_OFFSET (fdecl), 1);
+ return (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (fdecl)) * 8
+ + TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fdecl)));
}
@@ -4005,17 +4000,15 @@ insert_into_field_list_sorted (varinfo_t base, varinfo_t field)
struct fieldoff
{
- /* Type of the field. */
- tree type;
+ /* Offset from the base of the base containing object to this field. */
+ HOST_WIDE_INT offset;
/* Size, in bits, of the field. */
- tree size;
+ unsigned HOST_WIDE_INT size;
- /* Field. */
- tree decl;
+ unsigned has_unknown_size : 1;
- /* Offset from the base of the base containing object to this field. */
- HOST_WIDE_INT offset;
+ unsigned may_have_pointers : 1;
};
typedef struct fieldoff fieldoff_s;
@@ -4036,10 +4029,10 @@ fieldoff_compare (const void *pa, const void *pb)
else if (foa->offset > fob->offset)
return 1;
- foasize = TREE_INT_CST_LOW (foa->size);
- fobsize = TREE_INT_CST_LOW (fob->size);
+ foasize = foa->size;
+ fobsize = fob->size;
if (foasize < fobsize)
- return - 1;
+ return -1;
else if (foasize > fobsize)
return 1;
return 0;
@@ -4083,14 +4076,11 @@ var_can_have_subvars (const_tree v)
OFFSET is used to keep track of the offset in this entire
structure, rather than just the immediately containing structure.
- Returns the number of fields pushed.
-
- HAS_UNION is set to true if we find a union type as a field of
- TYPE. */
+ Returns the number of fields pushed. */
static int
push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
- HOST_WIDE_INT offset, bool *has_union)
+ HOST_WIDE_INT offset)
{
tree field;
int count = 0;
@@ -4109,19 +4099,14 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
{
bool push = false;
int pushed = 0;
+ HOST_WIDE_INT foff = bitpos_of_field (field);
- 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))
+ if (!var_can_have_subvars (field)
+ || TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
+ || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
push = true;
else if (!(pushed = push_fields_onto_fieldstack
- (TREE_TYPE (field),
- fieldstack,
- offset + bitpos_of_field (field),
- has_union))
+ (TREE_TYPE (field), fieldstack, offset + foff))
&& (DECL_SIZE (field)
&& !integer_zerop (DECL_SIZE (field))))
/* Empty structures may have actual size, like in C++. So
@@ -4131,14 +4116,39 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
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++;
+ fieldoff_s *pair = NULL;
+ bool has_unknown_size = false;
+
+ if (!VEC_empty (fieldoff_s, *fieldstack))
+ pair = VEC_last (fieldoff_s, *fieldstack);
+
+ if (!DECL_SIZE (field)
+ || !host_integerp (DECL_SIZE (field), 1))
+ has_unknown_size = true;
+
+ /* If adjacent fields do not contain pointers merge them. */
+ if (pair
+ && !pair->may_have_pointers
+ && !could_have_pointers (field)
+ && !pair->has_unknown_size
+ && !has_unknown_size
+ && pair->offset + (HOST_WIDE_INT)pair->size == offset + foff)
+ {
+ pair = VEC_last (fieldoff_s, *fieldstack);
+ pair->size += TREE_INT_CST_LOW (DECL_SIZE (field));
+ }
+ else
+ {
+ pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
+ pair->offset = offset + foff;
+ pair->has_unknown_size = has_unknown_size;
+ if (!has_unknown_size)
+ pair->size = TREE_INT_CST_LOW (DECL_SIZE (field));
+ else
+ pair->size = -1;
+ pair->may_have_pointers = could_have_pointers (field);
+ count++;
+ }
}
else
count += pushed;
@@ -4204,7 +4214,6 @@ create_function_info_for (tree decl, const char *name)
vi = new_var_info (decl, index, name);
vi->decl = decl;
vi->offset = 0;
- vi->has_union = 0;
vi->size = 1;
vi->fullsize = count_num_arguments (decl, &is_varargs) + 1;
insert_vi_for_tree (vi->decl, vi);
@@ -4249,7 +4258,6 @@ create_function_info_for (tree decl, const char *name)
argvi->offset = i;
argvi->size = 1;
argvi->fullsize = vi->fullsize;
- argvi->has_union = false;
insert_into_field_list_sorted (vi, argvi);
stats.total_vars ++;
if (arg)
@@ -4285,7 +4293,6 @@ create_function_info_for (tree decl, const char *name)
resultvi->offset = i;
resultvi->size = 1;
resultvi->fullsize = vi->fullsize;
- resultvi->has_union = false;
insert_into_field_list_sorted (vi, resultvi);
stats.total_vars ++;
if (DECL_RESULT (decl))
@@ -4325,25 +4332,14 @@ create_variable_info_for (tree decl, const char *name)
varinfo_t vi;
tree decltype = TREE_TYPE (decl);
tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decltype);
- bool notokay = false;
- bool hasunion;
bool is_global = DECL_P (decl) ? is_global_var (decl) : false;
VEC (fieldoff_s,heap) *fieldstack = NULL;
if (TREE_CODE (decl) == FUNCTION_DECL && in_ipa_mode)
return create_function_info_for (decl, name);
- hasunion = TREE_CODE (decltype) == UNION_TYPE
- || 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);
- notokay = true;
- }
- }
+ if (var_can_have_subvars (decl) && use_field_sensitive)
+ push_fields_onto_fieldstack (decltype, &fieldstack, 0);
/* If the variable doesn't have subvars, we may end up needing to
sort the field list and create fake variables for all the
@@ -4351,11 +4347,8 @@ create_variable_info_for (tree decl, const char *name)
vi = new_var_info (decl, index, name);
vi->decl = decl;
vi->offset = 0;
- vi->has_union = hasunion;
if (!declsize
- || TREE_CODE (declsize) != INTEGER_CST
- || TREE_CODE (decltype) == UNION_TYPE
- || TREE_CODE (decltype) == QUAL_UNION_TYPE)
+ || !host_integerp (declsize, 1))
{
vi->is_unknown_size_var = true;
vi->fullsize = ~0;
@@ -4375,7 +4368,6 @@ create_variable_info_for (tree decl, const char *name)
stats.total_vars++;
if (use_field_sensitive
- && !notokay
&& !vi->is_unknown_size_var
&& var_can_have_subvars (decl)
&& VEC_length (fieldoff_s, fieldstack) > 1
@@ -4383,12 +4375,12 @@ create_variable_info_for (tree decl, const char *name)
{
unsigned int newindex = VEC_length (varinfo_t, varmap);
fieldoff_s *fo = NULL;
+ bool notokay = false;
unsigned int i;
for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
{
- if (! fo->size
- || TREE_CODE (fo->size) != INTEGER_CST
+ if (fo->has_unknown_size
|| fo->offset < 0)
{
notokay = true;
@@ -4423,7 +4415,7 @@ create_variable_info_for (tree decl, const char *name)
return index;
}
- vi->size = TREE_INT_CST_LOW (fo->size);
+ vi->size = fo->size;
vi->offset = fo->offset;
for (i = VEC_length (fieldoff_s, fieldstack) - 1;
i >= 1 && VEC_iterate (fieldoff_s, fieldstack, i, fo);
@@ -4436,23 +4428,20 @@ create_variable_info_for (tree decl, const char *name)
newindex = VEC_length (varinfo_t, varmap);
if (dump_file)
{
- if (fo->decl)
- asprintf (&tempname, "%s.%s",
- vi->name, alias_get_name (fo->decl));
- else
- asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC,
- vi->name, fo->offset);
+ asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC
+ "+" HOST_WIDE_INT_PRINT_DEC,
+ vi->name, fo->offset, fo->size);
newname = ggc_strdup (tempname);
free (tempname);
}
newvi = new_var_info (decl, newindex, newname);
newvi->offset = fo->offset;
- newvi->size = TREE_INT_CST_LOW (fo->size);
+ newvi->size = fo->size;
newvi->fullsize = vi->fullsize;
insert_into_field_list (vi, newvi);
VEC_safe_push (varinfo_t, heap, varmap, newvi);
if (is_global && (!flag_whole_program || !in_ipa_mode)
- && (!fo->decl || could_have_pointers (fo->decl)))
+ && fo->may_have_pointers)
make_constraint_from (newvi, escaped_id);
stats.total_vars++;