Commit 2f4675b4 by Zdenek Dvorak Committed by Zdenek Dvorak

fold-const.c (fold): Fold difference of addresses.

	* fold-const.c (fold): Fold difference of addresses.
	(ptr_difference_const): Moved from tree-ssa-loop-ivopts, based on
	get_inner_reference.
	* tree-ssa-loop-ivopts.c (peel_address): Removed.
	(ptr_difference_const): Moved to fold-const.c.
	(split_address_cost): Use get_inner_reference instead of peel_address.
	(ptr_difference_cost): Change type of diff to HOST_WIDE_INT.
	* tree.h (ptr_difference_const): Export.

	* tree-ssa-loop-ivopts.c (dump_iv, dump_use, dump_cand): Add induction
	variable type to the dump.  Fix indentation.
	(idx_find_step): Handle nonconstant array_ref_element_size and
	array_ref_low_bound.
	(idx_record_use): Handle array_ref_element_size and
	array_ref_low_bound.
	(find_interesting_uses_stmt): Handle memory = nontrivial_expression
	statements correctly.
	(get_computation_at, iv_value): Do not unshare expressions here.
	(rewrite_use_outer): Unshare the expression before it is emitted
	to code.
	* tree-ssa-loop-niter.c (unsigned_type_for, signed_type_for):
	Moved to tree.c.
	* tree.c (unsigned_type_for, signed_type_for): Moved from
	tree-ssa-loop-niter.c.  Use langhooks.
	* tree.h (signed_type_for): Export.

From-SVN: r87601
parent 9c763d19
2004-09-16 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* fold-const.c (fold): Fold difference of addresses.
(ptr_difference_const): Moved from tree-ssa-loop-ivopts, based on
get_inner_reference.
* tree-ssa-loop-ivopts.c (peel_address): Removed.
(ptr_difference_const): Moved to fold-const.c.
(split_address_cost): Use get_inner_reference instead of peel_address.
(ptr_difference_cost): Change type of diff to HOST_WIDE_INT.
* tree.h (ptr_difference_const): Export.
* tree-ssa-loop-ivopts.c (dump_iv, dump_use, dump_cand): Add induction
variable type to the dump. Fix indentation.
(idx_find_step): Handle nonconstant array_ref_element_size and
array_ref_low_bound.
(idx_record_use): Handle array_ref_element_size and
array_ref_low_bound.
(find_interesting_uses_stmt): Handle memory = nontrivial_expression
statements correctly.
(get_computation_at, iv_value): Do not unshare expressions here.
(rewrite_use_outer): Unshare the expression before it is emitted
to code.
* tree-ssa-loop-niter.c (unsigned_type_for, signed_type_for):
Moved to tree.c.
* tree.c (unsigned_type_for, signed_type_for): Moved from
tree-ssa-loop-niter.c. Use langhooks.
* tree.h (signed_type_for): Export.
2004-09-16 David Edelsohn <edelsohn@gnu.org>
* config/rs6000/rs6000.c (rs6000_xcoff_asm_named_section): Update
......
......@@ -6966,6 +6966,18 @@ fold (tree expr)
|| (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv)))
return fold (build2 (PLUS_EXPR, type, arg0, negate_expr (arg1)));
/* Try folding difference of addresses. */
{
HOST_WIDE_INT diff;
if (TREE_CODE (arg0) == ADDR_EXPR
&& TREE_CODE (arg1) == ADDR_EXPR
&& ptr_difference_const (TREE_OPERAND (arg0, 0),
TREE_OPERAND (arg1, 0),
&diff))
return build_int_cst_type (type, diff);
}
if (TREE_CODE (arg0) == MULT_EXPR
&& TREE_CODE (arg1) == MULT_EXPR
&& (INTEGRAL_TYPE_P (type) || flag_unsafe_math_optimizations))
......@@ -10668,3 +10680,51 @@ round_down (tree value, int divisor)
return value;
}
/* Returns true if addresses of E1 and E2 differ by a constant, false
otherwise. If they do, &E1 - &E2 is stored in *DIFF. */
bool
ptr_difference_const (tree e1, tree e2, HOST_WIDE_INT *diff)
{
tree core1, core2;
HOST_WIDE_INT bitsize1, bitsize2;
HOST_WIDE_INT bitpos1, bitpos2;
tree toffset1, toffset2, tdiff, type;
enum machine_mode mode1, mode2;
int unsignedp1, unsignedp2, volatilep1, volatilep2;
core1 = get_inner_reference (e1, &bitsize1, &bitpos1, &toffset1, &mode1,
&unsignedp1, &volatilep1);
core2 = get_inner_reference (e2, &bitsize2, &bitpos2, &toffset2, &mode2,
&unsignedp2, &volatilep2);
if (bitpos1 % BITS_PER_UNIT != 0
|| bitpos2 % BITS_PER_UNIT != 0
|| !operand_equal_p (core1, core2, 0))
return false;
if (toffset1 && toffset2)
{
type = TREE_TYPE (toffset1);
if (type != TREE_TYPE (toffset2))
toffset2 = fold_convert (type, toffset2);
tdiff = fold (build2 (MINUS_EXPR, type, toffset1, toffset2));
if (!host_integerp (tdiff, 0))
return false;
*diff = tree_low_cst (tdiff, 0);
}
else if (toffset1 || toffset2)
{
/* If only one of the offsets is non-constant, the difference cannot
be a constant. */
return false;
}
else
*diff = 0;
*diff += (bitpos1 - bitpos2) / BITS_PER_UNIT;
return true;
}
......@@ -84,22 +84,6 @@ inverse (tree x, tree mask)
return rslt;
}
/* Returns unsigned variant of TYPE. */
tree
unsigned_type_for (tree type)
{
return make_unsigned_type (TYPE_PRECISION (type));
}
/* Returns signed variant of TYPE. */
static tree
signed_type_for (tree type)
{
return make_signed_type (TYPE_PRECISION (type));
}
/* Determine the number of iterations according to condition (for staying
inside loop) which compares two induction variables using comparison
operator CODE. The induction variable on left side of the comparison
......
......@@ -5866,4 +5866,20 @@ tree_fold_gcd (tree a, tree b)
}
}
/* Returns unsigned variant of TYPE. */
tree
unsigned_type_for (tree type)
{
return lang_hooks.types.unsigned_type (type);
}
/* Returns signed variant of TYPE. */
tree
signed_type_for (tree type)
{
return lang_hooks.types.signed_type (type);
}
#include "gt-tree.h"
......@@ -2792,6 +2792,7 @@ extern tree build_empty_stmt (void);
extern tree make_signed_type (int);
extern tree make_unsigned_type (int);
extern tree signed_type_for (tree);
extern tree unsigned_type_for (tree);
extern void initialize_sizetypes (bool);
extern void set_sizetype (tree);
......@@ -3464,6 +3465,8 @@ extern tree constant_boolean_node (int, tree);
extern bool tree_swap_operands_p (tree, tree, bool);
extern enum tree_code swap_tree_comparison (enum tree_code);
extern bool ptr_difference_const (tree, tree, HOST_WIDE_INT *);
/* In builtins.c */
extern tree fold_builtin (tree, bool);
extern tree fold_builtin_fputs (tree, bool, bool, 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