rtlanal.c (insn_rtx_cost): New function, moved and renamed from combine.c's combine_i...
authorRoger Sayle <roger@eyesopen.com>
Sun, 11 Jul 2004 14:37:57 +0000 (14:37 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Sun, 11 Jul 2004 14:37:57 +0000 (14:37 +0000)
* rtlanal.c (insn_rtx_cost): New function, moved and renamed from
combine.c's combine_insn_cost.
* rtl.h (insn_rtx_cost): Prototype here.
* combine.c (combine_insn_cost): Delete function.
(combine_validate_cost): Update callers of combine_insn_cost to
call insn_rtx_cost instead.
(combine_instructions): Likewise.  Use NONJUMP_INSN_P to avoid
requesting the rtx_cost of call and/or jump instructions.

* ifcvt.c (total_bb_rtx_cost): Use insn_rtx_cost instead of calling
rtx_cost directly.  Don't request/use the cost of call or jump
instructions.  Return -1 if the cost of any instruction can't be
determined (or the BB contains a function call).
(find_if_case_1): Abort transformation if total_bb_rtx_cost returns
-1 (i.e. can't determine the cost of any instruction or the basic
block contains a subroutine call).
(find_if_case_2): Likewise.

From-SVN: r84513

gcc/ChangeLog
gcc/combine.c
gcc/ifcvt.c
gcc/rtl.h
gcc/rtlanal.c

index 0eaf63705c26f91be08c34696cc53c707d184956..d52f351748702339eba72beba952355d40b218f4 100644 (file)
@@ -1,3 +1,23 @@
+2004-07-11  Roger Sayle  <roger@eyesopen.com>
+
+       * rtlanal.c (insn_rtx_cost): New function, moved and renamed from
+       combine.c's combine_insn_cost.
+       * rtl.h (insn_rtx_cost): Prototype here.
+       * combine.c (combine_insn_cost): Delete function.
+       (combine_validate_cost): Update callers of combine_insn_cost to
+       call insn_rtx_cost instead.
+       (combine_instructions): Likewise.  Use NONJUMP_INSN_P to avoid
+       requesting the rtx_cost of call and/or jump instructions.
+
+       * ifcvt.c (total_bb_rtx_cost): Use insn_rtx_cost instead of calling
+       rtx_cost directly.  Don't request/use the cost of call or jump
+       instructions.  Return -1 if the cost of any instruction can't be
+       determined (or the BB contains a function call).
+       (find_if_case_1): Abort transformation if total_bb_rtx_cost returns
+       -1 (i.e. can't determine the cost of any instruction or the basic
+       block contains a subroutine call).
+       (find_if_case_2): Likewise.
+
 2004-07-11  Roger Sayle  <roger@eyesopen.com>
 
        * rs6000.c (struct processor_costs): Change semantics of fields to
index 97198b5df4f4f01889a3f5d7f715df9af52a47c4..1bdceb5ef9c500a3b0e2410b847f93e3b3e3d574 100644 (file)
@@ -284,7 +284,7 @@ static basic_block this_basic_block;
    those blocks as starting points.  */
 static sbitmap refresh_blocks;
 \f
-/* The following array records the combine_insn_cost for every insn
+/* The following array records the insn_rtx_cost for every insn
    in the instruction stream.  */
 
 static int *uid_insn_cost;
@@ -515,44 +515,8 @@ do_SUBST_INT (int *into, int newval)
 
 #define SUBST_INT(INTO, NEWVAL)  do_SUBST_INT(&(INTO), (NEWVAL))
 \f
-/* Calculate the rtx_cost of a single instruction.  A return value of zero
-   indicates an instruction without a known cost.  */
-
-static int
-combine_insn_cost (rtx pat)
-{
-  int i, cost;
-  rtx set;
-
-  /* Extract the single set rtx from the instruction pattern.
-     We can't use single_set since we only have the pattern.  */
-  if (GET_CODE (pat) == SET)
-    set = pat;
-  else if (GET_CODE (pat) == PARALLEL)
-    {
-      set = NULL_RTX;
-      for (i = 0; i < XVECLEN (pat, 0); i++)
-       {
-         rtx x = XVECEXP (pat, 0, i);
-         if (GET_CODE (x) == SET)
-           {
-             if (set)
-               return 0;
-             set = x;
-           }
-       }
-      if (!set)
-       return 0;
-    }
-  else
-    return 0;
-
-  cost = rtx_cost (SET_SRC (set), SET);
-  return cost > 0 ? cost : COSTS_N_INSNS (1);
-}
-
 /* Subroutine of try_combine.  Determine whether the combine replacement
-   patterns NEWPAT and NEWI2PAT are cheaper according to combine_insn_cost
+   patterns NEWPAT and NEWI2PAT are cheaper according to insn_rtx_cost
    that the original instruction sequence I1, I2 and I3.  Note that I1
    and/or NEWI2PAT may be NULL_RTX.  This function returns false, if the
    costs of all instructions can be estimated, and the replacements are
@@ -565,7 +529,7 @@ combine_validate_cost (rtx i1, rtx i2, rtx i3, rtx newpat, rtx newi2pat)
   int new_i2_cost, new_i3_cost;
   int old_cost, new_cost;
 
-  /* Lookup the original combine_insn_costs.  */
+  /* Lookup the original insn_rtx_costs.  */
   i2_cost = INSN_UID (i2) <= last_insn_cost
            ? uid_insn_cost[INSN_UID (i2)] : 0;
   i3_cost = INSN_UID (i3) <= last_insn_cost
@@ -584,11 +548,11 @@ combine_validate_cost (rtx i1, rtx i2, rtx i3, rtx newpat, rtx newi2pat)
       i1_cost = 0;
     }
 
