diff options
author | Daniel Berlin <dberlin@dberlin.org> | 2005-03-21 19:27:00 +0000 |
---|---|---|
committer | Daniel Berlin <dberlin@gcc.gnu.org> | 2005-03-21 19:27:00 +0000 |
commit | 013cc86f9abb27c545e61c6a3e872ca147040be7 (patch) | |
tree | fa074c6a524b35099d5e619373b0066febd064c9 /gcc | |
parent | d331e204024e2a74124880dd0dee8f4952fc9b26 (diff) | |
download | gcc-013cc86f9abb27c545e61c6a3e872ca147040be7.zip gcc-013cc86f9abb27c545e61c6a3e872ca147040be7.tar.gz gcc-013cc86f9abb27c545e61c6a3e872ca147040be7.tar.bz2 |
re PR tree-optimization/20542 (Bootstrap failure at -Os)
2005-03-18 Daniel Berlin <dberlin@dberlin.org>
Fix PR tree-optimization/20542
* tree-flow-inline.h (overlap_subvar): Move to here.
* tree-ssa-operands.c: From here.
* tree-flow.h (overlap_subvar): Declare.
* tree-ssa-alias.c (add_pointed_to_var): Use overlap_subvar here.
* tree-ssa-loop-im.c (is_call_clobbered_ref): Return proper answer
for variables with subvars.
From-SVN: r96829
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/tree-flow-inline.h | 43 | ||||
-rw-r--r-- | gcc/tree-flow.h | 3 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 7 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-im.c | 29 | ||||
-rw-r--r-- | gcc/tree-ssa-operands.c | 43 |
6 files changed, 86 insertions, 50 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b87be58..571faae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2005-03-18 Daniel Berlin <dberlin@dberlin.org> + + Fix PR tree-optimization/20542 + + * tree-flow-inline.h (overlap_subvar): Move to here. + * tree-ssa-operands.c: From here. + * tree-flow.h (overlap_subvar): Declare. + * tree-ssa-alias.c (add_pointed_to_var): Use overlap_subvar here. + * tree-ssa-loop-im.c (is_call_clobbered_ref): Return proper answer + for variables with subvars. + 2005-03-21 Mostafa Hagog <mustafa@il.ibm.com> PR middle-end/20177 diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index 2d29eb2..4d6f5cb 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -933,5 +933,48 @@ var_can_have_subvars (tree v) } +/* Return true if OFFSET and SIZE define a range that overlaps with some + portion of the range of SV, a subvar. If there was an exact overlap, + *EXACT will be set to true upon return. */ + +static inline bool +overlap_subvar (HOST_WIDE_INT offset, HOST_WIDE_INT size, + subvar_t sv, bool *exact) +{ + /* There are three possible cases of overlap. + 1. We can have an exact overlap, like so: + |offset, offset + size | + |sv->offset, sv->offset + sv->size | + + 2. We can have offset starting after sv->offset, like so: + + |offset, offset + size | + |sv->offset, sv->offset + sv->size | + + 3. We can have offset starting before sv->offset, like so: + + |offset, offset + size | + |sv->offset, sv->offset + sv->size| + */ + + if (exact) + *exact = false; + if (offset == sv->offset && size == sv->size) + { + if (exact) + *exact = true; + return true; + } + else if (offset >= sv->offset && offset < (sv->offset + sv->size)) + { + return true; + } + else if (offset < sv->offset && (offset + size > sv->offset)) + { + return true; + } + return false; + +} #endif /* _TREE_FLOW_INLINE_H */ diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 25d3e5a..abca659 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -596,6 +596,9 @@ static inline bool ref_contains_array_ref (tree); extern tree okay_component_ref_for_subvars (tree, HOST_WIDE_INT *, HOST_WIDE_INT *); static inline bool var_can_have_subvars (tree); +static inline bool overlap_subvar (HOST_WIDE_INT, HOST_WIDE_INT, + subvar_t, bool *); + /* Call-back function for walk_use_def_chains(). At each reaching definition, a function with this prototype is called. */ typedef bool (*walk_use_def_chains_fn) (tree, tree, void *); diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 315463f..12a432b 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -1992,12 +1992,7 @@ add_pointed_to_var (struct alias_info *ai, tree ptr, tree value) for (sv = svars; sv; sv = sv->next) { - if (offset == sv->offset && size == sv->size) - bitmap_set_bit (pi->pt_vars, var_ann (sv->var)->uid); - else if (offset >= sv->offset && offset < (sv->offset + sv->size)) - bitmap_set_bit (pi->pt_vars, var_ann (sv->var)->uid); - else if (offset < sv->offset - && (offset + size > sv->offset)) + if (overlap_subvar (offset, size, sv, NULL)) bitmap_set_bit (pi->pt_vars, var_ann (sv->var)->uid); } } diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 4b695aa..51ada3d 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -1146,13 +1146,40 @@ static bool is_call_clobbered_ref (tree ref) { tree base; + HOST_WIDE_INT offset, size; + subvar_t sv; + subvar_t svars; + tree sref = ref; + if (TREE_CODE (sref) == COMPONENT_REF + && (sref = okay_component_ref_for_subvars (sref, &offset, &size))) + { + svars = get_subvars_for_var (sref); + for (sv = svars; sv; sv = sv->next) + { + if (overlap_subvar (offset, size, sv, NULL) + && is_call_clobbered (sv->var)) + return true; + } + } + base = get_base_address (ref); if (!base) return true; if (DECL_P (base)) - return is_call_clobbered (base); + { + if (var_can_have_subvars (base) + && (svars = get_subvars_for_var (base))) + { + for (sv = svars; sv; sv = sv->next) + if (is_call_clobbered (sv->var)) + return true; + return false; + } + else + return is_call_clobbered (base); + } if (INDIRECT_REF_P (base)) { diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index a3b44e2..1ef06db 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -1024,49 +1024,6 @@ get_stmt_operands (tree stmt) } -/* Return true if OFFSET and SIZE define a range that overlaps with some - portion of the range of SV, a subvar. If there was an exact overlap, - *EXACT will be set to true upon return. */ - -static bool -overlap_subvar (HOST_WIDE_INT offset, HOST_WIDE_INT size, - subvar_t sv, bool *exact) -{ - /* There are three possible cases of overlap. - 1. We can have an exact overlap, like so: - |offset, offset + size | - |sv->offset, sv->offset + sv->size | - - 2. We can have offset starting after sv->offset, like so: - - |offset, offset + size | - |sv->offset, sv->offset + sv->size | - - 3. We can have offset starting before sv->offset, like so: - - |offset, offset + size | - |sv->offset, sv->offset + sv->size| - */ - - if (exact) - *exact = false; - if (offset == sv->offset && size == sv->size) - { - if (exact) - *exact = true; - return true; - } - else if (offset >= sv->offset && offset < (sv->offset + sv->size)) - { - return true; - } - else if (offset < sv->offset && (offset + size > sv->offset)) - { - return true; - } - return false; - -} /* Recursively scan the expression pointed by EXPR_P in statement referred to by INFO. FLAGS is one of the OPF_* constants modifying how to interpret the operands found. */ |