double-int.h (double_int_setbit): Declare.

* double-int.h (double_int_setbit): Declare.
	* double-int.c (double_int_setbit): New function.
	* rtl.h (immed_double_int_const): Declare.
	* emit-rtl.c (immed_double_int_const): New function.
	* builtins.c (expand_builtin_signbit): Clean up, use double_int_*
	and immed_double_int_const functions.
	* optabs.c (expand_absneg_bit, expand_copysign_absneg,
	expand_copysign_bit):  (Ditto.).
	* simplify-rtx.c (simplify_binary_operation_1): (Ditto.).
	* tree-ssa-address.c (addr_for_mem_ref): (Ditto.).
	* dojump.c (prefer_and_bit_test): (Ditto.).
	* expr.c (convert_modes, reduce_to_bit_field_precision,
	const_vector_from_tree): (Ditto.).
	* expmed.c (mask_rtx, lshift_value): (Ditto.).

From-SVN: r158566
This commit is contained in:
Anatoly Sokolov 2010-04-20 20:33:46 +04:00 committed by Anatoly Sokolov
parent e4ba7a600e
commit 54fb1ae03e
12 changed files with 110 additions and 123 deletions

View File

@ -1,3 +1,20 @@
2010-04-20 Anatoly Sokolov <aesok@post.ru
* double-int.h (double_int_setbit): Declare.
* double-int.c (double_int_setbit): New function.
* rtl.h (immed_double_int_const): Declare.
* emit-rtl.c (immed_double_int_const): New function.
* builtins.c (expand_builtin_signbit): Clean up, use double_int_*
and immed_double_int_const functions.
* optabs.c (expand_absneg_bit, expand_copysign_absneg,
expand_copysign_bit): (Ditto.).
* simplify-rtx.c (simplify_binary_operation_1): (Ditto.).
* tree-ssa-address.c (addr_for_mem_ref): (Ditto.).
* dojump.c (prefer_and_bit_test): (Ditto.).
* expr.c (convert_modes, reduce_to_bit_field_precision,
const_vector_from_tree): (Ditto.).
* expmed.c (mask_rtx, lshift_value): (Ditto.).
2010-04-20 Jan Hubicka <jh@suse.cz>
* cgraph.c (cgraph_remove_node): Kill bodies in other partitoin.

View File

