#endif
/* Conversion succeeded. */
- if (rtl_dump_file)
- fprintf (rtl_dump_file, "%d insn%s converted to conditional execution.\n",
+ if (dump_file)
+ fprintf (dump_file, "%d insn%s converted to conditional execution.\n",
n_insns, (n_insns == 1) ? " was" : "s were");
/* Merge the blocks! */
static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx *);
static int noce_try_minmax (struct noce_if_info *);
static int noce_try_abs (struct noce_if_info *);
+static int noce_try_sign_mask (struct noce_if_info *);
/* Helper function for noce_try_store_flag*. */
return TRUE;
}
+/* Convert "if (m < 0) x = b; else x = 0;" to "x = (m >> C) & b;". */
+
+static int
+noce_try_sign_mask (struct noce_if_info *if_info)
+{
+ rtx cond, t, m, c, seq;
+ enum machine_mode mode;
+ enum rtx_code code;
+
+ if (no_new_pseudos)
+ return FALSE;
+
+ cond = if_info->cond;
+ code = GET_CODE (cond);
+ m = XEXP (cond, 0);
+ c = XEXP (cond, 1);
+
+ t = NULL_RTX;
+ if (if_info->a == const0_rtx)
+ {
+ if ((code == LT && c == const0_rtx)
+ || (code == LE && c == constm1_rtx))
+ t = if_info->b;
+ }
+ else if (if_info->b == const0_rtx)
+ {
+ if ((code == GE && c == const0_rtx)
+ || (code == GT && c == constm1_rtx))
+ t = if_info->a;
+ }
+
+ if (! t || side_effects_p (t))
+ return FALSE;
+
+ /* We currently don't handle different modes. */
+ mode = GET_MODE (t);
+ if (GET_MODE (m) != mode)
+ return FALSE;
+
+ /* This is only profitable if T is cheap. */
+ if (rtx_cost (t, SET) >= COSTS_N_INSNS (2))
+ return FALSE;
+
+ start_sequence ();
+ c = gen_int_mode (GET_MODE_BITSIZE (mode) - 1, mode);
+ m = expand_binop (mode, ashr_optab, m, c, NULL_RTX, 0, OPTAB_DIRECT);
+ t = m ? expand_binop (mode, and_optab, m, t, NULL_RTX, 0, OPTAB_DIRECT)
+ : NULL_RTX;
+
+ if (!t)
+ {
+ end_sequence ();
+ return FALSE;
+ }
+
+ noce_emit_move_insn (if_info->x, t);
+ seq = get_insns ();
+ unshare_ifcvt_sequence (if_info, seq);
+ end_sequence ();
+ emit_insn_before_setloc (seq, if_info->jump,
+ INSN_LOCATOR (if_info->insn_a));
+ return TRUE;
+}
+
+
/* Similar to get_condition, only the resulting condition must be
valid at JUMP, instead of at EARLIEST. */
if (HAVE_conditional_move
&& noce_try_cmove_arith (&if_info))
goto success;
+ if (noce_try_sign_mask (&if_info))
+ goto success;
}
return FALSE;
return NULL;
success:
- if (rtl_dump_file)
- fprintf (rtl_dump_file, "Conversion succeeded on pass %d.\n", pass);
+ if (dump_file)
+ fprintf (dump_file, "Conversion succeeded on pass %d.\n", pass);
return ce_info.test_bb;
}
num_possible_if_blocks++;
- if (rtl_dump_file)
+ if (dump_file)
{
- fprintf (rtl_dump_file, "\nIF-THEN%s block found, pass %d, start block %d [insn %d], then %d [%d]",
+ fprintf (dump_file,
+ "\nIF-THEN%s block found, pass %d, start block %d "
+ "[insn %d], then %d [%d]",
(else_bb) ? "-ELSE" : "",
ce_info->pass,
- test_bb->index, (BB_HEAD (test_bb)) ? (int)INSN_UID (BB_HEAD (test_bb)) : -1,
- then_bb->index, (BB_HEAD (then_bb)) ? (int)INSN_UID (BB_HEAD (then_bb)) : -1);
+ test_bb->index,
+ BB_HEAD (test_bb) ? (int)INSN_UID (BB_HEAD (test_bb)) : -1,
+ then_bb->index,
+ BB_HEAD (then_bb) ? (int)INSN_UID (BB_HEAD (then_bb)) : -1);
if (else_bb)
- fprintf (rtl_dump_file, ", else %d [%d]",
- else_bb->index, (BB_HEAD (else_bb)) ? (int)INSN_UID (BB_HEAD (else_bb)) : -1);
+ fprintf (dump_file, ", else %d [%d]",
+ else_bb->index,
+ BB_HEAD (else_bb) ? (int)INSN_UID (BB_HEAD (else_bb)) : -1);
- fprintf (rtl_dump_file, ", join %d [%d]",
- join_bb->index, (BB_HEAD (join_bb)) ? (int)INSN_UID (BB_HEAD (join_bb)) : -1);
+ fprintf (dump_file, ", join %d [%d]",
+ join_bb->index,
+ BB_HEAD (join_bb) ? (int)INSN_UID (BB_HEAD (join_bb)) : -1);
if (ce_info->num_multiple_test_blocks > 0)
- fprintf (rtl_dump_file, ", %d %s block%s last test %d [%d]",
+ fprintf (dump_file, ", %d %s block%s last test %d [%d]",
ce_info->num_multiple_test_blocks,
(ce_info->and_and_p) ? "&&" : "||",
(ce_info->num_multiple_test_blocks == 1) ? "" : "s",
? (int)INSN_UID (BB_HEAD (ce_info->last_test_bb))
: -1));
- fputc ('\n', rtl_dump_file);
+ fputc ('\n', dump_file);
}
/* Make sure IF, THEN, and ELSE, blocks are adjacent. Actually, we get the
else
return FALSE;
- if (rtl_dump_file)
+ if (dump_file)
{
- fprintf (rtl_dump_file, "\nTRAP-IF block found, start %d, trap %d\n",
+ fprintf (dump_file, "\nTRAP-IF block found, start %d, trap %d\n",
test_bb->index, trap_bb->index);
}
return FALSE;
num_possible_if_blocks++;
- if (rtl_dump_file)
- fprintf (rtl_dump_file,
+ if (dump_file)
+ fprintf (dump_file,
"\nIF-CASE-1 found, start %d, then %d\n",
test_bb->index, then_bb->index);
return FALSE;
num_possible_if_blocks++;
- if (rtl_dump_file)
- fprintf (rtl_dump_file,
+ if (dump_file)
+ fprintf (dump_file,
"\nIF-CASE-2 found, start %d, else %d\n",
test_bb->index, else_bb->index);
pass++;
#ifdef IFCVT_MULTIPLE_DUMPS
- if (rtl_dump_file && pass > 1)
- fprintf (rtl_dump_file, "\n\n========== Pass %d ==========\n", pass);
+ if (dump_file && pass > 1)
+ fprintf (dump_file, "\n\n========== Pass %d ==========\n", pass);
#endif
FOR_EACH_BB (bb)
}
#ifdef IFCVT_MULTIPLE_DUMPS
- if (rtl_dump_file && cond_exec_changed_p)
- print_rtl_with_bb (rtl_dump_file, get_insns ());
+ if (dump_file && cond_exec_changed_p)
+ print_rtl_with_bb (dump_file, get_insns ());
#endif
}
while (cond_exec_changed_p);
#ifdef IFCVT_MULTIPLE_DUMPS
- if (rtl_dump_file)
- fprintf (rtl_dump_file, "\n\n========== no more changes\n");
+ if (dump_file)
+ fprintf (dump_file, "\n\n========== no more changes\n");
#endif
free_dominance_info (CDI_POST_DOMINATORS);
- if (rtl_dump_file)
- fflush (rtl_dump_file);
+ if (dump_file)
+ fflush (dump_file);
clear_aux_for_blocks ();
}
/* Write the final stats. */
- if (rtl_dump_file && num_possible_if_blocks > 0)
+ if (dump_file && num_possible_if_blocks > 0)
{
- fprintf (rtl_dump_file,
+ fprintf (dump_file,
"\n%d possible IF blocks searched.\n",
num_possible_if_blocks);
- fprintf (rtl_dump_file,
+ fprintf (dump_file,
"%d IF blocks converted.\n",
num_updated_if_blocks);
- fprintf (rtl_dump_file,
+ fprintf (dump_file,
"%d true changes made.\n\n\n",
num_true_changes);
}