ipa-cp.c (ipcp_cloning_candidate_p): Use opt_for_fn.
[gcc.git] / gcc / ifcvt.c
index a28f5c13992f0a52c292390cd31111fb0ec8ec9c..21f08c218e741253ab14675e3ab05c9055437813 100644 (file)
 #include "insn-config.h"
 #include "recog.h"
 #include "except.h"
+#include "predict.h"
+#include "dominance.h"
+#include "cfg.h"
+#include "cfgrtl.h"
+#include "cfganal.h"
+#include "cfgcleanup.h"
 #include "basic-block.h"
 #include "expr.h"
 #include "output.h"
+#include "insn-codes.h"
 #include "optabs.h"
 #include "diagnostic-core.h"
 #include "tm_p.h"
    + 1)
 #endif
 
+#ifndef HAVE_cbranchcc4
+#define HAVE_cbranchcc4 0
+#endif
+
 #define IFCVT_MULTIPLE_DUMPS 1
 
 #define NULL_BLOCK     ((basic_block) NULL)
@@ -421,7 +432,7 @@ cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED,
 
       if (CALL_P (insn) && prob_val >= 0)
        validate_change (insn, &REG_NOTES (insn),
-                        gen_rtx_INT_LIST ((enum machine_mode) REG_BR_PROB,
+                        gen_rtx_INT_LIST ((machine_mode) REG_BR_PROB,
                                           prob_val, REG_NOTES (insn)), 1);
 
     insn_done:
@@ -903,7 +914,7 @@ noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep,
 static void
 noce_emit_move_insn (rtx x, rtx y)
 {
-  enum machine_mode outmode;
+  machine_mode outmode;
   rtx outer, inner;
   int bitpos;
 
@@ -1143,7 +1154,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info)
   int reversep;
   HOST_WIDE_INT itrue, ifalse, diff, tmp;
   int normalize, can_reverse;
-  enum machine_mode mode;
+  machine_mode mode;
 
   if (CONST_INT_P (if_info->a)
       && CONST_INT_P (if_info->b))
@@ -1387,6 +1398,9 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
 
       if (target)
        {
+         int old_cost, new_cost, insn_cost;
+         int speed_p;
+
          if (target != if_info->x)
            noce_emit_move_insn (if_info->x, target);
 
@@ -1394,6 +1408,14 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
          if (!seq)
            return FALSE;
 
+         speed_p = optimize_bb_for_speed_p (BLOCK_FOR_INSN (if_info->insn_a));
+         insn_cost = insn_rtx_cost (PATTERN (if_info->insn_a), speed_p);
+         old_cost = COSTS_N_INSNS (if_info->branch_cost) + insn_cost;
+         new_cost = seq_cost (seq, speed_p);
+
+         if (new_cost > old_cost)
+           return FALSE;
+
          emit_insn_before_setloc (seq, if_info->jump,
                                   INSN_LOCATION (if_info->insn_a));
          return TRUE;
@@ -1441,10 +1463,16 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
       end_sequence ();
     }
 
-  /* Don't even try if the comparison operands are weird.  */
+  /* Don't even try if the comparison operands are weird
+     except that the target supports cbranchcc4.  */
   if (! general_operand (cmp_a, GET_MODE (cmp_a))
       || ! general_operand (cmp_b, GET_MODE (cmp_b)))
-    return NULL_RTX;
+    {
+      if (!(HAVE_cbranchcc4)
+         || GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC
+         || cmp_b != const0_rtx)
+       return NULL_RTX;
+    }
 
 #if HAVE_conditional_move
   unsignedp = (code == LTU || code == GEU
@@ -1583,7 +1611,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
       && MEM_ADDR_SPACE (a) == MEM_ADDR_SPACE (b)
       && if_info->branch_cost >= 5)
     {
-      enum machine_mode address_mode = get_address_mode (a);
+      machine_mode address_mode = get_address_mode (a);
 
       a = XEXP (a, 0);
       b = XEXP (b, 0);
@@ -1891,7 +1919,7 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
     }
 
   cond = canonicalize_condition (if_info->jump, cond, reverse,
-                                earliest, target, false, true);
+                                earliest, target, HAVE_cbranchcc4, true);
   if (! cond || ! reg_mentioned_p (target, cond))
     return NULL;
 
@@ -2163,7 +2191,7 @@ noce_try_sign_mask (struct noce_if_info *if_info)
 {
   rtx cond, t, m, c;
   rtx_insn *seq;
-  enum machine_mode mode;
+  machine_mode mode;
   enum rtx_code code;
   bool t_unconditional;
 
@@ -2242,7 +2270,7 @@ noce_try_bitop (struct noce_if_info *if_info)
 {
   rtx cond, x, a, result;
   rtx_insn *seq;
-  enum machine_mode mode;
+  machine_mode mode;
   enum rtx_code code;
   int bitnum;
 
@@ -2383,7 +2411,7 @@ noce_get_condition (rtx_insn *jump, rtx_insn **earliest, bool then_else_reversed
   /* Otherwise, fall back on canonicalize_condition to do the dirty
      work of manipulating MODE_CC values and COMPARE rtx codes.  */
   tmp = canonicalize_condition (jump, cond, reverse, earliest,
-                               NULL_RTX, false, true);
+                               NULL_RTX, HAVE_cbranchcc4, true);
 
   /* We don't handle side-effects in the condition, like handling
      REG_INC notes and making sure no duplicate conditions are emitted.  */