OSDN Git Service

* config/m68k/m68k.c (notice_update_cc): Remove useless code.
[pf3gnuchains/gcc-fork.git] / gcc / cfg.c
index f33a950..c46ac0b 100644 (file)
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -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.  */
 
 /* This file contains low level functions to manipulate the CFG and
    analyze it.  All other modules should not transform the data structure
@@ -136,16 +136,6 @@ alloc_block (void)
   return bb;
 }
 
-/* Initialize rbi (the structure containing data used by basic block
-   duplication and reordering) for the given basic block.  */
-
-void
-initialize_bb_rbi (basic_block bb)
-{
-  gcc_assert (!bb->rbi);
-  bb->rbi = ggc_alloc_cleared (sizeof (struct reorder_block_def));
-}
-
 /* Link block B to chain after AFTER.  */
 void
 link_block (basic_block b, basic_block after)
@@ -421,7 +411,8 @@ clear_bb_flags (void)
   basic_block bb;
 
   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
-    bb->flags = BB_PARTITION (bb)  | (bb->flags & BB_DISABLE_SCHEDULE);
+    bb->flags = (BB_PARTITION (bb)  | (bb->flags & BB_DISABLE_SCHEDULE)
+                | (bb->flags & BB_RTL));
 }
 \f
 /* Check the consistency of profile information.  We can't do that
@@ -553,16 +544,19 @@ dump_flow_info (FILE *file)
       FOR_EACH_EDGE (e, ei, bb->succs)
        dump_edge_info (file, e, 1);
 
-      if (bb->global_live_at_start)
-       {
-         fprintf (file, "\nRegisters live at start:");
-         dump_regset (bb->global_live_at_start, file);
-       }
-
-      if (bb->global_live_at_end)
+      if (bb->flags & BB_RTL)
        {
-         fprintf (file, "\nRegisters live at end:");
-         dump_regset (bb->global_live_at_end, file);
+         if (bb->il.rtl->global_live_at_start)
+           {
+             fprintf (file, "\nRegisters live at start:");
+             dump_regset (bb->il.rtl->global_live_at_start, file);
+           }
+
+         if (bb->il.rtl->global_live_at_end)
+           {
+             fprintf (file, "\nRegisters live at end:");
+             dump_regset (bb->il.rtl->global_live_at_end, file);
+           }
        }
 
       putc ('\n', file);
@@ -856,7 +850,12 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency,
 
   bb->count -= count;
   if (bb->count < 0)
-    bb->count = 0;
+    {
+      if (dump_file)
+       fprintf (dump_file, "bb %i count became negative after threading",
+                bb->index);
+      bb->count = 0;
+    }
 
   /* Compute the probability of TAKEN_EDGE being reached via threaded edge.
      Watch for overflows.  */
@@ -894,16 +893,25 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency,
     }
   else if (prob != REG_BR_PROB_BASE)
     {
-      int scale = 65536 * REG_BR_PROB_BASE / prob;
+      int scale = RDIV (65536 * REG_BR_PROB_BASE, prob);
 
       FOR_EACH_EDGE (c, ei, bb->succs)
-       c->probability *= scale / 65536;
+       {
+         c->probability = RDIV (c->probability * scale, 65536);
+         if (c->probability > REG_BR_PROB_BASE)
+           c->probability = REG_BR_PROB_BASE;
+       }
     }
 
   gcc_assert (bb == taken_edge->src);
   taken_edge->count -= count;
   if (taken_edge->count < 0)
-    taken_edge->count = 0;
+    {
+      if (dump_file)
+       fprintf (dump_file, "edge %i->%i count became negative after threading",
+                taken_edge->src->index, taken_edge->dest->index);
+      taken_edge->count = 0;
+    }
 }
 
 /* Multiply all frequencies of basic blocks in array BBS of length NBBS
@@ -913,16 +921,27 @@ scale_bbs_frequencies_int (basic_block *bbs, int nbbs, int num, int den)
 {
   int i;
   edge e;
+  if (num < 0)
+    num = 0;
+  if (num > den)
+    return;
+  /* Assume that the users are producing the fraction from frequencies
+     that never grow far enough to risk arithmetic overflow.  */
+  gcc_assert (num < 65536);
   for (i = 0; i < nbbs; i++)
     {
       edge_iterator ei;
-      bbs[i]->frequency = (bbs[i]->frequency * num) / den;
+      bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den);
       bbs[i]->count = RDIV (bbs[i]->count * num, den);
       FOR_EACH_EDGE (e, ei, bbs[i]->succs)
