]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/ifcvt.c
Update copyright years.
[thirdparty/gcc.git] / gcc / ifcvt.c
index 9a646a692987a9d1eabb433b455ed5bfc626823e..a9ea7b1808d0498dd5a1dca8f1f9f0baef5be5b3 100644 (file)
@@ -1,5 +1,5 @@
 /* If-conversion support.
-   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   Copyright (C) 2000-2020 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
@@ -45,7 +45,6 @@
 #include "shrink-wrap.h"
 #include "rtl-iter.h"
 #include "ifcvt.h"
-#include "params.h"
 
 #ifndef MAX_CONDITIONAL_EXECUTE
 #define MAX_CONDITIONAL_EXECUTE \
@@ -121,7 +120,7 @@ count_bb_insns (const_basic_block bb)
   return count;
 }
 
-/* Determine whether the total insn_rtx_cost on non-jump insns in
+/* Determine whether the total insn_cost on non-jump insns in
    basic block BB is less than MAX_COST.  This function returns
    false if the cost of any instruction could not be estimated. 
 
@@ -140,7 +139,7 @@ cheap_bb_rtx_cost_p (const_basic_block bb,
              : REG_BR_PROB_BASE;
 
   /* Set scale to REG_BR_PROB_BASE to void the identical scaling
-     applied to insn_rtx_cost when optimizing for size.  Only do
+     applied to insn_cost when optimizing for size.  Only do
      this after combine because if-conversion might interfere with
      passes before combine.
 
@@ -163,7 +162,7 @@ cheap_bb_rtx_cost_p (const_basic_block bb,
     {
       if (NONJUMP_INSN_P (insn))
        {
-         int cost = insn_rtx_cost (PATTERN (insn), speed) * REG_BR_PROB_BASE;
+         int cost = insn_cost (insn, speed) * REG_BR_PROB_BASE;
          if (cost == 0)
            return false;
 
@@ -503,7 +502,7 @@ cond_exec_process_if_block (ce_if_block * ce_info,
     return FALSE;
 
   /* If the conditional jump is more than just a conditional jump,
-     then we can not do conditional execution conversion on this block.  */
+     then we cannot do conditional execution conversion on this block.  */
   if (! onlyjump_p (BB_END (test_bb)))
     return FALSE;
 
