Allow MODE_PARTIAL_INT in expmed costs
From-SVN: r190050
This commit is contained in:
parent
92e014ca10
commit
91f8035e9b
3 changed files with 106 additions and 86 deletions
|
@ -1,3 +1,19 @@
|
|||
2012-08-01 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* expmed.h (NUM_MODE_PARTIAL_INT): New.
|
||||
(NUM_MODE_VECTOR_INT, NUM_MODE_IP_INT, NUM_MODE_IPV_INT): New.
|
||||
(struct expmed_op_cheap): Size one array on NUM_MODE_IPV_INT.
|
||||
(struct expmed_op_costs): Likewise.
|
||||
(struct target_expmed): Size x_convert_cost on NUM_MODE_IP_INT.
|
||||
(expmed_mode_index): New.
|
||||
(expmed_op_cheap_ptr, expmed_op_cost_ptr): Use expmed_mode_index.
|
||||
(convert_cost_ptr): Likewise.
|
||||
* expmed.c (struct init_expmed_rtl): Rename convert to trunc.
|
||||
(init_expmed_one_conv): Split out from ...
|
||||
(init_expmed_one_mode): ... here. Iterate conversions over
|
||||
partial integer modes too.
|
||||
(init_expmed): Iterate over partial integer modes too.
|
||||
|
||||
2012-08-01 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/m32c/m32c.c (TARGET_INIT_LIBFUNCS): Remove.
|
||||
|
|
90
gcc/expmed.c
90
gcc/expmed.c
|
@ -101,7 +101,6 @@ struct init_expmed_rtl
|
|||
struct rtx_def mult; rtunion mult_fld1;
|
||||
struct rtx_def sdiv; rtunion sdiv_fld1;
|
||||
struct rtx_def udiv; rtunion udiv_fld1;
|
||||
struct rtx_def zext;
|
||||
struct rtx_def sdiv_32; rtunion sdiv_32_fld1;
|
||||
struct rtx_def smod_32; rtunion smod_32_fld1;
|
||||
struct rtx_def wide_mult; rtunion wide_mult_fld1;
|
||||
|
@ -112,12 +111,35 @@ struct init_expmed_rtl
|
|||
struct rtx_def shift_add; rtunion shift_add_fld1;
|
||||
struct rtx_def shift_sub0; rtunion shift_sub0_fld1;
|
||||
struct rtx_def shift_sub1; rtunion shift_sub1_fld1;
|
||||
struct rtx_def convert;
|
||||
struct rtx_def zext;
|
||||
struct rtx_def trunc;
|
||||
|
||||
rtx pow2[MAX_BITS_PER_WORD];
|
||||
rtx cint[MAX_BITS_PER_WORD];
|
||||
};
|
||||
|
||||
static void
|
||||
init_expmed_one_conv (struct init_expmed_rtl *all, enum machine_mode to_mode,
|
||||
enum machine_mode from_mode, bool speed)
|
||||
{
|
||||
int to_size, from_size;
|
||||
rtx which;
|
||||
|
||||
/* We're given no information about the true size of a partial integer,
|
||||
only the size of the "full" integer it requires for storage. For
|
||||
comparison purposes here, reduce the bit size by one in that case. */
|
||||
to_size = (GET_MODE_BITSIZE (to_mode)
|
||||
- (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT));
|
||||
from_size = (GET_MODE_BITSIZE (from_mode)
|
||||
- (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT));
|
||||
|
||||
/* Assume cost of zero-extend and sign-extend is the same. */
|
||||
which = (to_size < from_size ? &all->trunc : &all->zext);
|
||||
|
||||
PUT_MODE (&all->reg, from_mode);
|
||||
set_convert_cost (to_mode, from_mode, speed, set_src_cost (which, speed));
|
||||
}
|
||||
|
||||
static void
|
||||
init_expmed_one_mode (struct init_expmed_rtl *all,
|
||||
enum machine_mode mode, int speed)
|
||||
|
@ -141,7 +163,8 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
|
|||
PUT_MODE (&all->shift_add, mode);
|
||||
PUT_MODE (&all->shift_sub0, mode);
|
||||
PUT_MODE (&all->shift_sub1, mode);
|
||||
PUT_MODE (&all->convert, mode);
|
||||
PUT_MODE (&all->zext, mode);
|
||||
PUT_MODE (&all->trunc, mode);
|
||||
|
||||
set_add_cost (speed, mode, set_src_cost (&all->plus, speed));
|
||||
set_neg_cost (speed, mode, set_src_cost (&all->neg, speed));
|
||||
|
@ -176,8 +199,13 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
|
|||
|
||||
if (SCALAR_INT_MODE_P (mode))
|
||||
{
|
||||
enum machine_mode wider_mode = GET_MODE_WIDER_MODE (mode);
|
||||
|
||||
for (mode_from = MIN_MODE_INT; mode_from <= MAX_MODE_INT;
|
||||
mode_from = (enum machine_mode)(mode_from + 1))
|
||||
init_expmed_one_conv (all, mode, mode_from, speed);
|
||||
}
|
||||
if (GET_MODE_CLASS (mode) == MODE_INT)
|
||||
{
|
||||
enum machine_mode wider_mode = GET_MODE_WIDER_MODE (mode);
|
||||
if (wider_mode != VOIDmode)
|
||||
{
|
||||
PUT_MODE (&all->zext, wider_mode);
|
||||
|
@ -185,33 +213,11 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
|
|||
PUT_MODE (&all->wide_lshr, wider_mode);
|
||||
XEXP (&all->wide_lshr, 1) = GEN_INT (mode_bitsize);
|
||||
|
||||
set_mul_widen_cost (speed, wider_mode, set_src_cost (&all->wide_mult, speed));
|
||||
set_mul_highpart_cost (speed, mode, set_src_cost (&all->wide_trunc, speed));
|
||||
set_mul_widen_cost (speed, wider_mode,
|
||||
set_src_cost (&all->wide_mult, speed));
|
||||
set_mul_highpart_cost (speed, mode,
|
||||
set_src_cost (&all->wide_trunc, speed));
|
||||
}
|
||||
|
||||
for (mode_from = GET_CLASS_NARROWEST_MODE (MODE_INT);
|
||||
mode_from != VOIDmode;
|
||||
mode_from = GET_MODE_WIDER_MODE (mode_from))
|
||||
if (mode != mode_from)
|
||||
{
|
||||
unsigned short size_to = GET_MODE_SIZE (mode);
|
||||
unsigned short size_from = GET_MODE_SIZE (mode_from);
|
||||
if (size_to < size_from)
|
||||
{
|
||||
PUT_CODE (&all->convert, TRUNCATE);
|
||||
PUT_MODE (&all->reg, mode_from);
|
||||
set_convert_cost (mode, mode_from, speed,
|
||||
set_src_cost (&all->convert, speed));
|
||||
}
|
||||
else if (size_from < size_to)
|
||||
{
|
||||
/* Assume cost of zero-extend and sign-extend is the same. */
|
||||
PUT_CODE (&all->convert, ZERO_EXTEND);
|
||||
PUT_MODE (&all->reg, mode_from);
|
||||
set_convert_cost (mode, mode_from, speed,
|
||||
set_src_cost (&all->convert, speed));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,23 +297,27 @@ init_expmed (void)
|
|||
XEXP (&all.shift_sub1, 0) = &all.reg;
|
||||
XEXP (&all.shift_sub1, 1) = &all.shift_mult;
|
||||
|
||||
PUT_CODE (&all.convert, TRUNCATE);
|
||||
XEXP (&all.convert, 0) = &all.reg;
|
||||
PUT_CODE (&all.trunc, TRUNCATE);
|
||||
XEXP (&all.trunc, 0) = &all.reg;
|
||||
|
||||
for (speed = 0; speed < 2; speed++)
|
||||
{
|
||||
crtl->maybe_hot_insn_p = speed;
|
||||
set_zero_cost (speed, set_src_cost (const0_rtx, speed));
|
||||
|
||||
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
|
||||
mode != VOIDmode;
|
||||
mode = GET_MODE_WIDER_MODE (mode))
|
||||
for (mode = MIN_MODE_INT; mode <= MAX_MODE_INT;
|
||||
mode = (enum machine_mode)(mode + 1))
|
||||
init_expmed_one_mode (&all, mode, speed);
|
||||
|
||||
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
|
||||
mode != VOIDmode;
|
||||
mode = GET_MODE_WIDER_MODE (mode))
|
||||
init_expmed_one_mode (&all, mode, speed);
|
||||
if (MIN_MODE_PARTIAL_INT != VOIDmode)
|
||||
for (mode = MIN_MODE_PARTIAL_INT; mode <= MAX_MODE_PARTIAL_INT;
|
||||
mode = (enum machine_mode)(mode + 1))
|
||||
init_expmed_one_mode (&all, mode, speed);
|
||||
|
||||
if (MIN_MODE_VECTOR_INT != VOIDmode)
|
||||
for (mode = MIN_MODE_VECTOR_INT; mode <= MAX_MODE_VECTOR_INT;
|
||||
mode = (enum machine_mode)(mode + 1))
|
||||
init_expmed_one_mode (&all, mode, speed);
|
||||
}
|
||||
|
||||
if (alg_hash_used_p ())
|
||||
|
|
86
gcc/expmed.h
86
gcc/expmed.h
|
@ -124,23 +124,24 @@ struct alg_hash_entry {
|
|||
#define NUM_ALG_HASH_ENTRIES 307
|
||||
#endif
|
||||
|
||||
#define NUM_MODE_INT (MAX_MODE_INT - MIN_MODE_INT + 1)
|
||||
#define NUM_MODE_VECTOR_INT (MAX_MODE_VECTOR_INT - MIN_MODE_VECTOR_INT + 1)
|
||||
#define NUM_MODE_INT \
|
||||
(MAX_MODE_INT - MIN_MODE_INT + 1)
|
||||
#define NUM_MODE_PARTIAL_INT \
|
||||
(MIN_MODE_PARTIAL_INT == VOIDmode ? 0 \
|
||||
: MAX_MODE_PARTIAL_INT - MIN_MODE_PARTIAL_INT + 1)
|
||||
#define NUM_MODE_VECTOR_INT \
|
||||
(MIN_MODE_VECTOR_INT == VOIDmode ? 0 \
|
||||
: MAX_MODE_VECTOR_INT - MIN_MODE_VECTOR_INT + 1)
|
||||
|
||||
#define NUM_MODE_IP_INT (NUM_MODE_INT + NUM_MODE_PARTIAL_INT)
|
||||
#define NUM_MODE_IPV_INT (NUM_MODE_IP_INT + NUM_MODE_VECTOR_INT)
|
||||
|
||||
struct expmed_op_cheap {
|
||||
/* Whether an operation is cheap in a given integer mode. */
|
||||
bool cheap_int[2][NUM_MODE_INT];
|
||||
|
||||
/* Whether an operation is cheap in a given vector integer mode. */
|
||||
bool cheap_vector_int[2][NUM_MODE_VECTOR_INT];
|
||||
bool cheap[2][NUM_MODE_IPV_INT];
|
||||
};
|
||||
|
||||
struct expmed_op_costs {
|
||||
/* The cost of an operation in a given integer mode. */
|
||||
int int_cost[2][NUM_MODE_INT];
|
||||
|
||||
/* The cost of an operation in a given vector integer mode. */
|
||||
int vector_int_cost[2][NUM_MODE_VECTOR_INT];
|
||||
int cost[2][NUM_MODE_IPV_INT];
|
||||
};
|
||||
|
||||
/* Target-dependent globals. */
|
||||
|
@ -178,7 +179,7 @@ struct target_expmed {
|
|||
/* Conversion costs are only defined between two scalar integer modes
|
||||
of different sizes. The first machine mode is the destination mode,
|
||||
and the second is the source mode. */
|
||||
int x_convert_cost[2][NUM_MODE_INT][NUM_MODE_INT];
|
||||
int x_convert_cost[2][NUM_MODE_IP_INT][NUM_MODE_IP_INT];
|
||||
};
|
||||
|
||||
extern struct target_expmed default_target_expmed;
|
||||
|
@ -212,6 +213,24 @@ set_alg_hash_used_p (bool usedp)
|
|||
this_target_expmed->x_alg_hash_used_p = usedp;
|
||||
}
|
||||
|
||||
/* Compute an index into the cost arrays by mode class. */
|
||||
|
||||
static inline int
|
||||
expmed_mode_index (enum machine_mode mode)
|
||||
{
|
||||
switch (GET_MODE_CLASS (mode))
|
||||
{
|
||||
case MODE_INT:
|
||||
return mode - MIN_MODE_INT;
|
||||
case MODE_PARTIAL_INT:
|
||||
return mode - MIN_MODE_PARTIAL_INT + NUM_MODE_INT;
|
||||
case MODE_VECTOR_INT:
|
||||
return mode - MIN_MODE_VECTOR_INT + NUM_MODE_IP_INT;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Return a pointer to a boolean contained in EOC indicating whether
|
||||
a particular operation performed in MODE is cheap when optimizing
|
||||
for SPEED. */
|
||||
|
@ -220,19 +239,8 @@ static inline bool *
|
|||
expmed_op_cheap_ptr (struct expmed_op_cheap *eoc, bool speed,
|
||||
enum machine_mode mode)
|
||||
{
|
||||
gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
|
||||
|| GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
|
||||
|
||||
if (GET_MODE_CLASS (mode) == MODE_INT)
|
||||
{
|
||||
int idx = mode - MIN_MODE_INT;
|
||||
return &eoc->cheap_int[speed][idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
int idx = mode - MIN_MODE_VECTOR_INT;
|
||||
return &eoc->cheap_vector_int[speed][idx];
|
||||
}
|
||||
int idx = expmed_mode_index (mode);
|
||||
return &eoc->cheap[speed][idx];
|
||||
}
|
||||
|
||||
/* Return a pointer to a cost contained in COSTS when a particular
|
||||
|
@ -242,19 +250,8 @@ static inline int *
|
|||
expmed_op_cost_ptr (struct expmed_op_costs *costs, bool speed,
|
||||
enum machine_mode mode)
|
||||
{
|
||||
gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
|
||||
|| GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
|
||||
|
||||
if (GET_MODE_CLASS (mode) == MODE_INT)
|
||||
{
|
||||
int idx = mode - MIN_MODE_INT;
|
||||
return &costs->int_cost[speed][idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
int idx = mode - MIN_MODE_VECTOR_INT;
|
||||
return &costs->vector_int_cost[speed][idx];
|
||||
}
|
||||
int idx = expmed_mode_index (mode);
|
||||
return &costs->cost[speed][idx];
|
||||
}
|
||||
|
||||
/* Subroutine of {set_,}sdiv_pow2_cheap. Not to be used otherwise. */
|
||||
|
@ -631,15 +628,12 @@ static inline int *
|
|||
convert_cost_ptr (enum machine_mode to_mode, enum machine_mode from_mode,
|
||||
bool speed)
|
||||
{
|
||||
int to_idx, from_idx;
|
||||
int to_idx = expmed_mode_index (to_mode);
|
||||
int from_idx = expmed_mode_index (from_mode);
|
||||
|
||||
gcc_assert (to_mode >= MIN_MODE_INT
|
||||
&& to_mode <= MAX_MODE_INT
|
||||
&& from_mode >= MIN_MODE_INT
|
||||
&& from_mode <= MAX_MODE_INT);
|
||||
gcc_assert (IN_RANGE (to_idx, 0, NUM_MODE_IP_INT - 1));
|
||||
gcc_assert (IN_RANGE (from_idx, 0, NUM_MODE_IP_INT - 1));
|
||||
|
||||
to_idx = to_mode - MIN_MODE_INT;
|
||||
from_idx = from_mode - MIN_MODE_INT;
|
||||
return &this_target_expmed->x_convert_cost[speed][to_idx][from_idx];
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue