OSDN Git Service

* tree-vect-transform.c (vect_min_worthwhile_factor): Declare.
[pf3gnuchains/gcc-fork.git] / gcc / modulo-sched.c
index a2443c1..b436811 100644 (file)
@@ -17,8 +17,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 
 #include "config.h"
@@ -105,8 +105,6 @@ typedef struct ps_insn *ps_insn_ptr;
 #define PS_STAGE_COUNT(ps) ((PS_MAX_CYCLE (ps) - PS_MIN_CYCLE (ps) \
                             + 1 + (ps)->ii - 1) / (ps)->ii)
 
-#define CFG_HOOKS cfg_layout_rtl_cfg_hooks
-
 /* A single instruction in the partial schedule.  */
 struct ps_insn
 {
@@ -271,74 +269,35 @@ static struct sched_info sms_sched_info =
 };
 
 
-/* Return the register decremented and tested or zero if it is not a decrement
-   and branch jump insn (similar to doloop_condition_get).  */
+/* Return the register decremented and tested in INSN,
+   or zero if it is not a decrement-and-branch insn.  */
+
 static rtx
-doloop_register_get (rtx insn, rtx *comp)
+doloop_register_get (rtx insn ATTRIBUTE_UNUSED)
 {
-  rtx pattern, cmp, inc, reg, condition;
-
-  if (!JUMP_P (insn))
-    return NULL_RTX;
-  pattern = PATTERN (insn);
-
-  /* The canonical doloop pattern we expect is:
-
-     (parallel [(set (pc) (if_then_else (condition)
-                                       (label_ref (label))
-                                       (pc)))
-               (set (reg) (plus (reg) (const_int -1)))
-               (additional clobbers and uses)])
-
-    where condition is further restricted to be
-      (ne (reg) (const_int 1)).  */
-
-  if (GET_CODE (pattern) != PARALLEL)
-    return NULL_RTX;
-
-  cmp = XVECEXP (pattern, 0, 0);
-  inc = XVECEXP (pattern, 0, 1);
-  /* Return the compare rtx.  */
-  *comp = cmp;
-
-  /* Check for (set (reg) (something)).  */
-  if (GET_CODE (inc) != SET || ! REG_P (SET_DEST (inc)))
-    return NULL_RTX;
-
-  /* Extract loop counter register.  */
-  reg = SET_DEST (inc);
+#ifdef HAVE_doloop_end
+  rtx pattern, reg, condition;
 
-  /* Check if something = (plus (reg) (const_int -1)).  */
-  if (GET_CODE (SET_SRC (inc)) != PLUS
-      || XEXP (SET_SRC (inc), 0) != reg
-      || XEXP (SET_SRC (inc), 1) != constm1_rtx)
+  if (! JUMP_P (insn))
     return NULL_RTX;
 
-  /* Check for (set (pc) (if_then_else (condition)
-                                      (label_ref (label))
-                                      (pc))).  */
-  if (GET_CODE (cmp) != SET
-      || SET_DEST (cmp) != pc_rtx
-      || GET_CODE (SET_SRC (cmp)) != IF_THEN_ELSE
-      || GET_CODE (XEXP (SET_SRC (cmp), 1)) != LABEL_REF
-      || XEXP (SET_SRC (cmp), 2) != pc_rtx)
-    return NULL_RTX;
-
-  /* Extract loop termination condition.  */
-  condition = XEXP (SET_SRC (cmp), 0);
-
-  /* Check if condition = (ne (reg) (const_int 1)), which is more
-     restrictive than the check in doloop_condition_get:
-     if ((GET_CODE (condition) != GE && GET_CODE (condition) != NE)
-        || GET_CODE (XEXP (condition, 1)) != CONST_INT).  */
-  if (GET_CODE (condition) != NE
-      || XEXP (condition, 1) != const1_rtx)
+  pattern = PATTERN (insn);
+  condition = doloop_condition_get (pattern);
+  if (! condition)
     return NULL_RTX;
 
-  if (XEXP (condition, 0) == reg)
-    return reg;
+  if (REG_P (XEXP (condition, 0)))
+    reg = XEXP (condition, 0);
+  else if (GET_CODE (XEXP (condition, 0)) == PLUS
+          && REG_P (XEXP (XEXP (condition, 0), 0)))
+    reg = XEXP (XEXP (condition, 0), 0);
+  else
+    gcc_unreachable ();
 
+  return reg;
+#else
   return NULL_RTX;
+#endif
 }
 
 /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so
