mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 15:11:08 +08:00
re PR tree-optimization/33870 (miscompiles sqlite)
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. From-SVN: r129976
This commit is contained in:
parent
e4fd5b87bf
commit
6f09f3140c
@ -1,3 +1,22 @@
|
||||
2007-11-07 Diego Novillo <dnovillo@google.com>
|
||||
|
||||
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).
|
||||
|
||||
2007-11-07 Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||
|
||||
PR rtl-optimization/33737
|
||||
|
@ -1,3 +1,8 @@
|
||||
2007-11-07 Diego Novillo <dnovillo@google.com>
|
||||
|
||||
PR 33870
|
||||
* gcc.c-torture/execute/pr33870.x: Remove.
|
||||
|
||||
2007-11-07 Douglas Gregor <doug.gregor@gmail.com>
|
||||
|
||||
PR c++/33045
|
||||
|
@ -1,9 +0,0 @@
|
||||
# The test breaks because of wrong alias info for -O2 and -Os
|
||||
|
||||
set torture_eval_before_compile {
|
||||
if {[string match {*-O[2s]*} "$option"]} {
|
||||
set torture_execute_xfail "*-*-*"
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
@ -287,7 +287,7 @@ dump_subvars_for (FILE *file, tree var)
|
||||
for (i = 0; VEC_iterate (tree, sv, i, subvar); ++i)
|
||||
{
|
||||
print_generic_expr (file, subvar, dump_flags);
|
||||
fprintf (file, " ");
|
||||
fprintf (file, "@" HOST_WIDE_INT_PRINT_UNSIGNED " ", SFT_OFFSET (subvar));
|
||||
}
|
||||
|
||||
fprintf (file, "}");
|
||||
|
@ -1159,6 +1159,10 @@ struct fieldoff
|
||||
/* Field. */
|
||||
tree decl;
|
||||
|
||||
/* True if this field is inside a structure nested inside the base
|
||||
containing object. */
|
||||
unsigned int in_nested_struct : 1;
|
||||
|
||||
/* Offset from the base of the base containing object to this field. */
|
||||
HOST_WIDE_INT offset;
|
||||
|
||||
|
@ -1397,8 +1397,48 @@ add_vars_for_offset (tree var, unsigned HOST_WIDE_INT offset,
|
||||
subvar_t sv;
|
||||
unsigned int i;
|
||||
|
||||
/* Adjust offset by the pointed-to location. */
|
||||
offset += SFT_OFFSET (var);
|
||||
if (SFT_IN_NESTED_STRUCT (var))
|
||||
{
|
||||
/* Since VAR is an SFT inside a nested structure, the OFFSET
|
||||
computed by get_ref_base_and_extent is the offset from the
|
||||
start of the immediately containing structure. However, to
|
||||
find out what other SFTs are affected by this reference, we
|
||||
need to know the offsets starting at the root structure in
|
||||
the nesting hierarchy.
|
||||
|
||||
For instance, given the following structure:
|
||||
|
||||
struct X {
|
||||
int a;
|
||||
struct Y {
|
||||
int b;
|
||||
struct Z {
|
||||
int c[3];
|
||||
} d;
|
||||
} e;
|
||||
} m;
|
||||
|
||||
and the following address expression:
|
||||
|
||||
p_1 = &m.e.d;
|
||||
|
||||
This structure will receive 5 SFTs, namely 2 for fields 'a'
|
||||
and 'b' and 3 for the array 'c' in struct Z. So, the
|
||||
reference p_1->c[2] and m.e.d.c[2] access the exact same
|
||||
memory location (ie, SFT.5).
|
||||
|
||||
Now, alias analysis computed the points-to set for pointer
|
||||
p_1 as { SFT.3 } because that is the first field that p_1
|
||||
actually points to. When the expression p_1->c[2] is
|
||||
analyzed, get_ref_base_and_extent will return an offset of 96
|
||||
because we are accessing the third element of the array. But
|
||||
the SFT we are looking for is actually at offset 160,
|
||||
counting from the top of struct X.
|
||||
|
||||
Therefore, we adjust OFFSET by the offset of VAR so that we
|
||||
can get at all the fields starting at VAR. */
|
||||
offset += SFT_OFFSET (var);
|
||||
}
|
||||
|
||||
/* Add all subvars of var that overlap with the access.
|
||||
Binary search for the first relevant SFT. */
|
||||
|
@ -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++;
|
||||
|
||||
|
@ -2573,15 +2573,21 @@ struct tree_struct_field_tag GTY(())
|
||||
/* Size of the field. */
|
||||
unsigned HOST_WIDE_INT size;
|
||||
|
||||
/* True if this SFT is for a field in a nested structure. */
|
||||
unsigned int in_nested_struct : 1;
|
||||
|
||||
/* Alias set for a DECL_NONADDRESSABLE_P field. Otherwise -1. */
|
||||
alias_set_type alias_set;
|
||||
};
|
||||
|
||||
#define SFT_PARENT_VAR(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.parent_var)
|
||||
#define SFT_OFFSET(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.offset)
|
||||
#define SFT_SIZE(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.size)
|
||||
#define SFT_NONADDRESSABLE_P(NODE) \
|
||||
(STRUCT_FIELD_TAG_CHECK (NODE)->sft.alias_set != -1)
|
||||
#define SFT_ALIAS_SET(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.alias_set)
|
||||
#define SFT_IN_NESTED_STRUCT(NODE) \
|
||||
(STRUCT_FIELD_TAG_CHECK (NODE)->sft.in_nested_struct)
|
||||
|
||||
/* Memory Partition Tags (MPTs) group memory symbols under one
|
||||
common name for the purposes of placing memory PHI nodes. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user