Commit 11fc4275 by Eric Botcazou Committed by Eric Botcazou

tree.c (range_in_array_bounds_p): New predicate.

	* tree.c (range_in_array_bounds_p): New predicate.
	* tree.h (range_in_array_bounds_p): Declare it.
	* tree-eh.c (tree_could_trap_p) <ARRAY_RANGE_REF>: Use it to
	return a less conservative answer.
	* tree-sra.c (struct sra_elt): Add new pointer field 'groups'
	and flag 'is_group'.
	(IS_ELEMENT_FOR_GROUP): New macro.
	(FOR_EACH_ACTUAL_CHILD): Likewise.
	(next_child_for_group): New helper function.
	(can_completely_scalarize_p): Take into account groups.
	(sra_hash_tree): Handle RANGE_EXPR.
	(sra_elt_eq): Likewise.
	(lookup_element): Be prepared for handling groups.
	(is_valid_const_index): Delete.
	(maybe_lookup_element_for_expr) <ARRAY_REF>: Use in_array_bounds_p
	instead of is_valid_const_index.
	<ARRAY_RANGE_REF>: New case.
	(sra_walk_expr) <ARRAY_REF>: Use in_array_bounds_p instead of
	is_valid_const_index.
	<ARRAY_RANGE_REF>: Do not unconditionally punt.
	(scan_dump): Dump info for groups too.
	(decide_instantiation_1): Likewise.
	(decide_block_copy): Assert that the element is not a group.
	Propagate decision to groups.
	(generate_one_element_ref): Handle RANGE_EXPR.
	(mark_no_warning): Iterate over actual childs.
	(generate_copy_inout): Likewise.
	(generate_element_copy): Likewise.
	(generate_element_zero): Likewise.
	(generate_element_init_1): Likewise.
	(dump_sra_elt_name): Handle RANGE_EXPR.

From-SVN: r115160
parent 2da7ea25
2006-07-03 Eric Botcazou <ebotcazou@adacore.com>
* tree.c (range_in_array_bounds_p): New predicate.
* tree.h (range_in_array_bounds_p): Declare it.
* tree-eh.c (tree_could_trap_p) <ARRAY_RANGE_REF>: Use it to
return a less conservative answer.
* tree-sra.c (struct sra_elt): Add new pointer field 'groups'
and flag 'is_group'.
(IS_ELEMENT_FOR_GROUP): New macro.
(FOR_EACH_ACTUAL_CHILD): Likewise.
(next_child_for_group): New helper function.
(can_completely_scalarize_p): Take into account groups.
(sra_hash_tree): Handle RANGE_EXPR.
(sra_elt_eq): Likewise.
(lookup_element): Be prepared for handling groups.
(is_valid_const_index): Delete.
(maybe_lookup_element_for_expr) <ARRAY_REF>: Use in_array_bounds_p
instead of is_valid_const_index.
<ARRAY_RANGE_REF>: New case.
(sra_walk_expr) <ARRAY_REF>: Use in_array_bounds_p instead of
is_valid_const_index.
<ARRAY_RANGE_REF>: Do not unconditionally punt.
(scan_dump): Dump info for groups too.
(decide_instantiation_1): Likewise.
(decide_block_copy): Assert that the element is not a group.
Propagate decision to groups.
(generate_one_element_ref): Handle RANGE_EXPR.
(mark_no_warning): Iterate over actual childs.
(generate_copy_inout): Likewise.
(generate_element_copy): Likewise.
(generate_element_zero): Likewise.
(generate_element_init_1): Likewise.
(dump_sra_elt_name): Handle RANGE_EXPR.
2006-07-03 Roger Sayle <roger@eyesopen.com>
PR tree-optimization/26251
......
2006-07-03 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/gnat.dg/string_slice.adb: New test.
2006-07-01 Tobias Schlter <tobias.schlueter@physik.uni-muenchen.de>
PR fortran/19259
-- { dg-do run }
-- { dg-options "-O" }
procedure string_slice is
subtype Key_T is String (1 .. 3);
function One_Xkey return Key_T is
Key : Key_T := "XXX";
begin
Key (1 .. 2) := "__";
return Key;
end;
Key : Key_T := One_Xkey;
begin
if Key (3) /= 'X' then
raise Program_Error;
end if;
end;
......@@ -1889,13 +1889,14 @@ tree_could_trap_p (tree expr)
goto restart;
case ARRAY_RANGE_REF:
/* Let us be conservative here for now. We might be checking bounds of
the access similarly to the case below. */
if (!TREE_THIS_NOTRAP (expr))
base = TREE_OPERAND (expr, 0);
if (tree_could_trap_p (base))
return true;
base = TREE_OPERAND (expr, 0);
return tree_could_trap_p (base);
if (TREE_THIS_NOTRAP (expr))
return false;
return !range_in_array_bounds_p (expr);
case ARRAY_REF:
base = TREE_OPERAND (expr, 0);
......
......@@ -6892,6 +6892,39 @@ in_array_bounds_p (tree ref)
return true;
}
/* Returns true if it is possible to prove that the range of
an array access REF (an ARRAY_RANGE_REF expression) falls
into the array bounds. */
bool
range_in_array_bounds_p (tree ref)
{
tree domain_type = TYPE_DOMAIN (TREE_TYPE (ref));
tree range_min, range_max, min, max;
range_min = TYPE_MIN_VALUE (domain_type);
range_max = TYPE_MAX_VALUE (domain_type);
if (!range_min
|| !range_max
|| TREE_CODE (range_min) != INTEGER_CST
|| TREE_CODE (range_max) != INTEGER_CST)
return false;
min = array_ref_low_bound (ref);
max = array_ref_up_bound (ref);
if (!min
|| !max
|| TREE_CODE (min) != INTEGER_CST
|| TREE_CODE (max) != INTEGER_CST)
return false;
if (tree_int_cst_lt (range_min, min)
|| tree_int_cst_lt (max, range_max))
return false;
return true;
}
/* Return true if T (assumed to be a DECL) is a global variable. */
bool
......
......@@ -3576,6 +3576,7 @@ extern tree build_complex_type (tree);
extern tree build_resx (int);
extern tree array_type_nelts (tree);
extern bool in_array_bounds_p (tree);
extern bool range_in_array_bounds_p (tree);
extern tree value_member (tree, tree);
extern tree purpose_member (tree, tree);
......
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