OSDN Git Service

[gcc/ChangeLog]
[pf3gnuchains/gcc-fork.git] / gcc / sched-rgn.c
index cebb389..673416f 100644 (file)
@@ -1,6 +1,6 @@
 /* Instruction scheduling pass.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
    and currently maintained by, Jim Wilson (wilson@cygnus.com)
 
@@ -155,7 +155,7 @@ static int *containing_rgn;
 
 void debug_regions (void);
 static void find_single_block_region (void);
-static void find_rgns (struct edge_list *, dominance_info);
+static void find_rgns (struct edge_list *);
 static int too_large (int, int *, int *);
 
 extern void debug_live (int, int);
@@ -343,10 +343,10 @@ is_cfg_nonregular (void)
      the cfg not well structured.  */
   /* Check for labels referred to other thn by jumps.  */
   FOR_EACH_BB (b)
-    for (insn = b->head;; insn = NEXT_INSN (insn))
+    for (insn = BB_HEAD (b); ; insn = NEXT_INSN (insn))
       {
        code = GET_CODE (insn);
-       if (GET_RTX_CLASS (code) == 'i' && code != JUMP_INSN)
+       if (INSN_P (insn) && code != JUMP_INSN)
          {
            rtx note = find_reg_note (insn, REG_LABEL, NULL_RTX);
 
@@ -357,7 +357,7 @@ is_cfg_nonregular (void)
              return 1;
          }
 
-       if (insn == b->end)
+       if (insn == BB_END (b))
          break;
       }
 
@@ -398,9 +398,9 @@ build_control_flow (struct edge_list *edge_list)
     }
 
   /* ??? We can kill these soon.  */
-  in_edges = (int *) xcalloc (last_basic_block, sizeof (int));
-  out_edges = (int *) xcalloc (last_basic_block, sizeof (int));
-  edge_table = (haifa_edge *) xcalloc (num_edges, sizeof (haifa_edge));
+  in_edges = xcalloc (last_basic_block, sizeof (int));
+  out_edges = xcalloc (last_basic_block, sizeof (int));
+  edge_table = xcalloc (num_edges, sizeof (haifa_edge));
 
   nr_edges = 0;
   for (i = 0; i < num_edges; i++)