@@ -540,9 +499,10 @@ generate_reg_moves (partial_schedule_ptr ps)
 
       for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
        {
-         int i_use;
+         unsigned int i_use;
          rtx new_reg = gen_reg_rtx (GET_MODE (prev_reg));
          rtx reg_move = gen_move_insn (new_reg, prev_reg);
+         sbitmap_iterator sbi;
 
          add_insn_before (reg_move, last_reg_move);
          last_reg_move = reg_move;
@@ -550,7 +510,7 @@ generate_reg_moves (partial_schedule_ptr ps)
          if (!SCHED_FIRST_REG_MOVE (u))
            SCHED_FIRST_REG_MOVE (u) = reg_move;
 
-         EXECUTE_IF_SET_IN_SBITMAP (uses_of_defs[i_reg_move], 0, i_use,
+         EXECUTE_IF_SET_IN_SBITMAP (uses_of_defs[i_reg_move], 0, i_use, sbi)
            {
              struct undo_replace_buff_elem *rep;
 
@@ -569,7 +529,7 @@ generate_reg_moves (partial_schedule_ptr ps)
                }
 
              replace_rtx (g->nodes[i_use].insn, old_reg, new_reg);
-           });
+           }
 
          prev_reg = new_reg;
        }
@@ -599,6 +559,7 @@ undo_generate_reg_moves (partial_schedule_ptr ps,
          delete_insn (crr);
          crr = prev;
        }
+      SCHED_FIRST_REG_MOVE (u) = NULL_RTX;
     }
 
   while (reg_move_replaces)
@@ -640,8 +601,7 @@ normalize_sched_times (partial_schedule_ptr ps)
       ddg_node_ptr u = &g->nodes[i];
       int normalized_time = SCHED_TIME (u) - amount;
 
-      if (normalized_time < 0)
-       abort ();
+      gcc_assert (normalized_time >= 0);
 
       SCHED_TIME (u) = normalized_time;
       SCHED_ROW (u) = normalized_time % ii;
@@ -934,7 +894,7 @@ canon_loop (struct loop *loop)
 
 /* Build the loop information without loop
    canonization, the loop canonization will
-   be perfromed if the loop is SMSable.  */
+   be performed if the loop is SMSable.  */
 static struct loops *
 build_loops_structure (FILE *dumpfile)
 {
@@ -1003,7 +963,7 @@ sms_schedule (FILE *dump_file)
       int temp = reload_completed;
 
       reload_completed = 1;
-      issue_rate = (*targetm.sched.issue_rate) ();
+      issue_rate = targetm.sched.issue_rate ();
       reload_completed = temp;
     }
   else
@@ -1027,7 +987,7 @@ sms_schedule (FILE *dump_file)
   for (i = 0; i < loops->num; i++)
     {
       rtx head, tail;
-      rtx count_reg, comp;
+      rtx count_reg;
       struct loop *loop = loops->parray[i];
 
       /* For debugging.  */
@@ -1090,7 +1050,7 @@ sms_schedule (FILE *dump_file)
         }
 
       /* Make sure this is a doloop.  */
-      if ( !(count_reg = doloop_register_get (tail, &comp)))
+      if ( !(count_reg = doloop_register_get (tail)))
        continue;
 
       /* Don't handle BBs with calls or barriers, or !single_set insns.  */