-  /* Calculate the replacement combine_insn_costs.  */
-  new_i3_cost = combine_insn_cost (newpat);
+  /* Calculate the replacement insn_rtx_costs.  */
+  new_i3_cost = insn_rtx_cost (newpat);
   if (newi2pat)
     {
-      new_i2_cost = combine_insn_cost (newi2pat);
+      new_i2_cost = insn_rtx_cost (newi2pat);
       new_cost = (new_i2_cost > 0 && new_i3_cost > 0)
                 ? new_i2_cost + new_i3_cost : 0;
     }
@@ -708,7 +672,7 @@ combine_instructions (rtx f, unsigned int nregs)
   refresh_blocks = sbitmap_alloc (last_basic_block);
   sbitmap_zero (refresh_blocks);
 
-  /* Allocate array of current combine_insn_costs.  */
+  /* Allocate array of current insn_rtx_costs.  */
   uid_insn_cost = xcalloc (max_uid_cuid + 1, sizeof (int));
   last_insn_cost = max_uid_cuid;
 
@@ -731,8 +695,9 @@ combine_instructions (rtx f, unsigned int nregs)
                                                NULL);
 #endif
 
-         /* Record the current combine_insn_cost of this instruction.  */
-         uid_insn_cost[INSN_UID (insn)] = combine_insn_cost (PATTERN (insn));
+         /* Record the current insn_rtx_cost of this instruction.  */
+         if (NONJUMP_INSN_P (insn))
+           uid_insn_cost[INSN_UID (insn)] = insn_rtx_cost (PATTERN (insn));
          if (dump_file)
            fprintf(dump_file, "insn_cost %d: %d\n",
                    INSN_UID (insn), uid_insn_cost[INSN_UID (insn)]);
@@ -2655,7 +2620,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
   }
 #endif
 
-  /* Only allow this combination if combine_insn_costs reports that the
+  /* Only allow this combination if insn_rtx_costs reports that the
      replacement instructions are cheaper than the originals.  */
   if (!combine_validate_cost (i1, i2, i3, newpat, newi2pat))
     {
index 457fb37bdf04663795b17e6cc90e2d9476262605..ac478af71ba78ea29427f9b35e27b06b8346875b 100644 (file)
@@ -161,7 +161,9 @@ count_bb_insns (basic_block bb)
   return count;
 }
 
-/* Count the total rtx_cost of non-jump active insns in BB.  */
+/* Count the total insn_rtx_cost of non-jump active insns in BB.
+   This function returns -1, if the cost of any instruction could
+   not be estimated.  */
 
 static int
 total_bb_rtx_cost (basic_block bb)