@@ -558,8 +558,8 @@ static int
 too_large (int block, int *num_bbs, int *num_insns)
 {
   (*num_bbs)++;
-  (*num_insns) += (INSN_LUID (BLOCK_END (block)) -
-                  INSN_LUID (BLOCK_HEAD (block)));
+  (*num_insns) += (INSN_LUID (BB_END (BASIC_BLOCK (block))) -
+                  INSN_LUID (BB_HEAD (BASIC_BLOCK (block))));
   if ((*num_bbs > MAX_RGN_BLOCKS) || (*num_insns > MAX_RGN_INSNS))
     return 1;
   else
@@ -613,12 +613,13 @@ too_large (int block, int *num_bbs, int *num_insns)
    of edge tables.  That would simplify it somewhat.  */
 
 static void
-find_rgns (struct edge_list *edge_list, dominance_info dom)
+find_rgns (struct edge_list *edge_list)
 {
   int *max_hdr, *dfs_nr, *stack, *degree;
   char no_loops = 1;
   int node, child, loop_head, i, head, tail;
-  int count = 0, sp, idx = 0, current_edge = out_edges[0];
+  int count = 0, sp, idx = 0;
+  int current_edge = out_edges[ENTRY_BLOCK_PTR->succ->dest->index];
   int num_bbs, num_insns, unreachable;
   int too_large_failure;
   basic_block bb;
@@ -650,9 +651,9 @@ find_rgns (struct edge_list *edge_list, dominance_info dom)
      STACK, SP and DFS_NR are only used during the first traversal.  */
 
   /* Allocate and initialize variables for the first traversal.  */
-  max_hdr = (int *) xmalloc (last_basic_block * sizeof (int));
-  dfs_nr = (int *) xcalloc (last_basic_block, sizeof (int));
-  stack = (int *) xmalloc (nr_edges * sizeof (int));
+  max_hdr = xmalloc (last_basic_block * sizeof (int));
+  dfs_nr = xcalloc (last_basic_block, sizeof (int));
+  stack = xmalloc (nr_edges * sizeof (int));
 
   inner = sbitmap_alloc (last_basic_block);
   sbitmap_ones (inner);
@@ -796,7 +797,7 @@ find_rgns (struct edge_list *edge_list, dominance_info dom)
       /* Second traversal:find reducible inner loops and topologically sort
         block of each region.  */
 
-      queue = (int *) xmalloc (n_basic_blocks * sizeof (int));
+      queue = xmalloc (n_basic_blocks * sizeof (int));
 
       /* Find blocks which are inner loop headers.  We still have non-reducible
         loops to consider at this point.  */
@@ -826,7 +827,7 @@ find_rgns (struct edge_list *edge_list, dominance_info dom)
                    {
                      /* Now verify that the block is dominated by the loop
                         header.  */
-                     if (!dominated_by_p (dom, jbb, bb))
+                     if (!dominated_by_p (CDI_DOMINATORS, jbb, bb))
                        break;
                    }
                }
@@ -851,8 +852,8 @@ find_rgns (struct edge_list *edge_list, dominance_info dom)
 
              /* Estimate # insns, and count # blocks in the region.  */
              num_bbs = 1;
-             num_insns = (INSN_LUID (bb->end)
-                          - INSN_LUID (bb->head));
+             num_insns = (INSN_LUID (BB_END (bb))
+                          - INSN_LUID (BB_HEAD (bb)));
 
              /* Find all loop latches (blocks with back edges to the loop
                 header) or all the leaf blocks in the cfg has no loops.
@@ -1117,7 +1118,7 @@ compute_dom_prob_ps (int bb)
 static void
 split_edges (int bb_src, int bb_trg, edgelst *bl)
 {
-  sbitmap src = (edgeset) sbitmap_alloc (pot_split[bb_src]->n_bits);
+  sbitmap src = sbitmap_alloc (pot_split[bb_src]->n_bits);
   sbitmap_copy (src, pot_split[bb_src]);
 
   sbitmap_difference (src, src, pot_split[bb_trg]);
@@ -1181,7 +1182,7 @@ compute_trg_info (int trg)
             add the TO block to the update block list.  This list can end
             up with a lot of duplicates.  We need to weed them out to avoid
             overrunning the end of the bblst_table.  */
-         update_blocks = (char *) alloca (last_basic_block);
+         update_blocks = alloca (last_basic_block);
          memset (update_blocks, 0, last_basic_block);
 
          update_idx = 0;
@@ -1322,7 +1323,7 @@ check_live_1 (int src, rtx x)
       if (regno < FIRST_PSEUDO_REGISTER)
        {
          /* Check for hard registers.  */
-         int j = HARD_REGNO_NREGS (regno, GET_MODE (reg));
+         int j = hard_regno_nregs[regno][GET_MODE (reg)];
          while (--j >= 0)
            {
              for (i = 0; i < candidate_table[src].split_bbs.nr_members; i++)
@@ -1339,7 +1340,7 @@ check_live_1 (int src, rtx x)
        }
       else
        {
-         /* Check for psuedo registers.  */
+         /* Check for pseudo registers.  */
          for (i = 0; i < candidate_table[src].split_bbs.nr_members; i++)
            {
              int b = candidate_table[src].split_bbs.first_member[i];
@@ -1396,7 +1397,7 @@ update_live_1 (int src, rtx x)
     {
       if (regno < FIRST_PSEUDO_REGISTER)
        {
-         int j = HARD_REGNO_NREGS (regno, GET_MODE (reg));
+         int j = hard_regno_nregs[regno][GET_MODE (reg)];
          while (--j >= 0)
            {
              for (i = 0; i < candidate_table[src].update_bbs.nr_members; i++)
@@ -1701,7 +1702,7 @@ static int schedule_more_p (void);
 static const char *rgn_print_insn (rtx, int);
 static int rgn_rank (rtx, rtx);
 static int contributes_to_priority (rtx, rtx);
-static void compute_jump_reg_dependencies (rtx, regset);
+static void compute_jump_reg_dependencies (rtx, regset, regset, regset);
 
 /* Return nonzero if there are more insns that should be scheduled.  */
 
@@ -1734,8 +1735,7 @@ init_ready_list (struct ready_list *ready)
   /* Prepare current target block info.  */
   if (current_nr_blocks > 1)
     {
-      candidate_table = (candidate *) xmalloc (current_nr_blocks
-                                              * sizeof (candidate));
+      candidate_table = xmalloc (current_nr_blocks * sizeof (candidate));
 
       bblst_last = 0;
       /* bblst_table holds split blocks and update blocks for each block after
@@ -1743,10 +1743,10 @@ init_ready_list (struct ready_list *ready)
         the TO blocks of region edges, so there can be at most rgn_nr_edges
         of them.  */
       bblst_size = (current_nr_blocks - target_bb) * rgn_nr_edges;
-      bblst_table = (int *) xmalloc (bblst_size * sizeof (int));
+      bblst_table = xmalloc (bblst_size * sizeof (int));
 
       bitlst_table_last = 0;
-      bitlst_table = (int *) xmalloc (rgn_nr_edges * sizeof (int));
+      bitlst_table = xmalloc (rgn_nr_edges * sizeof (int));
 
       compute_trg_info (target_bb);
     }
@@ -1756,7 +1756,13 @@ init_ready_list (struct ready_list *ready)
   for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
     {
       if (INSN_DEP_COUNT (insn) == 0)
-       ready_add (ready, insn);
+       {
+         ready_add (ready, insn);
+
+         if (targetm.sched.adjust_priority)
+           INSN_PRIORITY (insn) =
+             (*targetm.sched.adjust_priority) (insn, INSN_PRIORITY (insn));
+       }
       target_n_insns++;
     }
 
@@ -1792,7 +1798,13 @@ init_ready_list (struct ready_list *ready)
                        && check_live (insn, bb_src)
                        && is_exception_free (insn, bb_src, target_bb))))
              if (INSN_DEP_COUNT (insn) == 0)
-               ready_add (ready, insn);
+               {
+                 ready_add (ready, insn); 
+
+                 if (targetm.sched.adjust_priority)
+                   INSN_PRIORITY (insn) =
+                     (*targetm.sched.adjust_priority) (insn, INSN_PRIORITY (insn));
+               }
          }
       }
 }
@@ -1827,28 +1839,28 @@ can_schedule_ready_p (rtx insn)
 
       /* Update source block boundaries.  */
       b1 = BLOCK_FOR_INSN (insn);
-      if (insn == b1->head && insn == b1->end)
+      if (insn == BB_HEAD (b1) && insn == BB_END (b1))
        {
          /* We moved all the insns in the basic block.
             Emit a note after the last insn and update the
             begin/end boundaries to point to the note.  */
          rtx note = emit_note_after (NOTE_INSN_DELETED, insn);
-         b1->head = note;
-         b1->end = note;
+         BB_HEAD (b1) = note;
+         BB_END (b1) = note;
        }
-      else if (insn == b1->end)
+      else if (insn == BB_END (b1))
        {
          /* We took insns from the end of the basic block,
             so update the end of block boundary so that it
             points to the first insn we did not move.  */
-         b1->end = PREV_INSN (insn);
+         BB_END (b1) = PREV_INSN (insn);
        }
-      else if (insn == b1->head)
+      else if (insn == BB_HEAD (b1))
        {
          /* We took insns from the start of the basic block,
             so update the start of block boundary so that
             it points to the first insn we did not move.  */
-         b1->head = NEXT_INSN (insn);
+         BB_HEAD (b1) = NEXT_INSN (insn);
        }
     }
   else
