summaryrefslogtreecommitdiff
path: root/gcc/expmed.c
diff options
context:
space:
mode:
authorwschmidt <wschmidt@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-26 13:10:04 +0000
committerwschmidt <wschmidt@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-26 13:10:04 +0000
commit726556769945a83a856e39bdcb44a090cd5547bb (patch)
treed1c32e077e8672a0302c870fe8ff5a2256a82879 /gcc/expmed.c
parent4f862fce4a1472026631923d26ef754f21c67c73 (diff)
downloadgcc-726556769945a83a856e39bdcb44a090cd5547bb.tar.gz
2012-07-26 Bill Schmidt <wschmidt@linux.ibm.com>
* tree-ssa-loop-ivopts.c (mbc_entry_hash): Remove. (mbc_entry_eq): Likewise. (mult_costs): Likewise. (cost_tables_exist): Likewise. (initialize_costs): Likewise. (finalize_costs): Likewise. (tree_ssa_iv_optimize_init): Remove call to initialize_costs. (add_regs_cost): Remove. (multiply_regs_cost): Likewise. (add_const_cost): Likewise. (extend_or_trunc_reg_cost): Likewise. (negate_reg_cost): Likewise. (struct mbc_entry): Likewise. (multiply_by_const_cost): Likewise. (get_address_cost): Change add_regs_cost calls to add_cost lookups; change multiply_by_const_cost to mult_by_coeff_cost. (force_expr_to_var_cost): Likewise. (difference_cost): Change multiply_by_const_cost to mult_by_coeff_cost. (get_computation_cost_at): Change add_regs_cost calls to add_cost lookups; change multiply_by_const_cost to mult_by_coeff_cost. (determine_iv_cost): Change add_regs_cost calls to add_cost lookups. (tree_ssa_iv_optimize_finalize): Remove call to finalize_costs. * tree-ssa-address.c (expmed.h): New #include. (most_expensive_mult_to_index): Change multiply_by_const_cost to mult_by_coeff_cost. * gimple-ssa-strength-reduction.c (expmed.h): New #include. (stmt_cost): Change to use mult_by_coeff_cost, mul_cost, add_cost, neg_cost, and convert_cost instead of IVOPTS interfaces. (execute_strength_reduction): Remove calls to initialize_costs and finalize_costs. * expmed.c (struct init_expmed_rtl): Add convert rtx_def. (init_expmed_one_mode): Initialize convert rtx_def; initialize x_convert_cost for related modes. (mult_by_coeff_cost): New function. * expmed.h (NUM_MODE_INT): New #define. (struct target_expmed): Add x_convert_cost matrix. (set_convert_cost): New inline function. (convert_cost): Likewise. (mult_by_coeff_cost): New extern decl. * tree-flow.h (initialize_costs): Remove decl. (finalize_costs): Likewise. (multiply_by_const_cost): Likewise. (add_regs_cost): Likewise. (multiply_regs_cost): Likewise. (add_const_cost): Likewise. (extend_or_trunc_reg_cost): Likewise. (negate_reg_cost): Likewise. * Makefile.in (gimple-ssa-strength-reduction.o): Update dependencies. (tree-ssa-address.o): Update dependencies. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189890 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r--gcc/expmed.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 4101f613f82..e660a3f65a1 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -112,6 +112,7 @@ 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;
rtx pow2[MAX_BITS_PER_WORD];
rtx cint[MAX_BITS_PER_WORD];
@@ -122,6 +123,7 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
enum machine_mode mode, int speed)
{
int m, n, mode_bitsize;
+ enum machine_mode mode_from;
mode_bitsize = GET_MODE_UNIT_BITSIZE (mode);
@@ -139,6 +141,7 @@ 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);
add_cost[speed][mode] = set_src_cost (&all->plus, speed);
neg_cost[speed][mode] = set_src_cost (&all->neg, speed);
@@ -183,6 +186,30 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
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));
+ }
+ }
}
}
@@ -262,6 +289,9 @@ 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;
+
for (speed = 0; speed < 2; speed++)
{
crtl->maybe_hot_insn_p = speed;
@@ -3262,6 +3292,24 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
return op0;
}
+/* Return a cost estimate for multiplying a register by the given
+ COEFFicient in the given MODE and SPEED. */
+
+int
+mult_by_coeff_cost (HOST_WIDE_INT coeff, enum machine_mode mode, bool speed)
+{
+ int max_cost;
+ struct algorithm algorithm;
+ enum mult_variant variant;
+
+ rtx fake_reg = gen_raw_REG (mode, LAST_VIRTUAL_REGISTER + 1);
+ max_cost = set_src_cost (gen_rtx_MULT (mode, fake_reg, fake_reg), speed);
+ if (choose_mult_variant (mode, coeff, &algorithm, &variant, max_cost))
+ return algorithm.cost.cost;
+ else
+ return max_cost;
+}
+
/* Perform a widening multiplication and return an rtx for the result.
MODE is mode of value; OP0 and OP1 are what to multiply (rtx's);
TARGET is a suggestion for where to store the result (an rtx).