diff options
author | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-11-13 15:20:40 +0000 |
---|---|---|
committer | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-11-13 15:20:40 +0000 |
commit | 18346ecd861dc66e71dafe48ff216cfa4dc95a21 (patch) | |
tree | b04ec56bade931807b6ed40c6d251c05aa588f0b /gcc/tree-ssa-alias.c | |
parent | 62e369b3a7e2a62037d4b22f55f96530b76bb9f8 (diff) | |
download | gcc-18346ecd861dc66e71dafe48ff216cfa4dc95a21.tar.gz |
pr 33870
* tree.h (strcut tree_memory_tag): add field unpartitionable.
remove field in_nested_struct.
(struct tree_struct_field_tag): add field nesting_level.
(sft_in_nested_struct): remove.
(sft_nesting_level): define.
(sft_unpartitionable_p): define.
* tree-ssa-alias.c (mem_sym_score): if mp->var is not
partitionable, return long_max.
(compute_memory_partitions): do not partition sfts marked
unpartitionable.
(create_sft): add argument nesting_level. set
sft_nesting_level with it. update all users.
(create_overlap_variables_for): show nesting level.
* tree-dfa.c (dump_subvars_for): likewise.
(dump_variable): likewise.
show whether the sft is partitionable or not.
* tree-flow.h (struct fieldoff): remove field
in_nested_struct.
add field nesting_level.
* tree-ssa-structalias.c (struct variable_info): remove
field in_nested_struct.
(push_fields_onto_fieldstack): add argument
nesting_level. update all users.
update documentation.
update pair->nesting_level with nesting_level.
make recursive calls with nesting_level + 1.
(set_uids_in_ptset): if an sft is added to the points-to
set, mark it as unpartitionable.
* tree-ssa-operands.c (ref_nesting_level): new.
(add_vars_for_offset): call it.
add argument full_ref. update
callers.
if var is inside a nested structure and the nesting level
of full_ref is lower than the nesting level of var,
adjust offset by the offset of var.
testsuite/ChangeLog
PR 33870
* gcc.c-torture/execute/pr33870-1.c: New test.
* gcc.dg/tree-ssa/alias-16.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130141 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r-- | gcc/tree-ssa-alias.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index f2e30646d4c..31e04bcca29 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -828,6 +828,13 @@ count_mem_refs (long *num_vuses_p, long *num_vdefs_p, static inline long mem_sym_score (mem_sym_stats_t mp) { + /* Unpartitionable SFTs are automatically thrown to the bottom of + the list. They are not stored in partitions, but they are used + for computing overall statistics. */ + if (TREE_CODE (mp->var) == STRUCT_FIELD_TAG + && SFT_UNPARTITIONABLE_P (mp->var)) + return LONG_MAX; + return mp->frequency_writes * 64 + mp->frequency_reads * 32 + mp->num_direct_writes * 16 + mp->num_direct_reads * 8 + mp->num_indirect_writes * 4 + mp->num_indirect_reads * 2 @@ -1392,8 +1399,8 @@ update_reference_counts (struct mem_ref_stats_d *mem_ref_stats) static void build_mp_info (struct mem_ref_stats_d *mem_ref_stats, - VEC(mem_sym_stats_t,heap) **mp_info_p, - VEC(tree,heap) **tags_p) + VEC(mem_sym_stats_t,heap) **mp_info_p, + VEC(tree,heap) **tags_p) { tree var; referenced_var_iterator rvi; @@ -1591,6 +1598,15 @@ compute_memory_partitions (void) if (!need_to_partition_p (mem_ref_stats)) break; + /* SFTs that are marked unpartitionable should not be added to + partitions. These SFTs are special because they mark the + first SFT into a structure where a pointer is pointing to. + This is needed by the operand scanner to find adjacent + fields. See add_vars_for_offset for details. */ + if (TREE_CODE (mp_p->var) == STRUCT_FIELD_TAG + && SFT_UNPARTITIONABLE_P (mp_p->var)) + continue; + mpt = find_partition_for (mp_p); estimate_vop_reduction (mem_ref_stats, mp_p, mpt); } @@ -3774,7 +3790,8 @@ get_or_create_used_part_for (size_t uid) static tree create_sft (tree var, tree field, unsigned HOST_WIDE_INT offset, - unsigned HOST_WIDE_INT size, alias_set_type alias_set) + unsigned HOST_WIDE_INT size, alias_set_type alias_set, + unsigned nesting_level) { tree subvar = create_tag_raw (STRUCT_FIELD_TAG, field, "SFT"); @@ -3794,6 +3811,8 @@ create_sft (tree var, tree field, unsigned HOST_WIDE_INT offset, SFT_OFFSET (subvar) = offset; SFT_SIZE (subvar) = size; SFT_ALIAS_SET (subvar) = alias_set; + SFT_NESTING_LEVEL (subvar) = nesting_level; + return subvar; } @@ -3814,7 +3833,7 @@ create_overlap_variables_for (tree var) return; push_fields_onto_fieldstack (TREE_TYPE (var), &fieldstack, 0, NULL, - TREE_TYPE (var)); + TREE_TYPE (var), 0); if (VEC_length (fieldoff_s, fieldstack) != 0) { subvar_t *subvars; @@ -3897,7 +3916,6 @@ create_overlap_variables_for (tree var) field, skip it. Note that we always need the field at offset 0 so we can properly handle pointers to the structure. */ - if ((fo->offset != 0 && ((fo->offset <= up->minused && fo->offset + fosize <= up->minused) @@ -3906,8 +3924,9 @@ create_overlap_variables_for (tree var) && fosize == lastfosize && currfotype == lastfotype)) continue; - subvar = create_sft (var, fo->type, fo->offset, - fosize, fo->alias_set); + + subvar = create_sft (var, fo->type, fo->offset, fosize, + fo->alias_set, fo->nesting_level); VEC_quick_push (tree, *subvars, subvar); if (dump_file) @@ -3918,7 +3937,8 @@ create_overlap_variables_for (tree var) SFT_OFFSET (subvar)); fprintf (dump_file, " size " HOST_WIDE_INT_PRINT_DEC, SFT_SIZE (subvar)); - fprintf (dump_file, "\n"); + fprintf (dump_file, " nesting level %d\n", + SFT_NESTING_LEVEL (subvar)); } lastfotype = currfotype; |