ipa-cp.c (ipcp_cloning_candidate_p): Use opt_for_fn.
[gcc.git] / gcc / ifcvt.c
index d5ae98b99622ce8e853c7dc51d79e5f4389e3fef..21f08c218e741253ab14675e3ab05c9055437813 100644 (file)
 
 #include "rtl.h"
 #include "regs.h"
+#include "hashtab.h"
+#include "hash-set.h"
+#include "vec.h"
+#include "machmode.h"
+#include "hard-reg-set.h"
+#include "input.h"
 #include "function.h"
 #include "flags.h"
 #include "insn-config.h"
 #include "recog.h"
 #include "except.h"
-#include "hard-reg-set.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"
@@ -40,8 +52,9 @@
 #include "target.h"
 #include "tree-pass.h"
 #include "df.h"
-#include "vec.h"
 #include "dbgcnt.h"
+#include "shrink-wrap.h"
+#include "ifcvt.h"
 
 #ifndef HAVE_conditional_move
 #define HAVE_conditional_move 0
    + 1)
 #endif
 
+#ifndef HAVE_cbranchcc4
+#define HAVE_cbranchcc4 0
+#endif
+
 #define IFCVT_MULTIPLE_DUMPS 1
 
 #define NULL_BLOCK     ((basic_block) NULL)
@@ -87,12 +104,13 @@ static int count_bb_insns (const_basic_block);
 static bool cheap_bb_rtx_cost_p (const_basic_block, int, int);
 static rtx_insn *first_active_insn (basic_block);
 static rtx_insn *last_active_insn (basic_block, int);
-static rtx find_active_insn_before (basic_block, rtx);
-static rtx find_active_insn_after (basic_block, rtx);
+static rtx_insn *find_active_insn_before (basic_block, rtx_insn *);
+static rtx_insn *find_active_insn_after (basic_block, rtx_insn *);
 static basic_block block_fallthru (basic_block);
-static int cond_exec_process_insns (ce_if_block *, rtx, rtx, rtx, int, int);
-static rtx cond_exec_get_condition (rtx);
-static rtx noce_get_condition (rtx, rtx *, bool);
+static int cond_exec_process_insns (ce_if_block *, rtx_insn *, rtx, rtx, int,
+                                   int);
+static rtx cond_exec_get_condition (rtx_insn *);
+static rtx noce_get_condition (rtx_insn *, rtx_insn **, bool);
 static int noce_operand_ok (const_rtx);
 static void merge_if_block (ce_if_block *);
 static int find_cond_trap (basic_block, edge, edge);
@@ -256,11 +274,11 @@ last_active_insn (basic_block bb, int skip_use_p)
 
 /* Return the active insn before INSN inside basic block CURR_BB. */
 
