mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-05 13:20:12 +08:00
expmed.c (const_mult_add_overflow_p): New.
* expmed.c (const_mult_add_overflow_p): New. * expr.h: Declare it. * loop.c (maybe_eliminate_biv_1) [COMPARE]: Use it. Don't eliminate the biv if the giv has a constant multiplier and the rhs argument of the comparison does satisfy the predicate. Use expand_mult_add to compute the replacement constant. From-SVN: r54075
This commit is contained in:
parent
d18b1ed89e
commit
ce60bf25b2
@ -1,3 +1,12 @@
|
||||
2002-05-30 Eric Botcazou <ebotcazou@multimania.com>
|
||||
|
||||
* expmed.c (const_mult_add_overflow_p): New.
|
||||
* expr.h: Declare it.
|
||||
* loop.c (maybe_eliminate_biv_1) [COMPARE]: Use it.
|
||||
Don't eliminate the biv if the giv has a constant multiplier and
|
||||
the rhs argument of the comparison does satisfy the predicate.
|
||||
Use expand_mult_add to compute the replacement constant.
|
||||
|
||||
2002-05-30 Osku Salerma <osku@iki.fi>
|
||||
|
||||
* c-common.c (c_common_attribute_table): Add "may_alias" entry.
|
||||
|
38
gcc/expmed.c
38
gcc/expmed.c
@ -4156,6 +4156,44 @@ make_tree (type, x)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether the multiplication X * MULT + ADD overflows.
|
||||
X, MULT and ADD must be CONST_*.
|
||||
MODE is the machine mode for the computation.
|
||||
X and MULT must have mode MODE. ADD may have a different mode.
|
||||
So can X (defaults to same as MODE).
|
||||
UNSIGNEDP is non-zero to do unsigned multiplication. */
|
||||
|
||||
bool
|
||||
const_mult_add_overflow_p (x, mult, add, mode, unsignedp)
|
||||
rtx x, mult, add;
|
||||
enum machine_mode mode;
|
||||
int unsignedp;
|
||||
{
|
||||
tree type, mult_type, add_type, result;
|
||||
|
||||
type = (*lang_hooks.types.type_for_mode) (mode, unsignedp);
|
||||
|
||||
/* In order to get a proper overflow indication from an unsigned
|
||||
type, we have to pretend that it's a sizetype. */
|
||||
mult_type = type;
|
||||
if (unsignedp)
|
||||
{
|
||||
mult_type = copy_node (type);
|
||||
TYPE_IS_SIZETYPE (mult_type) = 1;
|
||||
}
|
||||
|
||||
add_type = (GET_MODE (add) == VOIDmode ? mult_type
|
||||
: (*lang_hooks.types.type_for_mode) (GET_MODE (add), unsignedp));
|
||||
|
||||
result = fold (build (PLUS_EXPR, mult_type,
|
||||
fold (build (MULT_EXPR, mult_type,
|
||||
make_tree (mult_type, x),
|
||||
make_tree (mult_type, mult))),
|
||||
make_tree (add_type, add)));
|
||||
|
||||
return TREE_CONSTANT_OVERFLOW (result);
|
||||
}
|
||||
|
||||
/* Return an rtx representing the value of X * MULT + ADD.
|
||||
TARGET is a suggestion for where to store the result (an rtx).
|
||||
MODE is the machine mode for the computation.
|
||||
|
@ -758,6 +758,7 @@ extern rtx extract_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
|
||||
enum machine_mode, enum machine_mode,
|
||||
HOST_WIDE_INT));
|
||||
extern rtx expand_mult PARAMS ((enum machine_mode, rtx, rtx, rtx, int));
|
||||
extern bool const_mult_add_overflow_p PARAMS ((rtx, rtx, rtx, enum machine_mode, int));
|
||||
extern rtx expand_mult_add PARAMS ((rtx, rtx, rtx, rtx,enum machine_mode, int));
|
||||
extern rtx expand_mult_highpart_adjust PARAMS ((enum machine_mode, rtx, rtx, rtx, rtx, int));
|
||||
|
||||
|
27
gcc/loop.c
27
gcc/loop.c
@ -8863,6 +8863,22 @@ maybe_eliminate_biv_1 (loop, x, insn, bl, eliminate_p, where_bb, where_insn)
|
||||
if (! biv_elimination_giv_has_0_offset (bl->biv, v, insn))
|
||||
continue;
|
||||
|
||||
/* Don't eliminate if the linear combination that makes up
|
||||
the giv overflows when it is applied to ARG. */
|
||||
if (GET_CODE (arg) == CONST_INT)
|
||||
{
|
||||
rtx add_val;
|
||||
|
||||
if (GET_CODE (v->add_val) == CONST_INT)
|
||||
add_val = v->add_val;
|
||||
else
|
||||
add_val = const0_rtx;
|
||||
|
||||
if (const_mult_add_overflow_p (arg, v->mult_val,
|
||||
add_val, mode, 1))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! eliminate_p)
|
||||
return 1;
|
||||
|
||||
@ -8873,13 +8889,10 @@ maybe_eliminate_biv_1 (loop, x, insn, bl, eliminate_p, where_bb, where_insn)
|
||||
the derived constant can be directly placed in the COMPARE,
|
||||
do so. */
|
||||
if (GET_CODE (arg) == CONST_INT
|
||||
&& GET_CODE (v->mult_val) == CONST_INT
|
||||
&& GET_CODE (v->add_val) == CONST_INT)
|
||||
{
|
||||
validate_change (insn, &XEXP (x, arg_operand),
|
||||
GEN_INT (INTVAL (arg)
|
||||
* INTVAL (v->mult_val)
|
||||
+ INTVAL (v->add_val)), 1);
|
||||
tem = expand_mult_add (arg, NULL_RTX, v->mult_val,
|
||||
v->add_val, mode, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -8888,8 +8901,10 @@ maybe_eliminate_biv_1 (loop, x, insn, bl, eliminate_p, where_bb, where_insn)
|
||||
loop_iv_add_mult_emit_before (loop, arg,
|
||||
v->mult_val, v->add_val,
|
||||
tem, where_bb, where_insn);
|
||||
validate_change (insn, &XEXP (x, arg_operand), tem, 1);
|
||||
}
|
||||
|
||||
validate_change (insn, &XEXP (x, arg_operand), tem, 1);
|
||||
|
||||
if (apply_change_group ())
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user