-       e->count = (e->count * num) /den;
+       e->count = RDIV (e->count * num, den);
     }
 }
 
+/* numbers smaller than this value are safe to multiply without getting
+   64bit overflow.  */
+#define MAX_SAFE_MULTIPLIER (1 << (sizeof (HOST_WIDEST_INT) * 4 - 1))
+
 /* Multiply all frequencies of basic blocks in array BBS of length NBBS
    by NUM/DEN, in gcov_type arithmetic.  More accurate than previous
    function but considerably slower.  */
@@ -932,18 +951,41 @@ scale_bbs_frequencies_gcov_type (basic_block *bbs, int nbbs, gcov_type num,
 {
   int i;
   edge e;
+  gcov_type fraction = RDIV (num * 65536, den);
 
-  for (i = 0; i < nbbs; i++)
-    {
-      edge_iterator ei;
-      bbs[i]->frequency = (bbs[i]->frequency * num) / den;
-      bbs[i]->count = RDIV (bbs[i]->count * num, den);
-      FOR_EACH_EDGE (e, ei, bbs[i]->succs)
-       e->count = (e->count * num) /den;
-    }
+  gcc_assert (fraction >= 0);
+
+  if (num < MAX_SAFE_MULTIPLIER)
+    for (i = 0; i < nbbs; i++)
+      {
+       edge_iterator ei;
+       bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den);
+       if (bbs[i]->count <= MAX_SAFE_MULTIPLIER)
+         bbs[i]->count = RDIV (bbs[i]->count * num, den);
+       else
+         bbs[i]->count = RDIV (bbs[i]->count * fraction, 65536);
+       FOR_EACH_EDGE (e, ei, bbs[i]->succs)
+         if (bbs[i]->count <= MAX_SAFE_MULTIPLIER)
+           e->count = RDIV (e->count * num, den);
+         else
+           e->count = RDIV (e->count * fraction, 65536);
+      }
+   else
+    for (i = 0; i < nbbs; i++)
+      {
+       edge_iterator ei;
+       if (sizeof (gcov_type) > sizeof (int))
+         bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den);
+       else
+         bbs[i]->frequency = RDIV (bbs[i]->frequency * fraction, 65536);
+       bbs[i]->count = RDIV (bbs[i]->count * fraction, 65536);
+       FOR_EACH_EDGE (e, ei, bbs[i]->succs)
+         e->count = RDIV (e->count * fraction, 65536);
+      }
 }
 
-/* Datastructures used to maintain mapping between basic blocks and copies.  */
+/* Data structures used to maintain mapping between basic blocks and
+   copies.  */
 static htab_t bb_original;
 static htab_t bb_copy;
 static alloc_pool original_copy_bb_pool;
@@ -975,7 +1017,8 @@ bb_copy_original_eq (const void *p, const void *q)
   return data->index1 == data2->index1;
 }
 
-/* Initialize the datstructures to maintain mapping between blocks and it's copies.  */
+/* Initialize the data structures to maintain mapping between blocks
+   and its copies.  */
 void
 initialize_original_copy_tables (void)
 {
@@ -988,7 +1031,8 @@ initialize_original_copy_tables (void)
   bb_copy = htab_create (10, bb_copy_original_hash, bb_copy_original_eq, NULL);
 }
 
-/* Free the datstructures to maintain mapping between blocks and it's copies.  */
+/* Free the data structures to maintain mapping between blocks and
+   its copies.  */
 void
 free_original_copy_tables (void)
 {
@@ -1001,8 +1045,8 @@ free_original_copy_tables (void)
   original_copy_bb_pool = NULL;
 }
 
-/* Set original for basic block.  Do nothing when datstructures are not
-   intialized so passes not needing this don't need to care.  */
+/* Set original for basic block.  Do nothing when datstructures are not
+   initialized so passes not needing this don't need to care.  */
 void
 set_bb_original (basic_block bb, basic_block original)
 {
@@ -1043,8 +1087,8 @@ get_bb_original (basic_block bb)
     return NULL;
 }
 
-/* Set copy for basic block.  Do nothing when datstructures are not
-   intialized so passes not needing this don't need to care.  */
+/* Set copy for basic block.  Do nothing when datstructures are not
+   initialized so passes not needing this don't need to care.  */
 void
 set_bb_copy (basic_block bb, basic_block copy)
 {