@@ -652,7 +651,7 @@ cond_exec_process_if_block (ce_if_block * ce_info,
            goto fail;
 
          /* If the conditional jump is more than just a conditional jump, then
-            we can not do conditional execution conversion on this block.  */
+            we cannot do conditional execution conversion on this block.  */
          if (! onlyjump_p (BB_END (bb)))
            goto fail;
 
@@ -894,7 +893,7 @@ noce_emit_move_insn (rtx x, rtx y)
 {
   machine_mode outmode;
   rtx outer, inner;
-  int bitpos;
+  poly_int64 bitpos;
 
   if (GET_CODE (x) != STRICT_LOW_PART)
     {
@@ -1287,7 +1286,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info)
   HOST_WIDE_INT itrue, ifalse, diff, tmp;
   int normalize;
   bool can_reverse;
-  machine_mode mode = GET_MODE (if_info->x);;
+  machine_mode mode = GET_MODE (if_info->x);
   rtx common = NULL_RTX;
 
   rtx a = if_info->a;
@@ -1724,12 +1723,12 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
     {
       rtx reg_vtrue = SUBREG_REG (vtrue);
       rtx reg_vfalse = SUBREG_REG (vfalse);
-      unsigned int byte_vtrue = SUBREG_BYTE (vtrue);
-      unsigned int byte_vfalse = SUBREG_BYTE (vfalse);
+      poly_uint64 byte_vtrue = SUBREG_BYTE (vtrue);
+      poly_uint64 byte_vfalse = SUBREG_BYTE (vfalse);
       rtx promoted_target;
 
       if (GET_MODE (reg_vtrue) != GET_MODE (reg_vfalse)
-         || byte_vtrue != byte_vfalse
+         || maybe_ne (byte_vtrue, byte_vfalse)
          || (SUBREG_PROMOTED_VAR_P (vtrue)
              != SUBREG_PROMOTED_VAR_P (vfalse))
          || (SUBREG_PROMOTED_GET (vtrue)
@@ -3021,7 +3020,7 @@ bb_valid_for_noce_process_p (basic_block test_bb, rtx cond,
   if (first_insn == last_insn)
     {
       *simple_p = noce_operand_ok (SET_DEST (first_set));
-      *cost += insn_rtx_cost (first_set, speed_p);
+      *cost += pattern_cost (first_set, speed_p);
       return *simple_p;
     }
 
@@ -3037,7 +3036,7 @@ bb_valid_for_noce_process_p (basic_block test_bb, rtx cond,
   /* The regs that are live out of test_bb.  */
   bitmap test_bb_live_out = df_get_live_out (test_bb);
 
-  int potential_cost = insn_rtx_cost (last_set, speed_p);
+  int potential_cost = pattern_cost (last_set, speed_p);
   rtx_insn *insn;
   FOR_BB_INSNS (test_bb, insn)
     {
@@ -3057,7 +3056,7 @@ bb_valid_for_noce_process_p (basic_block test_bb, rtx cond,
              || reg_overlap_mentioned_p (SET_DEST (sset), cond))
            goto free_bitmap_and_fail;
 
-         potential_cost += insn_rtx_cost (sset, speed_p);
+         potential_cost += pattern_cost (sset, speed_p);
          bitmap_set_bit (test_bb_temps, REGNO (SET_DEST (sset)));
        }
     }
@@ -3198,7 +3197,7 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
        {
          machine_mode src_mode = GET_MODE (new_val);
          machine_mode dst_mode = GET_MODE (temp);
-         if (GET_MODE_SIZE (src_mode) <= GET_MODE_SIZE (dst_mode))
+         if (!partial_subreg_p (dst_mode, src_mode))
            {
              end_sequence ();
              return FALSE;
@@ -3209,7 +3208,7 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
        {
          machine_mode src_mode = GET_MODE (old_val);
          machine_mode dst_mode = GET_MODE (temp);
-         if (GET_MODE_SIZE (src_mode) <= GET_MODE_SIZE (dst_mode))
+         if (!partial_subreg_p (dst_mode, src_mode))
            {
              end_sequence ();
              return FALSE;
@@ -3311,7 +3310,7 @@ 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);
+  unsigned param = param_max_rtl_if_conversion_insns;
 
   FOR_BB_INSNS (test_bb, insn)
     {
@@ -3358,6 +3357,16 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb)
   return count > 1 && count <= param;
 }
 
+/* Compute average of two given costs weighted by relative probabilities
+   of respective basic blocks in an IF-THEN-ELSE.  E is the IF-THEN edge.
+   With P as the probability to take the IF-THEN branch, return
+   P * THEN_COST + (1 - P) * ELSE_COST.  */
+static unsigned
+average_cost (unsigned then_cost, unsigned else_cost, edge e)
+{
+  return else_cost + e->probability.apply ((signed) (then_cost - else_cost));
+}
+
 /* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
    it without using conditional execution.  Return TRUE if we were successful
    at converting the block.  */
@@ -3413,10 +3422,9 @@ noce_process_if_block (struct noce_if_info *if_info)
                                       &if_info->else_simple))
     return false;
 
-  if (else_bb == NULL)
-    if_info->original_cost += then_cost;
-  else if (speed_p)
-    if_info->original_cost += MIN (then_cost, else_cost);
+  if (speed_p)
+    if_info->original_cost += average_cost (then_cost, else_cost,
+                                           find_edge (test_bb, then_bb));
   else
     if_info->original_cost += then_cost + else_cost;
 
@@ -3829,7 +3837,7 @@ cond_move_process_if_block (struct noce_if_info *if_info)
   vec<rtx> else_regs = vNULL;
   unsigned int i;
   int success_p = FALSE;
-  int limit = PARAM_VALUE (PARAM_MAX_RTL_IF_CONVERSION_INSNS);
+  int limit = param_max_rtl_if_conversion_insns;
 
   /* Build a mapping for each block to the value used for each
      register.  */
@@ -4022,7 +4030,7 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge,
     }
 
   /* If the conditional jump is more than just a conditional
-     jump, then we can not do if-conversion on this block.  */
+     jump, then we cannot do if-conversion on this block.  */
   jump = BB_END (test_bb);
   if (! onlyjump_p (jump))
     return FALSE;
@@ -4642,7 +4650,7 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
     return FALSE;
 
   /* If the conditional jump is more than just a conditional jump, then
-     we can not do if-conversion on this block.  Give up for returnjump_p,
+     we cannot do if-conversion on this block.  Give up for returnjump_p,
      changing a conditional return followed by unconditional trap for
      conditional trap followed by unconditional return is likely not
      beneficial and harder to handle.  */
@@ -5283,8 +5291,6 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
       redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);
       if (reversep)
        {
-         std::swap (BRANCH_EDGE (test_bb)->count,
-                    FALLTHRU_EDGE (test_bb)->count);
          std::swap (BRANCH_EDGE (test_bb)->probability,
                     FALLTHRU_EDGE (test_bb)->probability);
          update_br_prob_note (test_bb);
@@ -5448,6 +5454,10 @@ if_convert (bool after_combine)
   if (optimize == 1)
     df_remove_problem (df_live);
 
+  /* Some non-cold blocks may now be only reachable from cold blocks.
+     Fix that up.  */
+  fixup_partitions ();
+
   checking_verify_flow_info ();
 }
 \f
@@ -5455,6 +5465,8 @@ if_convert (bool after_combine)
 static unsigned int
 rest_of_handle_if_conversion (void)
 {
+  int flags = 0;
+
   if (flag_if_conversion)
     {
       if (dump_file)
@@ -5464,9 +5476,12 @@ rest_of_handle_if_conversion (void)
        }
       cleanup_cfg (CLEANUP_EXPENSIVE);
       if_convert (false);
+      if (num_updated_if_blocks)
+       /* Get rid of any dead CC-related instructions.  */
+       flags |= CLEANUP_FORCE_FAST_DCE;
     }
 
-  cleanup_cfg (0);
+  cleanup_cfg (flags);
   return 0;
 }