Commit d8279b12 by Richard Guenther Committed by Richard Biener

tree-flow.h (array_at_struct_end_p): Move declaration ...

2012-04-17  Richard Guenther  <rguenther@suse.de>

	* tree-flow.h (array_at_struct_end_p): Move declaration ...
	* tree.h (array_at_struct_end_p): ... here.
	* tree-ssa-loop-niter.c (array_at_struct_end_p): Move ...
	* expr.c (array_at_struct_end_p): ... here.  Rewrite.

From-SVN: r186527
parent c5c20c55
2012-04-17 Richard Guenther <rguenther@suse.de>
* tree-flow.h (array_at_struct_end_p): Move declaration ...
* tree.h (array_at_struct_end_p): ... here.
* tree-ssa-loop-niter.c (array_at_struct_end_p): Move ...
* expr.c (array_at_struct_end_p): ... here. Rewrite.
2012-04-17 Steven Bosscher <steven@gcc.gnu.org>
* stmt.c (cost_table_, use_cost_table, cost_table_initialize,
......
......@@ -6778,6 +6778,43 @@ array_ref_low_bound (tree exp)
return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0);
}
/* Returns true if REF is an array reference to an array at the end of
a structure. If this is the case, the array may be allocated larger
than its upper bound implies. */
bool
array_at_struct_end_p (tree ref)
{
if (TREE_CODE (ref) != ARRAY_REF
&& TREE_CODE (ref) != ARRAY_RANGE_REF)
return false;
while (handled_component_p (ref))
{
/* If the reference chain contains a component reference to a
non-union type and there follows another field the reference
is not at the end of a structure. */
if (TREE_CODE (ref) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
{
tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1));
while (nextf && TREE_CODE (nextf) != FIELD_DECL)
nextf = DECL_CHAIN (nextf);
if (nextf)
return false;
}
ref = TREE_OPERAND (ref, 0);
}
/* If the reference is based on a declared entity, the size of the array
is constrained by its given domain. */
if (DECL_P (ref))
return false;
return true;
}
/* Return a tree representing the upper bound of the array mentioned in
EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
......
......@@ -686,7 +686,6 @@ tree find_loop_niter (struct loop *, edge *);
tree loop_niter_by_eval (struct loop *, edge);
tree find_loop_niter_by_eval (struct loop *, edge *);
void estimate_numbers_of_iterations (bool);
bool array_at_struct_end_p (tree);
bool scev_probably_wraps_p (tree, tree, gimple, struct loop *, bool);
bool convert_affine_scev (struct loop *, tree, tree *, tree *, gimple, bool);
......
......@@ -2640,47 +2640,6 @@ record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple stmt,
record_estimate (loop, niter_bound, max, stmt, false, realistic, upper);
}
/* Returns true if REF is a reference to an array at the end of a dynamically
allocated structure. If this is the case, the array may be allocated larger
than its upper bound implies. */
bool
array_at_struct_end_p (tree ref)
{
tree base = get_base_address (ref);
tree parent, field;
/* Unless the reference is through a pointer, the size of the array matches
its declaration. */
if (!base || (!INDIRECT_REF_P (base) && TREE_CODE (base) != MEM_REF))
return false;
for (;handled_component_p (ref); ref = parent)
{
parent = TREE_OPERAND (ref, 0);
if (TREE_CODE (ref) == COMPONENT_REF)
{
/* All fields of a union are at its end. */
if (TREE_CODE (TREE_TYPE (parent)) == UNION_TYPE)
continue;
/* Unless the field is at the end of the struct, we are done. */
field = TREE_OPERAND (ref, 1);
if (DECL_CHAIN (field))
return false;
}
/* The other options are ARRAY_REF, ARRAY_RANGE_REF, VIEW_CONVERT_EXPR.
In all these cases, we might be accessing the last element, and
although in practice this will probably never happen, it is legal for
the indices of this last element to exceed the bounds of the array.
Therefore, continue checking. */
}
return true;
}
/* Determine information about number of iterations a LOOP from the index
IDX of a data reference accessed in STMT. RELIABLE is true if STMT is
guaranteed to be executed in every iteration of LOOP. Callback for
......
......@@ -5068,6 +5068,8 @@ extern bool contains_packed_reference (const_tree exp);
extern tree array_ref_element_size (tree);
bool array_at_struct_end_p (tree);
/* Return a tree representing the lower bound of the array mentioned in
EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment