diff options
author | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-11-08 00:01:38 +0000 |
---|---|---|
committer | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-11-08 00:01:38 +0000 |
commit | f5ef996258725dd451733c21e2bba88c87019646 (patch) | |
tree | 06efa0a928d92fb0ec421d6bddae19cebfe2145b /gcc/tree-ssa-structalias.c | |
parent | a7905afa00a185861ad143eea26089abd5dbb966 (diff) | |
download | gcc-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.c | 24 |
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++; |