-static rtx
-find_active_insn_before (basic_block curr_bb, rtx insn)
+static rtx_insn *
+find_active_insn_before (basic_block curr_bb, rtx_insn *insn)
 {
   if (!insn || insn == BB_HEAD (curr_bb))
-    return NULL_RTX;
+    return NULL;
 
   while ((insn = PREV_INSN (insn)) != NULL_RTX)
     {
@@ -269,7 +287,7 @@ find_active_insn_before (basic_block curr_bb, rtx insn)
 
       /* No other active insn all the way to the start of the basic block. */
       if (insn == BB_HEAD (curr_bb))
-        return NULL_RTX;
+        return NULL;
     }
 
   return insn;
@@ -277,11 +295,11 @@ find_active_insn_before (basic_block curr_bb, rtx insn)
 
 /* Return the active insn after INSN inside basic block CURR_BB. */
 
-static rtx
-find_active_insn_after (basic_block curr_bb, rtx insn)
+static rtx_insn *
+find_active_insn_after (basic_block curr_bb, rtx_insn *insn)
 {
   if (!insn || insn == BB_END (curr_bb))
-    return NULL_RTX;
+    return NULL;
 
   while ((insn = NEXT_INSN (insn)) != NULL_RTX)
     {
@@ -290,7 +308,7 @@ find_active_insn_after (basic_block curr_bb, rtx insn)
 
       /* No other active insn all the way to the end of the basic block. */
       if (insn == BB_END (curr_bb))
-        return NULL_RTX;
+        return NULL;
     }
 
   return insn;
@@ -334,14 +352,14 @@ rtx_interchangeable_p (const_rtx a, const_rtx b)
 
 static int
 cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED,
-                        /* if block information */rtx start,
+                        /* if block information */rtx_insn *start,
                         /* first insn to look at */rtx end,
                         /* last insn to look at */rtx test,
                         /* conditional execution test */int prob_val,
                         /* probability of branch taken. */int mod_ok)
 {
   int must_be_last = FALSE;
-  rtx insn;
+  rtx_insn *insn;
   rtx xtest;
   rtx pattern;
 
@@ -414,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:
@@ -428,7 +446,7 @@ cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED,
 /* Return the condition for a jump.  Do not do any special processing.  */
 
 static rtx
-cond_exec_get_condition (rtx jump)
+cond_exec_get_condition (rtx_insn *jump)
 {
   rtx test_if, cond;
 
@@ -441,7 +459,7 @@ cond_exec_get_condition (rtx jump)
   /* If this branches to JUMP_LABEL when the condition is false,
      reverse the condition.  */
   if (GET_CODE (XEXP (test_if, 2)) == LABEL_REF
-      && XEXP (XEXP (test_if, 2), 0) == JUMP_LABEL (jump))
+      && LABEL_REF_LABEL (XEXP (test_if, 2)) == JUMP_LABEL (jump))
     {
       enum rtx_code rev = reversed_comparison_code (cond, jump);
       if (rev == UNKNOWN)
@@ -466,10 +484,10 @@ cond_exec_process_if_block (ce_if_block * ce_info,
   basic_block then_bb = ce_info->then_bb;      /* THEN */
   basic_block else_bb = ce_info->else_bb;      /* ELSE or NULL */
   rtx test_expr;               /* expression in IF_THEN_ELSE that is tested */
-  rtx then_start;              /* first insn in THEN block */
-  rtx then_end;                        /* last insn + 1 in THEN block */
-  rtx else_start = NULL_RTX;   /* first insn in ELSE block or NULL */
-  rtx else_end = NULL_RTX;     /* last insn + 1 in ELSE block */
+  rtx_insn *then_start;                /* first insn in THEN block */
+  rtx_insn *then_end;          /* last insn + 1 in THEN block */
+  rtx_insn *else_start = NULL; /* first insn in ELSE block or NULL */
+  rtx_insn *else_end = NULL;   /* last insn + 1 in ELSE block */
   int max;                     /* max # of insns to convert.  */
   int then_mod_ok;             /* whether conditional mods are ok in THEN */
   rtx true_expr;               /* test for else block insns */
@@ -534,9 +552,9 @@ cond_exec_process_if_block (ce_if_block * ce_info,
                                         &then_first_tail, &else_first_tail,
                                         NULL);
       if (then_first_tail == BB_HEAD (then_bb))
-       then_start = then_end = NULL_RTX;
+       then_start = then_end = NULL;
       if (else_first_tail == BB_HEAD (else_bb))
-       else_start = else_end = NULL_RTX;
+       else_start = else_end = NULL;
 
       if (n_matching > 0)
        {
@@ -562,7 +580,7 @@ cond_exec_process_if_block (ce_if_block * ce_info,
 
          if (n_matching > 0)
            {
-             rtx insn;
+             rtx_insn *insn;
 
              /* We won't pass the insns in the head sequence to
                 cond_exec_process_insns, so we need to test them here
@@ -577,9 +595,9 @@ cond_exec_process_if_block (ce_if_block * ce_info,
            }
 
          if (then_last_head == then_end)
-           then_start = then_end = NULL_RTX;
+           then_start = then_end = NULL;
          if (else_last_head == else_end)
-           else_start = else_end = NULL_RTX;
+           else_start = else_end = NULL;
 
          if (n_matching > 0)
            {
@@ -641,7 +659,7 @@ cond_exec_process_if_block (ce_if_block * ce_info,
 
       do
        {
-         rtx start, end;
+         rtx_insn *start, *end;
          rtx t, f;
          enum rtx_code f_code;
 
@@ -743,7 +761,7 @@ cond_exec_process_if_block (ce_if_block * ce_info,
      that the remaining one is executed first for both branches.  */
   if (then_first_tail)
     {
-      rtx from = then_first_tail;
+      rtx_insn *from = then_first_tail;
       if (!INSN_P (from))
        from = find_active_insn_after (then_bb, from);
       delete_insn_chain (from, BB_END (then_bb), false);
@@ -783,7 +801,7 @@ struct noce_if_info
   rtx cond;
 
   /* New insns should be inserted before this one.  */
-  rtx cond_earliest;
+  rtx_insn *cond_earliest;
 
   /* Insns in the THEN and ELSE block.  There is always just this
      one insns in those blocks.  The insns are single_set insns.
@@ -819,7 +837,7 @@ static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx,
                            rtx, rtx, rtx);
 static int noce_try_cmove (struct noce_if_info *);
 static int noce_try_cmove_arith (struct noce_if_info *);
-static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx *);
+static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx_insn **);
 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 *);
@@ -845,7 +863,7 @@ noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep,
       rtx set = pc_set (if_info->jump);
       cond = XEXP (SET_SRC (set), 0);
       if (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
-         && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (if_info->jump))
+         && LABEL_REF_LABEL (XEXP (SET_SRC (set), 2)) == JUMP_LABEL (if_info->jump))
        reversep = !reversep;
       if (if_info->then_else_reversed)
        reversep = !reversep;
@@ -859,20 +877,18 @@ noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep,
   if ((if_info->cond_earliest == if_info->jump || cond_complex)
       && (normalize == 0 || STORE_FLAG_VALUE == normalize))
     {
-      rtx tmp;
-
-      tmp = gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (cond, 0),
+      rtx src = gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (cond, 0),
                            XEXP (cond, 1));
-      tmp = gen_rtx_SET (VOIDmode, x, tmp);
+      rtx set = gen_rtx_SET (VOIDmode, x, src);
 
       start_sequence ();
-      tmp = emit_insn (tmp);
+      rtx_insn *insn = emit_insn (set);
 
-      if (recog_memoized (tmp) >= 0)
+      if (recog_memoized (insn) >= 0)
        {
-         tmp = get_insns ();
+         rtx_insn *seq = get_insns ();
          end_sequence ();
-         emit_insn (tmp);
+         emit_insn (seq);
 
          if_info->cond_earliest = if_info->jump;
 
@@ -898,13 +914,14 @@ 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;
 
   if (GET_CODE (x) != STRICT_LOW_PART)
     {
-      rtx seq, insn, target;
+      rtx_insn *seq, *insn;
+      rtx target;
       optab ot;
 
       start_sequence ();
@@ -1137,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))
@@ -1381,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);
 
@@ -1388,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;
@@ -1415,20 +1443,19 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
 
   if (if_info->cond_earliest == if_info->jump)
     {
-      rtx tmp;
-
-      tmp = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
-      tmp = gen_rtx_IF_THEN_ELSE (GET_MODE (x), tmp, vtrue, vfalse);
-      tmp = gen_rtx_SET (VOIDmode, x, tmp);
+      rtx cond = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
+      rtx if_then_else = gen_rtx_IF_THEN_ELSE (GET_MODE (x),
+                                              cond, vtrue, vfalse);
+      rtx set = gen_rtx_SET (VOIDmode, x, if_then_else);
 
       start_sequence ();
-      tmp = emit_insn (tmp);
+      rtx_insn *insn = emit_insn (set);
 
-      if (recog_memoized (tmp) >= 0)
+      if (recog_memoized (insn) >= 0)
        {
-         tmp = get_insns ();
+         rtx_insn *seq = get_insns ();
          end_sequence ();
-         emit_insn (tmp);
+         emit_insn (seq);
 
          return x;
        }
@@ -1436,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
@@ -1561,11 +1594,12 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
   rtx b = if_info->b;
   rtx x = if_info->x;
   rtx orig_a, orig_b;
-  rtx insn_a, insn_b;
-  rtx tmp, target;
+  rtx_insn *insn_a, *insn_b;
+  rtx target;
   int is_mem = 0;
   int insn_cost;
   enum rtx_code code;
+  rtx_insn *ifcvt_seq;
 
   /* A conditional move from two memory sources is equivalent to a
      conditional on their addresses followed by a load.  Don't do this
@@ -1577,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);
@@ -1635,9 +1669,11 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
 
       if (reversep)
        {
+         rtx tmp;
+         rtx_insn *tmp_insn;
          code = reversed_comparison_code (if_info->cond, if_info->jump);
          tmp = a, a = b, b = tmp;
-         tmp = insn_a, insn_a = insn_b, insn_b = tmp;
+         tmp_insn = insn_a, insn_a = insn_b, insn_b = tmp_insn;
        }
     }
 
@@ -1652,44 +1688,46 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
      This is of course not possible in the IS_MEM case.  */
   if (! general_operand (a, GET_MODE (a)))
     {
-      rtx set;
+      rtx_insn *insn;
 
       if (is_mem)
        {
-         tmp = gen_reg_rtx (GET_MODE (a));
-         tmp = emit_insn (gen_rtx_SET (VOIDmode, tmp, a));
+         rtx reg = gen_reg_rtx (GET_MODE (a));
+         insn = emit_insn (gen_rtx_SET (VOIDmode, reg, a));
        }
       else if (! insn_a)
        goto end_seq_and_fail;
       else
        {
          a = gen_reg_rtx (GET_MODE (a));
-         tmp = copy_rtx (insn_a);
-         set = single_set (tmp);
+         rtx_insn *copy_of_a = as_a <rtx_insn *> (copy_rtx (insn_a));
+         rtx set = single_set (copy_of_a);
          SET_DEST (set) = a;
-         tmp = emit_insn (PATTERN (tmp));
+         insn = emit_insn (PATTERN (copy_of_a));
        }
-      if (recog_memoized (tmp) < 0)
+      if (recog_memoized (insn) < 0)
        goto end_seq_and_fail;
     }
   if (! general_operand (b, GET_MODE (b)))
     {
-      rtx set, last;
+      rtx pat;
+      rtx_insn *last;
+      rtx_insn *new_insn;
 
       if (is_mem)
        {
-          tmp = gen_reg_rtx (GET_MODE (b));
-         tmp = gen_rtx_SET (VOIDmode, tmp, b);
+          rtx reg = gen_reg_rtx (GET_MODE (b));
+         pat = gen_rtx_SET (VOIDmode, reg, b);
        }
       else if (! insn_b)
        goto end_seq_and_fail;
       else
        {
           b = gen_reg_rtx (GET_MODE (b));
-         tmp = copy_rtx (insn_b);
-         set = single_set (tmp);
+         rtx_insn *copy_of_insn_b = as_a <rtx_insn *> (copy_rtx (insn_b));
+         rtx set = single_set (copy_of_insn_b);
          SET_DEST (set) = b;
-         tmp = PATTERN (tmp);
+         pat = PATTERN (copy_of_insn_b);
        }
 
       /* If insn to set up A clobbers any registers B depends on, try to
@@ -1698,14 +1736,14 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
       last = get_last_insn ();
       if (last && modified_in_p (orig_b, last))
        {
-         tmp = emit_insn_before (tmp, get_insns ());
-         if (modified_in_p (orig_a, tmp))
+         new_insn = emit_insn_before (pat, get_insns ());
+         if (modified_in_p (orig_a, new_insn))
            goto end_seq_and_fail;
        }
       else
-       tmp = emit_insn (tmp);
+       new_insn = emit_insn (pat);
 
-      if (recog_memoized (tmp) < 0)
+      if (recog_memoized (new_insn) < 0)
        goto end_seq_and_fail;
     }
 
@@ -1718,29 +1756,30 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
   /* If we're handling a memory for above, emit the load now.  */
   if (is_mem)
     {
-      tmp = gen_rtx_MEM (GET_MODE (if_info->x), target);
+      rtx mem = gen_rtx_MEM (GET_MODE (if_info->x), target);
 
       /* Copy over flags as appropriate.  */
       if (MEM_VOLATILE_P (if_info->a) || MEM_VOLATILE_P (if_info->b))
-       MEM_VOLATILE_P (tmp) = 1;
+       MEM_VOLATILE_P (mem) = 1;
       if (MEM_ALIAS_SET (if_info->a) == MEM_ALIAS_SET (if_info->b))
-       set_mem_alias_set (tmp, MEM_ALIAS_SET (if_info->a));
-      set_mem_align (tmp,
+       set_mem_alias_set (mem, MEM_ALIAS_SET (if_info->a));
+      set_mem_align (mem,
                     MIN (MEM_ALIGN (if_info->a), MEM_ALIGN (if_info->b)));
 
       gcc_assert (MEM_ADDR_SPACE (if_info->a) == MEM_ADDR_SPACE (if_info->b));
-      set_mem_addr_space (tmp, MEM_ADDR_SPACE (if_info->a));
+      set_mem_addr_space (mem, MEM_ADDR_SPACE (if_info->a));
 
-      noce_emit_move_insn (if_info->x, tmp);
+      noce_emit_move_insn (if_info->x, mem);
     }
   else if (target != x)
     noce_emit_move_insn (x, target);
 
-  tmp = end_ifcvt_sequence (if_info);
-  if (!tmp)
+  ifcvt_seq = end_ifcvt_sequence (if_info);
+  if (!ifcvt_seq)
     return FALSE;
 
-  emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATION (if_info->insn_a));
+  emit_insn_before_setloc (ifcvt_seq, if_info->jump,
+                          INSN_LOCATION (if_info->insn_a));
   return TRUE;
 
  end_seq_and_fail:
@@ -1754,9 +1793,10 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
 
 static rtx
 noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
-                       rtx *earliest)
+                       rtx_insn **earliest)
 {
-  rtx cond, set, insn;
+  rtx cond, set;
+  rtx_insn *insn;
   int reverse;
 
   /* If target is already mentioned in the known condition, return it.  */
@@ -1770,7 +1810,7 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
   cond = XEXP (SET_SRC (set), 0);
   reverse
     = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
-      && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (if_info->jump);
+      && LABEL_REF_LABEL (XEXP (SET_SRC (set), 2)) == JUMP_LABEL (if_info->jump);
   if (if_info->then_else_reversed)
     reverse = !reverse;
 
@@ -1879,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;
 
@@ -1906,8 +1946,8 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
 static int
 noce_try_minmax (struct noce_if_info *if_info)
 {
-  rtx cond, earliest, target;
-  rtx_insn *seq;
+  rtx cond, target;
+  rtx_insn *earliest, *seq;
   enum rtx_code code, op;
   int unsignedp;
 
@@ -2002,8 +2042,8 @@ noce_try_minmax (struct noce_if_info *if_info)
 static int
 noce_try_abs (struct noce_if_info *if_info)
 {
-  rtx cond, earliest, target, a, b, c;
-  rtx_insn *seq;
+  rtx cond, target, a, b, c;
+  rtx_insn *earliest, *seq;
   int negate;
   bool one_cmpl = false;
 
@@ -2056,7 +2096,8 @@ noce_try_abs (struct noce_if_info *if_info)
      REG_EQUAL note or a simple source if necessary.  */
   if (REG_P (c))
     {
-      rtx set, insn = prev_nonnote_insn (earliest);
+      rtx set;
+      rtx_insn *insn = prev_nonnote_insn (earliest);
       if (insn
          && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (earliest)
          && (set = single_set (insn))
@@ -2150,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;
 
@@ -2229,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;
 
@@ -2330,7 +2371,7 @@ noce_try_bitop (struct noce_if_info *if_info)
    THEN block of the caller, and we have to reverse the condition.  */
 
 static rtx
-noce_get_condition (rtx jump, rtx *earliest, bool then_else_reversed)
+noce_get_condition (rtx_insn *jump, rtx_insn **earliest, bool then_else_reversed)
 {
   rtx cond, set, tmp;
   bool reverse;
@@ -2343,7 +2384,7 @@ noce_get_condition (rtx jump, rtx *earliest, bool then_else_reversed)
   /* If this branches to JUMP_LABEL when the condition is false,
      reverse the condition.  */
   reverse = (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
-            && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump));
+            && LABEL_REF_LABEL (XEXP (SET_SRC (set), 2)) == JUMP_LABEL (jump));
 
   /* We may have to reverse because the caller's if block is not canonical,
      i.e. the THEN block isn't the fallthrough block for the TEST block
@@ -2370,7 +2411,7 @@ noce_get_condition (rtx jump, rtx *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.  */
@@ -2498,7 +2539,7 @@ noce_process_if_block (struct noce_if_info *if_info)
   basic_block then_bb = if_info->then_bb;      /* THEN */
   basic_block else_bb = if_info->else_bb;      /* ELSE or NULL */
   basic_block join_bb = if_info->join_bb;      /* JOIN */
-  rtx jump = if_info->jump;
+  rtx_insn *jump = if_info->jump;
   rtx cond = if_info->cond;
   rtx_insn *insn_a, *insn_b;
   rtx set_a, set_b;
@@ -2913,7 +2954,7 @@ cond_move_process_if_block (struct noce_if_info *if_info)
   basic_block then_bb = if_info->then_bb;
   basic_block else_bb = if_info->else_bb;
   basic_block join_bb = if_info->join_bb;
-  rtx jump = if_info->jump;
+  rtx_insn *jump = if_info->jump;
   rtx cond = if_info->cond;
   rtx_insn *seq, *loc_insn;
   rtx reg;
@@ -3044,7 +3085,7 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge,
   bool then_else_reversed = false;
   rtx_insn *jump;
   rtx cond;
-  rtx cond_earliest;
+  rtx_insn *cond_earliest;
   struct noce_if_info if_info;
 
   /* We only ever should get here before reload.  */
@@ -3200,7 +3241,7 @@ merge_if_block (struct ce_if_block * ce_info)
       if (EDGE_COUNT (then_bb->succs) == 0
          && EDGE_COUNT (combo_bb->succs) > 1)
        {
-         rtx end = NEXT_INSN (BB_END (then_bb));
+         rtx_insn *end = NEXT_INSN (BB_END (then_bb));
          while (end && NOTE_P (end) && !NOTE_INSN_BASIC_BLOCK_P (end))
            end = NEXT_INSN (end);
 
@@ -3223,7 +3264,7 @@ merge_if_block (struct ce_if_block * ce_info)
       if (EDGE_COUNT (else_bb->succs) == 0
          && EDGE_COUNT (combo_bb->succs) > 1)
        {
-         rtx end = NEXT_INSN (BB_END (else_bb));
+         rtx_insn *end = NEXT_INSN (BB_END (else_bb));
          while (end && NOTE_P (end) && !NOTE_INSN_BASIC_BLOCK_P (end))
            end = NEXT_INSN (end);
 
@@ -3567,7 +3608,7 @@ cond_exec_find_if_block (struct ce_if_block * ce_info)
     {
       if (single_pred_p (else_bb) && else_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
        {
-         rtx last_insn = BB_END (then_bb);
+         rtx_insn *last_insn = BB_END (then_bb);
 
          while (last_insn
                 && NOTE_P (last_insn)
@@ -3698,7 +3739,8 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
   basic_block else_bb = else_edge->dest;
   basic_block other_bb, trap_bb;
   rtx_insn *trap, *jump;
-  rtx cond, cond_earliest, seq;
+  rtx cond, seq;
+  rtx_insn *cond_earliest;
   enum rtx_code code;
 
   /* Locate the block with the trap instruction.  */
@@ -4134,7 +4176,8 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
 {
   basic_block new_dest = dest_edge->dest;
   rtx_insn *head, *end, *jump;
-  rtx earliest = NULL_RTX, old_dest;
+  rtx_insn *earliest = NULL;
+  rtx old_dest;
   bitmap merge_set = NULL;
   /* Number of pending changes.  */
   int n_validated_changes = 0;
@@ -4284,14 +4327,13 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
        if (NONDEBUG_INSN_P (insn))
          df_simulate_find_defs (insn, merge_set);
 
-#ifdef HAVE_simple_return
       /* If shrink-wrapping, disable this optimization when test_bb is
         the first basic block and merge_bb exits.  The idea is to not
         move code setting up a return register as that may clobber a
         register used to pass function parameters, which then must be
         saved in caller-saved regs.  A caller-saved reg requires the
         prologue, killing a shrink-wrap opportunity.  */
-      if ((flag_shrink_wrap && HAVE_simple_return && !epilogue_completed)
+      if ((SHRINK_WRAPPING_ENABLED && !epilogue_completed)
          && ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb == test_bb
          && single_succ_p (new_dest)
          && single_succ (new_dest) == EXIT_BLOCK_PTR_FOR_FN (cfun)
@@ -4338,7 +4380,6 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
            }
          BITMAP_FREE (return_regs);
        }
-#endif
     }
 
  no_body:
@@ -4349,6 +4390,9 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
   old_dest = JUMP_LABEL (jump);
   if (other_bb != new_dest)
     {
+      if (!any_condjump_p (jump))
+       goto cancel;
+
       if (JUMP_P (BB_END (dest_edge->src)))
        new_dest_label = JUMP_LABEL (BB_END (dest_edge->src));
       else if (new_dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
@@ -4399,17 +4443,14 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
       insn = head;
       do
        {
-         rtx note, set;
+         rtx note;
 
          if (! INSN_P (insn))
            continue;
          note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
          if (! note)
            continue;
-         set = single_set (insn);
-         if (!set || !function_invariant_p (SET_SRC (set))
-             || !function_invariant_p (XEXP (note, 0)))
-           remove_note (insn, note);
+         remove_note (insn, note);
        } while (insn != end && (insn = NEXT_INSN (insn)));
 
       /* PR46315: when moving insns above a conditional branch, the REG_EQUAL