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
This commit is contained in:
Daniel Berlin 2005-03-21 19:27:00 +00:00 committed by Daniel Berlin
parent d331e20402
commit 013cc86f9a
6 changed files with 86 additions and 50 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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 *);

View File

@ -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);
}
}

View File

@ -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))
{

View File

@ -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. */