@@ -3373,12 +3373,7 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
/* Return true iff basic block TEST_BB is comprised of only
(SET (REG) (REG)) insns suitable for conversion to a series
of conditional moves. FORNOW: Use II to find the expected cost of
- the branch into/over TEST_BB.
-
- TODO: This creates an implicit "magic number" for if conversion.
- II->rtx_edge_cost now guides the maximum number of set instructions in
- a basic block which is considered profitable to completely
- if-convert. */
+ the branch into/over TEST_BB. */
static bool
bb_ok_for_noce_convert_multiple_sets (basic_block test_bb,
@@ -3387,8 +3382,11 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb,
rtx_insn *insn;
unsigned count = 0;
unsigned param = PARAM_VALUE (PARAM_MAX_RTL_IF_CONVERSION_INSNS);
- /* TODO: Revisit this cost model. */
- unsigned limit = MIN (ii->rtx_edge_cost / COSTS_N_INSNS (1), param);
+ unsigned cost_limit = ii->rtx_edge_cost;
+ unsigned cost = 0;
+ bool speed_p = optimize_bb_for_speed_p (ii->test_bb);
+ rtx_code code = GET_CODE (ii->cond);
+ machine_mode cmode = GET_MODE (XEXP (ii->cond, 0));
FOR_BB_INSNS (test_bb, insn)
{
@@ -3404,6 +3402,9 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb,
rtx dest = SET_DEST (set);
rtx src = SET_SRC (set);
+ cost += noce_cmove_estimate_cost (cmode, GET_MODE (dest),
+ code, speed_p);
+
/* We can possibly relax this, but for now only handle REG to REG
moves. This avoids any issues that might come from introducing
loads/stores that might violate data-race-freedom guarantees. */
@@ -3418,14 +3419,14 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb,
if (!can_conditionally_move_p (GET_MODE (dest)))
return false;
- /* FORNOW: Our cost model is a count of the number of instructions we
- would if-convert. This is suboptimal, and should be improved as part
- of a wider rework of branch_cost. */
- if (++count > limit)
- return false;
+ count++;
}
- return count > 1;
+ /* If we would only put out one conditional move, the other strategies
+ this pass tries are better optimized and will be more appropriate.
+ If the cost in instructions is higher than the limit we've imposed,
+ also give up. */
+ return (count > 1 && cost <= cost_limit && count <= param);
}
/* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert