OSDN Git Service

* tree-ssa-dse.c (fix_phi_uses): Use SSA operand iterators.
[pf3gnuchains/gcc-fork.git] / gcc / tracer.c
index a0164dd..9b88766 100644 (file)
@@ -1,6 +1,6 @@
 /* The tracer pass for the GNU compiler.
    Contributed by Jan Hubicka, SuSE Labs.
-   Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
 #include "cfglayout.h"
 #include "fibheap.h"
 #include "flags.h"
+#include "timevar.h"
 #include "params.h"
 #include "coverage.h"
 
-static int count_insns         PARAMS ((basic_block));
-static bool ignore_bb_p                PARAMS ((basic_block));
-static bool better_p           PARAMS ((edge, edge));
-static edge find_best_successor PARAMS ((basic_block));
-static edge find_best_predecessor PARAMS ((basic_block));
-static int find_trace          PARAMS ((basic_block, basic_block *));
-static void tail_duplicate     PARAMS ((void));
-static void layout_superblocks PARAMS ((void));
+static int count_insns (basic_block);
+static bool ignore_bb_p (basic_block);
+static bool better_p (edge, edge);
+static edge find_best_successor (basic_block);
+static edge find_best_predecessor (basic_block);
+static int find_trace (basic_block, basic_block *);
+static void tail_duplicate (void);
+static void layout_superblocks (void);
 
 /* Minimal outgoing edge probability considered for superblock formation.  */
 static int probability_cutoff;
@@ -68,8 +69,7 @@ static int branch_ratio_cutoff;
 
 /* Return true if we should ignore the basic block for purposes of tracing.  */
 static bool