@@ -1136,7 +1096,7 @@ sms_schedule (FILE *dump_file)
   for (i = 0; i < num_loops; i++)
     {
       rtx head, tail;
-      rtx count_reg, count_init, comp;
+      rtx count_reg, count_init;
       int mii, rec_mii;
       unsigned stage_count = 0;
       HOST_WIDEST_INT loop_count = 0;
@@ -1188,7 +1148,7 @@ sms_schedule (FILE *dump_file)
       /* In case of th loop have doloop register it gets special
         handling.  */
       count_init = NULL_RTX;
-      if ((count_reg = doloop_register_get (tail, &comp)))
+      if ((count_reg = doloop_register_get (tail)))
        {
          basic_block pre_header;
 
@@ -1286,7 +1246,7 @@ sms_schedule (FILE *dump_file)
              /* SMS is not profitable so undo the permutation and reg move generation
                 and return the kernel to its original state.  */
              if (dump_file)
-               fprintf (dump_file, "Undoing SMS becuase it is not profitable.\n");
+               fprintf (dump_file, "Undoing SMS because it is not profitable.\n");
 
            }
          else
@@ -1417,11 +1377,11 @@ sms_schedule (FILE *dump_file)
 #define DFA_HISTORY SMS_DFA_HISTORY
 
 /* Given the partial schedule PS, this function calculates and returns the
-   cycles in wich we can schedule the node with the given index I.
+   cycles in which we can schedule the node with the given index I.
    NOTE: Here we do the backtracking in SMS, in some special cases. We have
    noticed that there are several cases in which we fail    to SMS the loop
    because the sched window of a node is empty    due to tight data-deps. In
-   such cases we want to unschedule    some of the predecssors/successors
+   such cases we want to unschedule    some of the predecessors/successors
    until we get non-empty    scheduling window.  It returns -1 if the
    scheduling window is empty and zero otherwise.  */
 
@@ -1735,8 +1695,7 @@ check_nodes_order (int *node_order, int num_nodes)
     {
       int u = node_order[i];
 
-      if (u >= num_nodes || u < 0 || TEST_BIT (tmp, u))
-       abort ();
+      gcc_assert (u < num_nodes && u >= 0 && !TEST_BIT (tmp, u));
 
       SET_BIT (tmp, u);
     }
@@ -1884,11 +1843,12 @@ calculate_order_params (ddg_ptr g, int mii ATTRIBUTE_UNUSED)
 static int
 find_max_asap (ddg_ptr g, sbitmap nodes)
 {
-  int u;
+  unsigned int u;
   int max_asap = -1;
   int result = -1;
+  sbitmap_iterator sbi;
 
-  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
+  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
     {
       ddg_node_ptr u_node = &g->nodes[u];
 
@@ -1897,19 +1857,20 @@ find_max_asap (ddg_ptr g, sbitmap nodes)
          max_asap = ASAP (u_node);
          result = u;
        }
-    });
+    }
   return result;
 }
 
 static int
 find_max_hv_min_mob (ddg_ptr g, sbitmap nodes)
 {
-  int u;
+  unsigned int u;
   int max_hv = -1;
   int min_mob = INT_MAX;
   int result = -1;
+  sbitmap_iterator sbi;
 
-  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
+  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
     {
       ddg_node_ptr u_node = &g->nodes[u];
 
@@ -1925,19 +1886,20 @@ find_max_hv_min_mob (ddg_ptr g, sbitmap nodes)
          min_mob = MOB (u_node);
          result = u;
        }
-    });
+    }
   return result;
 }
 
 static int
 find_max_dv_min_mob (ddg_ptr g, sbitmap nodes)
 {
-  int u;
+  unsigned int u;
   int max_dv = -1;
   int min_mob = INT_MAX;
   int result = -1;
+  sbitmap_iterator sbi;
 
-  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
+  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
     {
       ddg_node_ptr u_node = &g->nodes[u];
 
@@ -1953,7 +1915,7 @@ find_max_dv_min_mob (ddg_ptr g, sbitmap nodes)
          min_mob = MOB (u_node);
          result = u;
        }
-    });
+    }
   return result;
 }
 
@@ -2346,13 +2308,13 @@ advance_one_cycle (void)
 {
   if (targetm.sched.dfa_pre_cycle_insn)
     state_transition (curr_state,
-                     (*targetm.sched.dfa_pre_cycle_insn) ());
+                     targetm.sched.dfa_pre_cycle_insn ());
 
   state_transition (curr_state, NULL);
 
   if (targetm.sched.dfa_post_cycle_insn)
     state_transition (curr_state,
-                     (*targetm.sched.dfa_post_cycle_insn) ());
+                     targetm.sched.dfa_post_cycle_insn ());
 }
 
 /* Given the kernel of a loop (from FIRST_INSN to LAST_INSN), finds
@@ -2396,8 +2358,8 @@ kernel_number_of_cycles (rtx first_insn, rtx last_insn)
 
       if (targetm.sched.variable_issue)
        can_issue_more =
-         (*targetm.sched.variable_issue) (sched_dump, sched_verbose,
-                                          insn, can_issue_more);
+         targetm.sched.variable_issue (sched_dump, sched_verbose,
+                                       insn, can_issue_more);
       /* A naked CLOBBER or USE generates no instruction, so don't
         let them consume issue slots.  */
       else if (GET_CODE (PATTERN (insn)) != USE
@@ -2444,8 +2406,8 @@ ps_has_conflicts (partial_schedule_ptr ps, int from, int to)
 
          if (targetm.sched.variable_issue)
            can_issue_more =
-             (*targetm.sched.variable_issue) (sched_dump, sched_verbose,
-                                              insn, can_issue_more);
+             targetm.sched.variable_issue (sched_dump, sched_verbose,
+                                           insn, can_issue_more);
          /* A naked CLOBBER or USE generates no instruction, so don't
             let them consume issue slots.  */
          else if (GET_CODE (PATTERN (insn)) != USE
@@ -2535,8 +2497,8 @@ rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle)
   ps->min_cycle -= start_cycle;
 }
 
-/* Remove the node N from the partial schedule PS; becuase we restart the DFA
-   each time we want to check for resuorce conflicts; this is equivalent to
+/* Remove the node N from the partial schedule PS; because we restart the DFA
+   each time we want to check for resource conflicts; this is equivalent to
    unscheduling the node N.  */
 static bool
 ps_unschedule_node (partial_schedule_ptr ps, ddg_node_ptr n)