Commit 91f8035e by Richard Henderson Committed by Richard Henderson

Allow MODE_PARTIAL_INT in expmed costs

From-SVN: r190050
parent 92e014ca
2012-08-01 Richard Henderson <rth@redhat.com> 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. * config/m32c/m32c.c (TARGET_INIT_LIBFUNCS): Remove.
(m32c_init_libfuncs): Remove. (m32c_init_libfuncs): Remove.
* config/m32c/cond.md (cstore<QHPSI>4_16): Rename from cstore<QHPSI>4. * config/m32c/cond.md (cstore<QHPSI>4_16): Rename from cstore<QHPSI>4.
......
...@@ -101,7 +101,6 @@ struct init_expmed_rtl ...@@ -101,7 +101,6 @@ struct init_expmed_rtl
struct rtx_def mult; rtunion mult_fld1; struct rtx_def mult; rtunion mult_fld1;
struct rtx_def sdiv; rtunion sdiv_fld1; struct rtx_def sdiv; rtunion sdiv_fld1;
struct rtx_def udiv; rtunion udiv_fld1; struct rtx_def udiv; rtunion udiv_fld1;
struct rtx_def zext;
struct rtx_def sdiv_32; rtunion sdiv_32_fld1; struct rtx_def sdiv_32; rtunion sdiv_32_fld1;
struct rtx_def smod_32; rtunion smod_32_fld1; struct rtx_def smod_32; rtunion smod_32_fld1;
struct rtx_def wide_mult; rtunion wide_mult_fld1; struct rtx_def wide_mult; rtunion wide_mult_fld1;
...@@ -112,13 +111,36 @@ struct init_expmed_rtl ...@@ -112,13 +111,36 @@ struct init_expmed_rtl
struct rtx_def shift_add; rtunion shift_add_fld1; struct rtx_def shift_add; rtunion shift_add_fld1;
struct rtx_def shift_sub0; rtunion shift_sub0_fld1; struct rtx_def shift_sub0; rtunion shift_sub0_fld1;
struct rtx_def shift_sub1; rtunion shift_sub1_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 pow2[MAX_BITS_PER_WORD];
rtx cint[MAX_BITS_PER_WORD]; rtx cint[MAX_BITS_PER_WORD];
}; };
static void 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, init_expmed_one_mode (struct init_expmed_rtl *all,
enum machine_mode mode, int speed) enum machine_mode mode, int speed)
{ {
...@@ -141,7 +163,8 @@ init_expmed_one_mode (struct init_expmed_rtl *all, ...@@ -141,7 +163,8 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
PUT_MODE (&all->shift_add, mode); PUT_MODE (&all->shift_add, mode);
PUT_MODE (&all->shift_sub0, mode); PUT_MODE (&all->shift_sub0, mode);
PUT_MODE (&all->shift_sub1, 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_add_cost (speed, mode, set_src_cost (&all->plus, speed));
set_neg_cost (speed, mode, set_src_cost (&all->neg, 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, ...@@ -176,8 +199,13 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
if (SCALAR_INT_MODE_P (mode)) if (SCALAR_INT_MODE_P (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); enum machine_mode wider_mode = GET_MODE_WIDER_MODE (mode);
if (wider_mode != VOIDmode) if (wider_mode != VOIDmode)
{ {
PUT_MODE (&all->zext, wider_mode); PUT_MODE (&all->zext, wider_mode);
...@@ -185,32 +213,10 @@ init_expmed_one_mode (struct init_expmed_rtl *all, ...@@ -185,32 +213,10 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
PUT_MODE (&all->wide_lshr, wider_mode); PUT_MODE (&all->wide_lshr, wider_mode);
XEXP (&all->wide_lshr, 1) = GEN_INT (mode_bitsize); 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_widen_cost (speed, wider_mode,
set_mul_highpart_cost (speed, mode, set_src_cost (&all->wide_trunc, speed)); 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,22 +297,26 @@ init_expmed (void) ...@@ -291,22 +297,26 @@ init_expmed (void)
XEXP (&all.shift_sub1, 0) = &all.reg; XEXP (&all.shift_sub1, 0) = &all.reg;
XEXP (&all.shift_sub1, 1) = &all.shift_mult; XEXP (&all.shift_sub1, 1) = &all.shift_mult;
PUT_CODE (&all.convert, TRUNCATE); PUT_CODE (&all.trunc, TRUNCATE);
XEXP (&all.convert, 0) = &all.reg; XEXP (&all.trunc, 0) = &all.reg;
for (speed = 0; speed < 2; speed++) for (speed = 0; speed < 2; speed++)
{ {
crtl->maybe_hot_insn_p = speed; crtl->maybe_hot_insn_p = speed;
set_zero_cost (speed, set_src_cost (const0_rtx, speed)); set_zero_cost (speed, set_src_cost (const0_rtx, speed));
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); for (mode = MIN_MODE_INT; mode <= MAX_MODE_INT;
mode != VOIDmode; mode = (enum machine_mode)(mode + 1))
mode = GET_MODE_WIDER_MODE (mode))
init_expmed_one_mode (&all, mode, speed); init_expmed_one_mode (&all, mode, speed);
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT); if (MIN_MODE_PARTIAL_INT != VOIDmode)
mode != VOIDmode; for (mode = MIN_MODE_PARTIAL_INT; mode <= MAX_MODE_PARTIAL_INT;
mode = GET_MODE_WIDER_MODE (mode)) 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); init_expmed_one_mode (&all, mode, speed);
} }
......
...@@ -124,23 +124,24 @@ struct alg_hash_entry { ...@@ -124,23 +124,24 @@ struct alg_hash_entry {
#define NUM_ALG_HASH_ENTRIES 307 #define NUM_ALG_HASH_ENTRIES 307
#endif #endif
#define NUM_MODE_INT (MAX_MODE_INT - MIN_MODE_INT + 1) #define NUM_MODE_INT \
#define NUM_MODE_VECTOR_INT (MAX_MODE_VECTOR_INT - MIN_MODE_VECTOR_INT + 1) (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 { struct expmed_op_cheap {
/* Whether an operation is cheap in a given integer mode. */ bool cheap[2][NUM_MODE_IPV_INT];
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];
}; };
struct expmed_op_costs { struct expmed_op_costs {
/* The cost of an operation in a given integer mode. */ int cost[2][NUM_MODE_IPV_INT];
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];
}; };
/* Target-dependent globals. */ /* Target-dependent globals. */
...@@ -178,7 +179,7 @@ struct target_expmed { ...@@ -178,7 +179,7 @@ struct target_expmed {
/* Conversion costs are only defined between two scalar integer modes /* Conversion costs are only defined between two scalar integer modes
of different sizes. The first machine mode is the destination mode, of different sizes. The first machine mode is the destination mode,
and the second is the source 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; extern struct target_expmed default_target_expmed;
...@@ -212,6 +213,24 @@ set_alg_hash_used_p (bool usedp) ...@@ -212,6 +213,24 @@ set_alg_hash_used_p (bool usedp)
this_target_expmed->x_alg_hash_used_p = 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 /* Return a pointer to a boolean contained in EOC indicating whether
a particular operation performed in MODE is cheap when optimizing a particular operation performed in MODE is cheap when optimizing
for SPEED. */ for SPEED. */
...@@ -220,19 +239,8 @@ static inline bool * ...@@ -220,19 +239,8 @@ static inline bool *
expmed_op_cheap_ptr (struct expmed_op_cheap *eoc, bool speed, expmed_op_cheap_ptr (struct expmed_op_cheap *eoc, bool speed,
enum machine_mode mode) enum machine_mode mode)
{ {
gcc_assert (GET_MODE_CLASS (mode) == MODE_INT int idx = expmed_mode_index (mode);
|| GET_MODE_CLASS (mode) == MODE_VECTOR_INT); return &eoc->cheap[speed][idx];
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];
}
} }
/* Return a pointer to a cost contained in COSTS when a particular /* Return a pointer to a cost contained in COSTS when a particular
...@@ -242,19 +250,8 @@ static inline int * ...@@ -242,19 +250,8 @@ static inline int *
expmed_op_cost_ptr (struct expmed_op_costs *costs, bool speed, expmed_op_cost_ptr (struct expmed_op_costs *costs, bool speed,
enum machine_mode mode) enum machine_mode mode)
{ {
gcc_assert (GET_MODE_CLASS (mode) == MODE_INT int idx = expmed_mode_index (mode);
|| GET_MODE_CLASS (mode) == MODE_VECTOR_INT); return &costs->cost[speed][idx];
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];
}
} }
/* Subroutine of {set_,}sdiv_pow2_cheap. Not to be used otherwise. */ /* Subroutine of {set_,}sdiv_pow2_cheap. Not to be used otherwise. */
...@@ -631,15 +628,12 @@ static inline int * ...@@ -631,15 +628,12 @@ static inline int *
convert_cost_ptr (enum machine_mode to_mode, enum machine_mode from_mode, convert_cost_ptr (enum machine_mode to_mode, enum machine_mode from_mode,
bool speed) 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 gcc_assert (IN_RANGE (to_idx, 0, NUM_MODE_IP_INT - 1));
&& to_mode <= MAX_MODE_INT gcc_assert (IN_RANGE (from_idx, 0, NUM_MODE_IP_INT - 1));
&& from_mode >= MIN_MODE_INT
&& from_mode <= MAX_MODE_INT);
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]; return &this_target_expmed->x_convert_cost[speed][to_idx][from_idx];
} }
......
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