@@ -3191,6 +3191,7 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
rtx_insn *jump = if_info->jump;
rtx_insn *cond_earliest;
rtx_insn *insn;
+ bool speed_p = optimize_bb_for_speed_p (if_info->test_bb);
start_sequence ();
@@ -3273,9 +3274,17 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
for (int i = 0; i < count; i++)
noce_emit_move_insn (targets[i], temporaries[i]);
- /* Actually emit the sequence. */
+ /* Actually emit the sequence if it isn't too expensive. */
rtx_insn *seq = get_insns ();
+ /* Check the cost model to ensure this is profitable. */
+ if (seq_cost (seq, speed_p)
+ > if_info->max_seq_cost)
+ {
+ end_sequence ();
+ return FALSE;
+ }
+
for (insn = seq; insn; insn = NEXT_INSN (insn))
set_used_flags (insn);
@@ -3325,23 +3334,16 @@ 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->max_seq_cost now guides the maximum number of set instructions in
- a basic block which is considered profitable to completely
- if-convert. */
+ of conditional moves. Also check that we have more than one set
+ (other routines can handle a single set better than we would), and
+ fewer than PARAM_MAX_RTL_IF_CONVERSION_INSNS sets. */
static bool
-bb_ok_for_noce_convert_multiple_sets (basic_block test_bb,
- struct noce_if_info *ii)
+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->max_seq_cost / COSTS_N_INSNS (1), param);
FOR_BB_INSNS (test_bb, insn)
{
@@ -3377,14 +3379,15 @@ 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.
+ Some targets want to strictly limit the number of conditional moves
+ that are emitted, they set this through PARAM, we need to respect
+ that. */
+ return count > 1 && count <= param;
}
/* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
@@ -3420,7 +3423,7 @@ noce_process_if_block (struct noce_if_info *if_info)
if (!else_bb
&& HAVE_conditional_move
&& !HAVE_cc0
- && bb_ok_for_noce_convert_multiple_sets (then_bb, if_info))
+ && bb_ok_for_noce_convert_multiple_sets (then_bb))
{
if (noce_convert_multiple_sets (if_info))
{
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-rtl-ce1 -O2 --param max-rtl-if-conversion-insns=3" } */
+/* { dg-options "-fdump-rtl-ce1 -O2 --param max-rtl-if-conversion-insns=3 --param max-rtl-if-conversion-unpredictable-cost=100" } */
/* { dg-additional-options "-misel" { target { powerpc*-*-* } } } */
/* { dg-skip-if "Multiple set if-conversion not guaranteed on all subtargets" { "arm*-*-* hppa*64*-*-* visium-*-*" } } */
@@ -1,7 +1,8 @@
/* Check that multi-insn if-conversion is not done if the override
- parameter would not allow it. */
+ parameter would not allow it. Set the cost parameter very high
+ to ensure that the limiting factor is actually the count parameter. */
-/* { dg-options "-fdump-rtl-ce1 -O2 --param max-rtl-if-conversion-insns=1" } */
+/* { dg-options "-fdump-rtl-ce1 -O2 --param max-rtl-if-conversion-insns=1 --param max-rtl-if-conversion-unpredictable-cost=200" } */
typedef int word __attribute__((mode(word)));