@ -5279,7 +5279,6 @@ expand_builtin_signbit (tree exp, rtx target)
{
const struct real_format *fmt;
enum machine_mode fmode, imode, rmode;
HOST_WIDE_INT hi, lo;
tree arg;
int word, bitpos;
enum insn_code icode;
@ -5355,21 +5354,12 @@ expand_builtin_signbit (tree exp, rtx target)
if (bitpos < GET_MODE_BITSIZE (rmode))
{
if (bitpos < HOST_BITS_PER_WIDE_INT)
{
hi = 0;
lo = (HOST_WIDE_INT) 1 << bitpos;
}
else
{
hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
lo = 0;
}
double_int mask = double_int_setbit (double_int_zero, bitpos);
if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
temp = gen_lowpart (rmode, temp);
temp = expand_binop (rmode, and_optab, temp,
immed_double_const (lo, hi, rmode),
immed_double_int_const (mask, rmode),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
}
else

View File

@ -163,7 +163,8 @@ prefer_and_bit_test (enum machine_mode mode, int bitnum)
/* Fill in the integers. */
XEXP (and_test, 1)
= immed_double_const ((unsigned HOST_WIDE_INT) 1 << bitnum, 0, mode);
= immed_double_int_const (double_int_setbit (double_int_zero, bitnum),
mode);
XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
return (rtx_cost (and_test, IF_THEN_ELSE, optimize_insn_for_speed_p ())

View File

@ -1013,6 +1013,18 @@ double_int_umod (double_int a, double_int b, unsigned code)
return double_int_mod (a, b, true, code);
}
/* Set BITPOS bit in A. */
double_int
double_int_setbit (double_int a, unsigned bitpos)
{
if (bitpos < HOST_BITS_PER_WIDE_INT)
a.low |= (unsigned HOST_WIDE_INT) 1 << bitpos;
else
a.high |= (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
return a;
}
/* Shift A left by COUNT places keeping only PREC bits of result. Shift
right if COUNT is negative. ARITH true specifies arithmetic shifting;
otherwise use logical shift. */

View File

@ -130,6 +130,7 @@ double_int double_int_umod (double_int, double_int, unsigned);
double_int double_int_divmod (double_int, double_int, bool, unsigned, double_int *);
double_int double_int_sdivmod (double_int, double_int, unsigned, double_int *);
double_int double_int_udivmod (double_int, double_int, unsigned, double_int *);
double_int double_int_setbit (double_int, unsigned);
/* Logical operations. */
static inline double_int

View File

@ -1,6 +1,7 @@
/* Emit RTL for the GCC expander.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010
Free Software Foundation, Inc.
This file is part of GCC.
@ -517,6 +518,15 @@ const_fixed_from_fixed_value (FIXED_VALUE_TYPE value, enum machine_mode mode)
return lookup_const_fixed (fixed);
}
/* Return a CONST_DOUBLE or CONST_INT for a value specified as
a double_int. */
rtx
immed_double_int_const (double_int i, enum machine_mode mode)
{
return immed_double_const (i.low, i.high, mode);
}
/* Return a CONST_DOUBLE or CONST_INT for a value specified as a pair
of ints: I0 is the low-order word and I1 is the high-order word.
Do not use this routine for non-integer modes; convert to

View File

@ -1847,7 +1847,7 @@ mask_rtx (enum machine_mode mode, int bitpos, int bitsize, int complement)
if (complement)
mask = double_int_not (mask);
return immed_double_const (mask.low, mask.high, mode);
return immed_double_int_const (mask, mode);
}
/* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value
@ -1861,7 +1861,7 @@ lshift_value (enum machine_mode mode, rtx value, int bitpos, int bitsize)
val = double_int_zext (uhwi_to_double_int (INTVAL (value)), bitsize);
val = double_int_lshift (val, bitpos, HOST_BITS_PER_DOUBLE_INT, false);
return immed_double_const (val.low, val.high, mode);
return immed_double_int_const (val, mode);
}
/* Extract a bit field that is split across two words

View File

@ -774,18 +774,13 @@ convert_modes (enum machine_mode mode, enum machine_mode oldmode, rtx x, int uns
&& GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT
&& CONST_INT_P (x) && INTVAL (x) < 0)
{
HOST_WIDE_INT val = INTVAL (x);
double_int val = uhwi_to_double_int (INTVAL (x));
if (oldmode != VOIDmode
&& HOST_BITS_PER_WIDE_INT > GET_MODE_BITSIZE (oldmode))
{
int width = GET_MODE_BITSIZE (oldmode);
/* We need to zero extend VAL. */
if (oldmode != VOIDmode)
val = double_int_zext (val, GET_MODE_BITSIZE (oldmode));
/* We need to zero extend VAL. */
val &= ((HOST_WIDE_INT) 1 << width) - 1;
}
return immed_double_const (val, (HOST_WIDE_INT) 0, mode);
return immed_double_int_const (val, mode);
}
/* We can do this with a gen_lowpart if both desired and current modes
@ -9686,15 +9681,8 @@ reduce_to_bit_field_precision (rtx exp, rtx target, tree type)
}
else if (TYPE_UNSIGNED (type))
{
rtx mask;
if (prec < HOST_BITS_PER_WIDE_INT)
mask = immed_double_const (((unsigned HOST_WIDE_INT) 1 << prec) - 1, 0,
GET_MODE (exp));
else
mask = immed_double_const ((unsigned HOST_WIDE_INT) -1,
((unsigned HOST_WIDE_INT) 1
<< (prec - HOST_BITS_PER_WIDE_INT)) - 1,
GET_MODE (exp));
rtx mask = immed_double_int_const (double_int_mask (prec),
GET_MODE (exp));
return expand_and (GET_MODE (exp), exp, mask, target);
}
else
@ -10280,9 +10268,8 @@ const_vector_from_tree (tree exp)
RTVEC_ELT (v, i) = CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt),
inner);
else
RTVEC_ELT (v, i) = immed_double_const (TREE_INT_CST_LOW (elt),
TREE_INT_CST_HIGH (elt),
inner);
RTVEC_ELT (v, i) = immed_double_int_const (tree_to_double_int (elt),
inner);
}
/* Initialize remaining elements to 0. */

View File

@ -2928,7 +2928,7 @@ expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
const struct real_format *fmt;
int bitpos, word, nwords, i;
enum machine_mode imode;
HOST_WIDE_INT hi, lo;
double_int mask;
rtx temp, insns;
/* The format has to have a simple sign bit. */
@ -2964,18 +2964,9 @@ expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
}
if (bitpos < HOST_BITS_PER_WIDE_INT)
{
hi = 0;
lo = (HOST_WIDE_INT) 1 << bitpos;
}
else
{
hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
lo = 0;
}
mask = double_int_setbit (double_int_zero, bitpos);
if (code == ABS)
lo = ~lo, hi = ~hi;
mask = double_int_not (mask);
if (target == 0 || target == op0)
target = gen_reg_rtx (mode);
@ -2993,7 +2984,7 @@ expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
{
temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
op0_piece,
immed_double_const (lo, hi, imode),
immed_double_int_const (mask, imode),
targ_piece, 1, OPTAB_LIB_WIDEN);
if (temp != targ_piece)
emit_move_insn (targ_piece, temp);
@ -3011,7 +3002,7 @@ expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
{
temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
gen_lowpart (imode, op0),
immed_double_const (lo, hi, imode),
immed_double_int_const (mask, imode),
gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
target = lowpart_subreg_maybe_copy (mode, temp, imode);
@ -3562,7 +3553,7 @@ expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
}
else
{
HOST_WIDE_INT hi, lo;
double_int mask;
if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
{
@ -3584,20 +3575,10 @@ expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
op1 = operand_subword_force (op1, word, mode);
}
if (bitpos < HOST_BITS_PER_WIDE_INT)
{
hi = 0;
lo = (HOST_WIDE_INT) 1 << bitpos;
}
else
{
hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
lo = 0;
}
mask = double_int_setbit (double_int_zero, bitpos);
sign = gen_reg_rtx (imode);
sign = expand_binop (imode, and_optab, op1,
immed_double_const (lo, hi, imode),
immed_double_int_const (mask, imode),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
}
@ -3641,7 +3622,7 @@ expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
int bitpos, bool op0_is_abs)
{
enum machine_mode imode;
HOST_WIDE_INT hi, lo;
double_int mask;
int word, nwords, i;
rtx temp, insns;
@ -3665,16 +3646,7 @@ expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
}
if (bitpos < HOST_BITS_PER_WIDE_INT)
{
hi = 0;
lo = (HOST_WIDE_INT) 1 << bitpos;
}
else
{
hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
lo = 0;
}
mask = double_int_setbit (double_int_zero, bitpos);
if (target == 0 || target == op0 || target == op1)
target = gen_reg_rtx (mode);
@ -3691,13 +3663,15 @@ expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
if (i == word)
{
if (!op0_is_abs)
op0_piece = expand_binop (imode, and_optab, op0_piece,
immed_double_const (~lo, ~hi, imode),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
op0_piece
= expand_binop (imode, and_optab, op0_piece,
immed_double_int_const (double_int_not (mask),
imode),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
op1 = expand_binop (imode, and_optab,
operand_subword_force (op1, i, mode),
immed_double_const (lo, hi, imode),
immed_double_int_const (mask, imode),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
temp = expand_binop (imode, ior_optab, op0_piece, op1,
@ -3717,13 +3691,14 @@ expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
else
{
op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
immed_double_const (lo, hi, imode),
immed_double_int_const (mask, imode),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
op0 = gen_lowpart (imode, op0);
if (!op0_is_abs)
op0 = expand_binop (imode, and_optab, op0,
immed_double_const (~lo, ~hi, imode),
immed_double_int_const (double_int_not (mask),
imode),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
temp = expand_binop (imode, ior_optab, op0, op1,

View File

@ -1627,6 +1627,7 @@ extern void start_sequence (void);
extern void push_to_sequence (rtx);
extern void push_to_sequence2 (rtx, rtx);
extern void end_sequence (void);
extern rtx immed_double_int_const (double_int, enum machine_mode);
extern rtx immed_double_const (HOST_WIDE_INT, HOST_WIDE_INT,
enum machine_mode);

View File

@ -1770,44 +1770,42 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
if (SCALAR_INT_MODE_P (mode))
{
HOST_WIDE_INT coeff0h = 0, coeff1h = 0;
unsigned HOST_WIDE_INT coeff0l = 1, coeff1l = 1;
double_int coeff0, coeff1;
rtx lhs = op0, rhs = op1;
coeff0 = double_int_one;
coeff1 = double_int_one;
if (GET_CODE (lhs) == NEG)
{
coeff0l = -1;
coeff0h = -1;
coeff0 = double_int_minus_one;
lhs = XEXP (lhs, 0);
}
else if (GET_CODE (lhs) == MULT
&& CONST_INT_P (XEXP (lhs, 1)))
{
coeff0l = INTVAL (XEXP (lhs, 1));
coeff0h = INTVAL (XEXP (lhs, 1)) < 0 ? -1 : 0;
coeff0 = shwi_to_double_int (INTVAL (XEXP (lhs, 1)));
lhs = XEXP (lhs, 0);
}
else if (GET_CODE (lhs) == ASHIFT
&& CONST_INT_P (XEXP (lhs, 1))
&& INTVAL (XEXP (lhs, 1)) >= 0
&& INTVAL (XEXP (lhs, 1)) >= 0
&& INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
{
coeff0l = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
coeff0h = 0;
coeff0 = double_int_setbit (double_int_zero,
INTVAL (XEXP (lhs, 1)));
lhs = XEXP (lhs, 0);
}
if (GET_CODE (rhs) == NEG)
{
coeff1l = -1;
coeff1h = -1;
coeff1 = double_int_minus_one;
rhs = XEXP (rhs, 0);
}
else if (GET_CODE (rhs) == MULT
&& CONST_INT_P (XEXP (rhs, 1)))
{
coeff1l = INTVAL (XEXP (rhs, 1));
coeff1h = INTVAL (XEXP (rhs, 1)) < 0 ? -1 : 0;
coeff1 = shwi_to_double_int (INTVAL (XEXP (rhs, 1)));
rhs = XEXP (rhs, 0);
}
else if (GET_CODE (rhs) == ASHIFT
@ -1815,8 +1813,8 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
&& INTVAL (XEXP (rhs, 1)) >= 0
&& INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
{
coeff1l = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
coeff1h = 0;
coeff1 = double_int_setbit (double_int_zero,
INTVAL (XEXP (rhs, 1)));
rhs = XEXP (rhs, 0);
}
@ -1824,12 +1822,11 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
{
rtx orig = gen_rtx_PLUS (mode, op0, op1);
rtx coeff;
unsigned HOST_WIDE_INT l;
HOST_WIDE_INT h;
double_int val;
bool speed = optimize_function_for_speed_p (cfun);
add_double (coeff0l, coeff0h, coeff1l, coeff1h, &l, &h);
coeff = immed_double_const (l, h, mode);
val = double_int_add (coeff0, coeff1);
coeff = immed_double_int_const (val, mode);
tem = simplify_gen_binary (MULT, mode, lhs, coeff);
return rtx_cost (tem, SET, speed) <= rtx_cost (orig, SET, speed)
@ -1953,21 +1950,21 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
if (SCALAR_INT_MODE_P (mode))
{
HOST_WIDE_INT coeff0h = 0, negcoeff1h = -1;
unsigned HOST_WIDE_INT coeff0l = 1, negcoeff1l = -1;
double_int coeff0, negcoeff1;
rtx lhs = op0, rhs = op1;
coeff0 = double_int_one;
negcoeff1 = double_int_minus_one;
if (GET_CODE (lhs) == NEG)
{
coeff0l = -1;
coeff0h = -1;
coeff0 = double_int_minus_one;
lhs = XEXP (lhs, 0);
}
else if (GET_CODE (lhs) == MULT
&& CONST_INT_P (XEXP (lhs, 1)))
{
coeff0l = INTVAL (XEXP (lhs, 1));
coeff0h = INTVAL (XEXP (lhs, 1)) < 0 ? -1 : 0;
coeff0 = shwi_to_double_int (INTVAL (XEXP (lhs, 1)));
lhs = XEXP (lhs, 0);
}
else if (GET_CODE (lhs) == ASHIFT
@ -1975,22 +1972,20 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
&& INTVAL (XEXP (lhs, 1)) >= 0
&& INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
{
coeff0l = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
coeff0h = 0;
coeff0 = double_int_setbit (double_int_zero,
INTVAL (XEXP (lhs, 1)));
lhs = XEXP (lhs, 0);
}
if (GET_CODE (rhs) == NEG)
{
negcoeff1l = 1;
negcoeff1h = 0;
negcoeff1 = double_int_one;
rhs = XEXP (rhs, 0);
}
else if (GET_CODE (rhs) == MULT
&& CONST_INT_P (XEXP (rhs, 1)))
{
negcoeff1l = -INTVAL (XEXP (rhs, 1));
negcoeff1h = INTVAL (XEXP (rhs, 1)) <= 0 ? 0 : -1;
negcoeff1 = shwi_to_double_int (-INTVAL (XEXP (rhs, 1)));
rhs = XEXP (rhs, 0);
}
else if (GET_CODE (rhs) == ASHIFT
@ -1998,8 +1993,9 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
&& INTVAL (XEXP (rhs, 1)) >= 0
&& INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
{
negcoeff1l = -(((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1)));
negcoeff1h = -1;
negcoeff1 = double_int_setbit (double_int_zero,
INTVAL (XEXP (rhs, 1)));
negcoeff1 = double_int_neg (negcoeff1);
rhs = XEXP (rhs, 0);
}
@ -2007,12 +2003,11 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
{
rtx orig = gen_rtx_MINUS (mode, op0, op1);
rtx coeff;
unsigned HOST_WIDE_INT l;
HOST_WIDE_INT h;
double_int val;
bool speed = optimize_function_for_speed_p (cfun);
add_double (coeff0l, coeff0h, negcoeff1l, negcoeff1h, &l, &h);
coeff = immed_double_const (l, h, mode);
val = double_int_add (coeff0, negcoeff1);
coeff = immed_double_int_const (val, mode);
tem = simplify_gen_binary (MULT, mode, lhs, coeff);
return rtx_cost (tem, SET, speed) <= rtx_cost (orig, SET, speed)

View File

@ -192,14 +192,12 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
struct mem_addr_template *templ;
if (addr->step && !integer_onep (addr->step))
st = immed_double_const (TREE_INT_CST_LOW (addr->step),
TREE_INT_CST_HIGH (addr->step), address_mode);
st = immed_double_int_const (tree_to_double_int (addr->step), address_mode);
else
st = NULL_RTX;
if (addr->offset && !integer_zerop (addr->offset))
off = immed_double_const (TREE_INT_CST_LOW (addr->offset),
TREE_INT_CST_HIGH (addr->offset), address_mode);
off = immed_double_int_const (tree_to_double_int (addr->offset), address_mode);
else
off = NULL_RTX;