-ignore_bb_p (bb)
-     basic_block bb;
+ignore_bb_p (basic_block bb)
 {
   if (bb->index < 0)
     return true;
@@ -81,13 +81,14 @@ ignore_bb_p (bb)
 /* Return number of instructions in the block.  */
 
 static int
-count_insns (bb)
-     basic_block bb;
+count_insns (basic_block bb)
 {
   rtx insn;
   int n = 0;
 
-  for (insn = bb->head; insn != NEXT_INSN (bb->end); insn = NEXT_INSN (insn))
+  for (insn = BB_HEAD (bb);
+       insn != NEXT_INSN (BB_END (bb));
+       insn = NEXT_INSN (insn))
     if (active_insn_p (insn))
       n++;
   return n;
@@ -95,8 +96,7 @@ count_insns (bb)
 
 /* Return true if E1 is more frequent than E2.  */
 static bool
-better_p (e1, e2)
-     edge e1, e2;
+better_p (edge e1, edge e2)
 {
   if (e1->count != e2->count)
     return e1->count > e2->count;
@@ -114,13 +114,13 @@ better_p (e1, e2)
 /* Return most frequent successor of basic block BB.  */
 
 static edge
-find_best_successor (bb)
-     basic_block bb;
+find_best_successor (basic_block bb)
 {
   edge e;
   edge best = NULL;
+  edge_iterator ei;
 
-  for (e = bb->succ; e; e = e->succ_next)
+  FOR_EACH_EDGE (e, ei, bb->succs)
     if (!best || better_p (e, best))
       best = e;
   if (!best || ignore_bb_p (best->dest))
@@ -133,13 +133,13 @@ find_best_successor (bb)
 /* Return most frequent predecessor of basic block BB.  */
 
 static edge
-find_best_predecessor (bb)
-     basic_block bb;
+find_best_predecessor (basic_block bb)
 {
   edge e;
   edge best = NULL;
+  edge_iterator ei;
 
-  for (e = bb->pred; e; e = e->pred_next)
+  FOR_EACH_EDGE (e, ei, bb->preds)
     if (!best || better_p (e, best))
       best = e;
   if (!best || ignore_bb_p (best->src))
@@ -154,15 +154,13 @@ find_best_predecessor (bb)
    Return number of basic blocks recorded.  */
 
 static int
-find_trace (bb, trace)
-     basic_block bb;
-     basic_block *trace;
+find_trace (basic_block bb, basic_block *trace)
 {
   int i = 0;
   edge e;
 
-  if (rtl_dump_file)
-    fprintf (rtl_dump_file, "Trace seed %i [%i]", bb->index, bb->frequency);
+  if (dump_file)
+    fprintf (dump_file, "Trace seed %i [%i]", bb->index, bb->frequency);
 
   while ((e = find_best_predecessor (bb)) != NULL)
     {
@@ -170,12 +168,12 @@ find_trace (bb, trace)
       if (seen (bb2) || (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
          || find_best_successor (bb2) != e)
        break;
-      if (rtl_dump_file)
-       fprintf (rtl_dump_file, ",%i [%i]", bb->index, bb->frequency);
+      if (dump_file)
+       fprintf (dump_file, ",%i [%i]", bb->index, bb->frequency);
       bb = bb2;
     }
-  if (rtl_dump_file)
-    fprintf (rtl_dump_file, " forward %i [%i]", bb->index, bb->frequency);
+  if (dump_file)
+    fprintf (dump_file, " forward %i [%i]", bb->index, bb->frequency);
   trace[i++] = bb;
 
   /* Follow the trace in forward direction.  */
@@ -185,12 +183,12 @@ find_trace (bb, trace)
       if (seen (bb) || (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
          || find_best_predecessor (bb) != e)
        break;
-      if (rtl_dump_file)
-       fprintf (rtl_dump_file, ",%i [%i]", bb->index, bb->frequency);
+      if (dump_file)
+       fprintf (dump_file, ",%i [%i]", bb->index, bb->frequency);
       trace[i++] = bb;
     }
-  if (rtl_dump_file)
-    fprintf (rtl_dump_file, "\n");
+  if (dump_file)
+    fprintf (dump_file, "\n");
   return i;
 }
 
@@ -198,7 +196,7 @@ find_trace (bb, trace)
    if profitable.  */
 
 static void
-tail_duplicate ()
+tail_duplicate (void)
 {
   fibnode_t *blocks = xcalloc (last_basic_block, sizeof (fibnode_t));
   basic_block *trace = xmalloc (sizeof (basic_block) * n_basic_blocks);
@@ -251,8 +249,7 @@ tail_duplicate ()
 
       if (ignore_bb_p (bb))
        continue;
-      if (seen (bb))
-       abort ();
+      gcc_assert (!seen (bb));
 
       n = find_trace (bb, trace);
 
@@ -274,16 +271,16 @@ tail_duplicate ()
              blocks[bb2->index] = NULL;
            }
          traced_insns += bb2->frequency * counts [bb2->index];
-         if (bb2->pred && bb2->pred->pred_next
-             && cfg_layout_can_duplicate_bb_p (bb2))
+         if (EDGE_COUNT (bb2->preds) > 1
+             && can_duplicate_block_p (bb2))
            {
-             edge e = bb2->pred;
+             edge e;
              basic_block old = bb2;
 
-             while (e->src != bb)
-               e = e->pred_next;
+             e = find_edge (bb, bb2);
+
              nduplicated += counts [bb2->index];
-             bb2 = cfg_layout_duplicate_bb (bb2, e);
+             bb2 = duplicate_block (bb2, e);
 
              /* Reconsider the original copy of block we've duplicated.
                 Removing the most common predecessor may make it to be
@@ -291,8 +288,8 @@ tail_duplicate ()
              blocks[old->index] =
                fibheap_insert (heap, -old->frequency, old);
 
-             if (rtl_dump_file)
-               fprintf (rtl_dump_file, "Duplicated %i as %i [%i]\n",
+             if (dump_file)
+               fprintf (dump_file, "Duplicated %i as %i [%i]\n",
                         old->index, bb2->index, bb2->frequency);
            }
          bb->rbi->next = bb2;
@@ -302,12 +299,12 @@ tail_duplicate ()
          if (ignore_bb_p (bb))
            break;
        }
-      if (rtl_dump_file)
-       fprintf (rtl_dump_file, " covered now %.1f\n\n",
+      if (dump_file)
+       fprintf (dump_file, " covered now %.1f\n\n",
                 traced_insns * 100.0 / weighted_insns);
     }
-  if (rtl_dump_file)
-    fprintf (rtl_dump_file, "Duplicated %i insns (%i%%)\n", nduplicated,
+  if (dump_file)
+    fprintf (dump_file, "Duplicated %i insns (%i%%)\n", nduplicated,
             nduplicated * 100 / ninsns);
 
   free (blocks);
@@ -322,20 +319,21 @@ tail_duplicate ()
    change though.  */
 
 static void
-layout_superblocks ()
+layout_superblocks (void)
 {
-  basic_block end = ENTRY_BLOCK_PTR->succ->dest;
-  basic_block bb = ENTRY_BLOCK_PTR->succ->dest->next_bb;
+  basic_block end = EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest;
+  basic_block bb = EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest->next_bb;
 
   while (bb != EXIT_BLOCK_PTR)
     {
+      edge_iterator ei;
       edge e, best = NULL;
       while (end->rbi->next)
        end = end->rbi->next;
 
-      for (e = end->succ; e; e = e->succ_next)
+      FOR_EACH_EDGE (e, ei, end->succs)
        if (e->dest != EXIT_BLOCK_PTR
-           && e->dest != ENTRY_BLOCK_PTR->succ->dest
+           && e->dest != EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest
            && !e->dest->rbi->visited
            && (!best || EDGE_FREQUENCY (e) > EDGE_FREQUENCY (best)))
          best = e;
@@ -358,22 +356,29 @@ layout_superblocks ()
     }
 }
 
-/* Main entry point to this file.  */
+/* Main entry point to this file.  FLAGS is the set of flags to pass
+   to cfg_layout_initialize().  */
 
 void
-tracer ()
+tracer (unsigned int flags)
 {
   if (n_basic_blocks <= 1)
     return;
-  cfg_layout_initialize ();
+
+  timevar_push (TV_TRACER);
+
+  cfg_layout_initialize (flags);
   mark_dfs_back_edges ();
-  if (rtl_dump_file)
-    dump_flow_info (rtl_dump_file);
+  if (dump_file)
+    dump_flow_info (dump_file);
   tail_duplicate ();
   layout_superblocks ();
-  if (rtl_dump_file)
-    dump_flow_info (rtl_dump_file);
+  if (dump_file)
+    dump_flow_info (dump_file);
   cfg_layout_finalize ();
+
   /* Merge basic blocks in duplicated traces.  */
   cleanup_cfg (CLEANUP_EXPENSIVE);
+
+  timevar_pop (TV_TRACER);
 }