@@ -171,9 +173,16 @@ total_bb_rtx_cost (basic_block bb)
 
   while (1)
     {
-      if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == INSN)
-       count += rtx_cost (PATTERN (insn), 0);
-
+      if (NONJUMP_INSN_P (insn))
+       {
+         int cost = insn_rtx_cost (PATTERN (insn));
+         if (cost == 0)
+           return -1;
+         count += cost;
+       }
+      else if (CALL_P (insn))
+       return -1;
       if (insn == BB_END (bb))
        break;
       insn = NEXT_INSN (insn);
@@ -2867,7 +2876,7 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
   basic_block then_bb = then_edge->dest;
   basic_block else_bb = else_edge->dest, new_bb;
   edge then_succ = then_bb->succ;
-  int then_bb_index;
+  int then_bb_index, bb_cost;
 
   /* If we are partitioning hot/cold basic blocks, we don't want to
      mess up unconditional or indirect jumps that cross between hot
@@ -2904,7 +2913,8 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
             test_bb->index, then_bb->index);
 
   /* THEN is small.  */
-  if (total_bb_rtx_cost (then_bb) >= COSTS_N_INSNS (BRANCH_COST))
+  bb_cost = total_bb_rtx_cost (then_bb);
+  if (bb_cost < 0 || bb_cost >= COSTS_N_INSNS (BRANCH_COST))
     return FALSE;
 
   /* Registers set are dead, or are predicable.  */
@@ -2947,6 +2957,7 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
   basic_block then_bb = then_edge->dest;
   basic_block else_bb = else_edge->dest;
   edge else_succ = else_bb->succ;
+  int bb_cost;
   rtx note;
 
   /* If we are partitioning hot/cold basic blocks, we don't want to
@@ -2995,7 +3006,8 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
             test_bb->index, else_bb->index);
 
   /* ELSE is small.  */
-  if (total_bb_rtx_cost (else_bb) >= COSTS_N_INSNS (BRANCH_COST))
+  bb_cost = total_bb_rtx_cost (else_bb);
+  if (bb_cost < 0 || bb_cost >= COSTS_N_INSNS (BRANCH_COST))
     return FALSE;
 
   /* Registers set are dead, or are predicable.  */
index f9495b53d231ab1a46ffb76b4cc92f5026025dc7..bc87dd280e0f4e7ed3f04de66437ffeb474888c7 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1879,6 +1879,7 @@ extern int loc_mentioned_in_p (rtx *, rtx);
 extern rtx find_first_parameter_load (rtx, rtx);
 extern bool keep_with_call_p (rtx);
 extern bool label_is_jump_target_p (rtx, rtx);
+extern int insn_rtx_cost (rtx);
 
 /* flow.c */
 
index b802e3f55d6b4ec44b33738e60bddcab73e79047..81d4f4024f57c48258b42cf8fc50d5d693c558a2 100644 (file)
@@ -4785,3 +4785,39 @@ num_sign_bit_copies1 (rtx x, enum machine_mode mode, rtx known_x,
   return nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))
         ? 1 : bitwidth - floor_log2 (nonzero) - 1;
 }
+
+/* Calculate the rtx_cost of a single instruction.  A return value of
+   zero indicates an instruction pattern without a known cost.  */
+
+int
+insn_rtx_cost (rtx pat)
+{
+  int i, cost;
+  rtx set;
+
+  /* Extract the single set rtx from the instruction pattern.
+     We can't use single_set since we only have the pattern.  */
+  if (GET_CODE (pat) == SET)
+    set = pat;
+  else if (GET_CODE (pat) == PARALLEL)
+    {
+      set = NULL_RTX;
+      for (i = 0; i < XVECLEN (pat, 0); i++)
+       {
+         rtx x = XVECEXP (pat, 0, i);
+         if (GET_CODE (x) == SET)
+           {
+             if (set)
+               return 0;
+             set = x;
+           }
+       }
+      if (!set)
+       return 0;
+    }
+  else
+    return 0;
+
+  cost = rtx_cost (SET_SRC (set), SET);
+  return cost > 0 ? cost : COSTS_N_INSNS (1);
+}