@@ -1951,11 +1963,15 @@ contributes_to_priority (rtx next, rtx insn)
   return BLOCK_NUM (next) == BLOCK_NUM (insn);
 }
 
-/* INSN is a JUMP_INSN.  Store the set of registers that must be considered
-   to be set by this jump in SET.  */
+/* INSN is a JUMP_INSN, COND_SET is the set of registers that are
+   conditionally set before INSN.  Store the set of registers that
+   must be considered as used by this jump in USED and that of
+   registers that must be considered as set in SET.  */
 
 static void
 compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED,
+                              regset cond_exec ATTRIBUTE_UNUSED,
+                              regset used ATTRIBUTE_UNUSED,
                               regset set ATTRIBUTE_UNUSED)
 {
   /* Nothing to do here, since we postprocess jumps in
@@ -1978,7 +1994,7 @@ static struct sched_info region_sched_info =
 
   NULL, NULL,
   NULL, NULL,
-  0, 0
+  0, 0, 0
 };
 
 /* Determine if PAT sets a CLASS_LIKELY_SPILLED_P register.  */
@@ -2020,7 +2036,7 @@ add_branch_dependences (rtx head, rtx tail)
      end since moving them results in worse register allocation.  Uses remain
      at the end to ensure proper register allocation.
 
-     cc0 setters remaim at the end because they can't be moved away from
+     cc0 setters remain at the end because they can't be moved away from
      their cc0 user.
 
      Insns setting CLASS_LIKELY_SPILLED_P registers (usually return values)
@@ -2384,7 +2400,7 @@ schedule_region (int rgn)
   init_deps_global ();
 
   /* Initializations for region data dependence analysis.  */
-  bb_deps = (struct deps *) xmalloc (sizeof (struct deps) * current_nr_blocks);
+  bb_deps = xmalloc (sizeof (struct deps) * current_nr_blocks);
   for (bb = 0; bb < current_nr_blocks; bb++)
     init_deps (bb_deps + bb);
 
@@ -2419,17 +2435,17 @@ schedule_region (int rgn)
     {
       int i;
 
-      prob = (float *) xmalloc ((current_nr_blocks) * sizeof (float));
+      prob = xmalloc ((current_nr_blocks) * sizeof (float));
 
       dom = sbitmap_vector_alloc (current_nr_blocks, current_nr_blocks);
       sbitmap_vector_zero (dom, current_nr_blocks);
       /* Edge to bit.  */
       rgn_nr_edges = 0;
-      edge_to_bit = (int *) xmalloc (nr_edges * sizeof (int));
+      edge_to_bit = xmalloc (nr_edges * sizeof (int));
       for (i = 1; i < nr_edges; i++)
        if (CONTAINING_RGN (FROM_BLOCK (i)) == rgn)
          EDGE_TO_BIT (i) = rgn_nr_edges++;
-      rgn_edges = (int *) xmalloc (rgn_nr_edges * sizeof (int));
+      rgn_edges = xmalloc (rgn_nr_edges * sizeof (int));
 
       rgn_nr_edges = 0;
       for (i = 1; i < nr_edges; i++)
@@ -2500,10 +2516,10 @@ schedule_region (int rgn)
       sched_rgn_n_insns += sched_n_insns;
 
       /* Update target block boundaries.  */
-      if (head == BLOCK_HEAD (b))
-       BLOCK_HEAD (b) = current_sched_info->head;
-      if (tail == BLOCK_END (b))
-       BLOCK_END (b) = current_sched_info->tail;
+      if (head == BB_HEAD (BASIC_BLOCK (b)))
+       BB_HEAD (BASIC_BLOCK (b)) = current_sched_info->head;
+      if (tail == BB_END (BASIC_BLOCK (b)))
+       BB_END (BASIC_BLOCK (b)) = current_sched_info->tail;
 
       /* Clean up.  */
       if (current_nr_blocks > 1)
@@ -2560,10 +2576,10 @@ init_regions (void)
   int rgn;
 
   nr_regions = 0;
-  rgn_table = (region *) xmalloc ((n_basic_blocks) * sizeof (region));
-  rgn_bb_table = (int *) xmalloc ((n_basic_blocks) * sizeof (int));
-  block_to_bb = (int *) xmalloc ((last_basic_block) * sizeof (int));
-  containing_rgn = (int *) xmalloc ((last_basic_block) * sizeof (int));
+  rgn_table = xmalloc ((n_basic_blocks) * sizeof (region));
+  rgn_bb_table = xmalloc ((n_basic_blocks) * sizeof (int));
+  block_to_bb = xmalloc ((last_basic_block) * sizeof (int));
+  containing_rgn = xmalloc ((last_basic_block) * sizeof (int));
 
   /* Compute regions for scheduling.  */
   if (reload_completed
@@ -2581,7 +2597,6 @@ init_regions (void)
        }
       else
        {
-         dominance_info dom;
          struct edge_list *edge_list;
 
          /* The scheduler runs after estimate_probabilities; therefore, we
@@ -2591,7 +2606,7 @@ init_regions (void)
          edge_list = create_edge_list ();
 
          /* Compute the dominators and post dominators.  */
-         dom = calculate_dominance_info (CDI_DOMINATORS);
+         calculate_dominance_info (CDI_DOMINATORS);
 
          /* build_control_flow will return nonzero if it detects unreachable
             blocks or any other irregularity with the cfg which prevents
@@ -2599,7 +2614,7 @@ init_regions (void)
          if (build_control_flow (edge_list) != 0)
            find_single_block_region ();
          else
-           find_rgns (edge_list, dom);
+           find_rgns (edge_list);
 
          if (sched_verbose >= 3)
            debug_regions ();
@@ -2609,7 +2624,7 @@ init_regions (void)
 
          /* For now.  This will move as more and more of haifa is converted
             to using the cfg code in flow.c.  */
-         free_dominance_info (dom);
+         free_dominance_info (CDI_DOMINATORS);
        }
     }
 
@@ -2617,7 +2632,7 @@ init_regions (void)
   if (CHECK_DEAD_NOTES)
     {
       blocks = sbitmap_alloc (last_basic_block);
-      deaths_in_region = (int *) xmalloc (sizeof (int) * nr_regions);
+      deaths_in_region = xmalloc (sizeof (int) * nr_regions);
       /* Remove all death notes from the subroutine.  */
       for (rgn = 0; rgn < nr_regions; rgn++)
        {