Hi, This patch is a small rewrite to the cost model for bb_ok_for_noce_multiple_sets to use the new noce_cmove_estimate_cost function added in the previous patches.
Thanks, James --- 2016-06-02 James Greenhalgh <james.greenha...@arm.com> * ifcvt.c (bb_of_for_noce_convert_multiple_sets): Change cost model.
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index bd3f55d..f71889e 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -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