summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-structalias.c
diff options
context:
space:
mode:
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2007-11-08 00:01:38 +0000
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2007-11-08 00:01:38 +0000
commitf5ef996258725dd451733c21e2bba88c87019646 (patch)
tree06efa0a928d92fb0ec421d6bddae19cebfe2145b /gcc/tree-ssa-structalias.c
parenta7905afa00a185861ad143eea26089abd5dbb966 (diff)
downloadgcc-f5ef996258725dd451733c21e2bba88c87019646.tar.gz
PR 33870
* tree.h (struct tree_struct_field_tag): Add field in_nested_struct. (SFT_IN_NESTED_STRUCT): Define. * tree-dfa.c (dump_subvars_for): Show offset of each sub-var. * tree-flow.h (struct fieldoff): Add field in_nested_struct. * tree-ssa-structalias.c (struct variable_info): Likewise. (push_fields_onto_fieldstack): If OFFSET is positive, set in_nested_struct. (create_variable_info_for): Copy setting of in_nested_struct from the field offset object. (set_uids_in_ptset): Set SFT_IN_NESTED_STRUCT from the variable info object. * tree-ssa-operands.c (add_vars_for_offset): If VAR belongs to a nested structure, adjust OFFSET by SFT_OFFSET(VAR). testsuite/ChangeLog * gcc.c-torture/execute/pr33870.x: Remove. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129976 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r--gcc/tree-ssa-structalias.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 02124992b5b..2d3a40a8731 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -253,6 +253,15 @@ struct variable_info
variable. This is used for C++ placement new. */
unsigned int no_tbaa_pruning : 1;
+ /* True if this variable is inside a structure nested in the
+ structure for the base variable. For instance, in
+ struct X { int a; struct Y { int b; int c; } }, the variables for
+ fields 'b' and 'c' are inside a nested structure. We are not
+ interested in tracking how many levels of nesting, just whether
+ there is nesting at all. This is later used to adjust offsets
+ for pointers pointing into sub-structures. */
+ unsigned int in_nested_struct : 1;
+
/* Points-to set for this variable. */
bitmap solution;
@@ -4133,6 +4142,12 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
pair->alias_set = get_alias_set (addressable_type);
else
pair->alias_set = -1;
+
+ /* If the base offset is positive, this field belongs to
+ a structure nested inside the base structure. */
+ if (offset > 0)
+ pair->in_nested_struct = true;
+
count++;
}
else
@@ -4181,6 +4196,12 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
pair->alias_set = get_alias_set (addressable_type);
else
pair->alias_set = -1;
+
+ /* If the base offset is positive, this field belongs to
+ a structure nested inside the base structure. */
+ if (offset > 0)
+ pair->in_nested_struct = true;
+
count++;
}
else
@@ -4491,6 +4512,7 @@ create_variable_info_for (tree decl, const char *name)
newvi->offset = fo->offset;
newvi->size = TREE_INT_CST_LOW (fo->size);
newvi->fullsize = vi->fullsize;
+ newvi->in_nested_struct = fo->in_nested_struct;
insert_into_field_list (vi, newvi);
VEC_safe_push (varinfo_t, heap, varmap, newvi);
if (is_global && (!flag_whole_program || !in_ipa_mode))
@@ -4743,6 +4765,7 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed,
|| (!is_derefed && !vi->directly_dereferenced)
|| alias_sets_conflict_p (ptr_alias_set, var_alias_set))
bitmap_set_bit (into, DECL_UID (sft));
+ SFT_IN_NESTED_STRUCT (sft) = vi->in_nested_struct;
}
}
else
@@ -4946,7 +4969,6 @@ find_what_p_points_to (tree p)
}
/* Share the final set of variables when possible. */
-
finished_solution = BITMAP_GGC_ALLOC ();
stats.points_to_sets_created++;