aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-structalias.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2007-11-16 14:40:04 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2007-11-16 14:40:04 +0000
commit99739a3e63eb906c77b8acdb76d4f40485eb56fe (patch)
treeb456fc38c0a138350839b7ebdcbf56a53752ed5d /gcc/tree-ssa-structalias.c
parentbf3bde19e0bf954db21ec98ee179262ec68c5ded (diff)
downloadgcc-99739a3e63eb906c77b8acdb76d4f40485eb56fe.zip
gcc-99739a3e63eb906c77b8acdb76d4f40485eb56fe.tar.gz
gcc-99739a3e63eb906c77b8acdb76d4f40485eb56fe.tar.bz2
re PR tree-optimization/33870 (miscompiles sqlite)
2007-11-16 Richard Guenther <rguenther@suse.de> PR tree-optimization/33870 * tree.h (struct tree_memory_tag): Add base_for_components flag. (struct tree_struct_field_tag): Remove nesting_level field. (SFT_NESTING_LEVEL): Remove. (SFT_BASE_FOR_COMPONENTS_P): Add. * tree-flow.h (struct fieldoff): Remove nesting_level field. Add base_for_components flag. (push_fields_onto_fieldstack): Remove nesting_level parameter. * tree-ssa-alias.c (create_sft): Likewise. Add base_for_components parameter. (create_overlap_variables_for): Deal with it. * tree-dfa.c (dump_subvars_for): Likewise. (dump_variable): Likewise. * tree-ssa-structalias.c (push_fields_onto_fieldstack): Likewise. Set base_for_components for first elements of sub-structures. (create_variable_info_for): Handle base_for_components. (set_uids_in_ptset): Always set SFT_UNPARTITIONABLE_P for pointed-to SFTs if SFT_BASE_FOR_COMPONENTS_P is set. * tree-ssa-operands.c (ref_nesting_level): Remove. (add_vars_for_offset): Remove full_ref parameter, always add the offset of the pointed-to SFT. (add_virtual_operand): Adjust for changed signature of add_vars_for_offset. * gcc.dg/torture/pr33870.c: New testcase. From-SVN: r130231
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r--gcc/tree-ssa-structalias.c133
1 files changed, 68 insertions, 65 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index b175d25..5fbcfc5 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -4053,19 +4053,16 @@ sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
TYPE.
ADDRESSABLE_TYPE is the type of the outermost object that could
- have its address taken.
-
- NESTING_LEVEL indicates whether TYPE is a structure nested inside
- another, it starts at 0 and it is incremented by one on every
- structure recursed into. */
+ 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, unsigned nesting_level)
+ tree addressable_type)
{
tree field;
int count = 0;
+ int first_element = VEC_length (fieldoff_s, *fieldstack);
if (TREE_CODE (type) == COMPLEX_TYPE)
{
@@ -4076,6 +4073,7 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
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);
@@ -4083,11 +4081,12 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
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;
- return 2;
+ count = 2;
}
- if (TREE_CODE (type) == ARRAY_TYPE)
+ else if (TREE_CODE (type) == ARRAY_TYPE)
{
tree sz = TYPE_SIZE (type);
tree elsz = TYPE_SIZE (TREE_TYPE (type));
@@ -4125,8 +4124,7 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
has_union,
(TYPE_NONALIASED_COMPONENT (type)
? addressable_type
- : TREE_TYPE (type)),
- nesting_level + 1)))
+ : 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 */
@@ -4145,64 +4143,69 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
pair->alias_set = get_alias_set (addressable_type);
else
pair->alias_set = -1;
- pair->nesting_level = nesting_level;
+ pair->base_for_components = false;
count++;
}
else
count += pushed;
}
-
- return count;
}
- 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)),
- nesting_level + 1))
- && 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)
+ else
+ {
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL)
{
- 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);
+ 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)))
+ /* 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);
+ 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
- pair->alias_set = -1;
- pair->nesting_level = nesting_level;
- count++;
- }
- else
- count += pushed;
- }
+ 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;
}
@@ -4397,7 +4400,7 @@ create_variable_info_for (tree decl, const char *name)
if (var_can_have_subvars (decl) && use_field_sensitive && !hasunion)
{
push_fields_onto_fieldstack (decltype, &fieldstack, 0, &hasunion,
- decltype, 0);
+ decltype);
if (hasunion)
{
VEC_free (fieldoff_s, heap, fieldstack);
@@ -4774,15 +4777,15 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed,
{
bitmap_set_bit (into, DECL_UID (sft));
- /* If SFT is inside a nested structure, it will
- be needed by the operand scanner to adjust
- offsets when adding operands to memory
+ /* Pointed-to SFTs are needed by the operand scanner
+ to adjust offsets when adding operands to memory
expressions that dereference PTR. This means
that memory partitioning may not partition
this SFT because the operand scanner will not
be able to find the other SFTs next to this
- one. */
- if (SFT_NESTING_LEVEL (sft) > 0)
+ one. But we only need to do this if the pointed
+ to type is aggregate. */
+ if (SFT_BASE_FOR_COMPONENTS_P (sft))
SFT_UNPARTITIONABLE_P (sft) = true;
}
}