OSDN Git Service

2005-12-02 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / cgraph.c
index 68e3ea6..33eb1fe 100644 (file)
@@ -98,6 +98,7 @@ The varpool data structure:
 #include "output.h"
 #include "intl.h"
 #include "tree-gimple.h"
+#include "tree-dump.h"
 
 static void cgraph_node_remove_callers (struct cgraph_node *node);
 static inline void cgraph_edge_remove_caller (struct cgraph_edge *e);
@@ -473,7 +474,8 @@ cgraph_remove_node (struct cgraph_node *node)
     {
       struct cgraph_node *n = *slot;
       if (!n->next_clone && !n->global.inlined_to
-         && (TREE_ASM_WRITTEN (n->decl) || DECL_EXTERNAL (n->decl)))
+         && (cgraph_global_info_ready
+             && (TREE_ASM_WRITTEN (n->decl) || DECL_EXTERNAL (n->decl))))
        kill_body = true;
     }
 
@@ -882,7 +884,8 @@ cgraph_function_possibly_inlined_p (tree decl)
 /* Create clone of E in the node N represented by CALL_EXPR the callgraph.  */
 struct cgraph_edge *
 cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
-                  tree call_stmt, int count_scale, int loop_nest)
+                  tree call_stmt, gcov_type count_scale, int loop_nest,
+                  bool update_original)
 {
   struct cgraph_edge *new;
 
@@ -891,18 +894,28 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
                            e->loop_nest + loop_nest);
 
   new->inline_failed = e->inline_failed;
-  e->count -= new->count;
+  if (update_original)
+    {
+      e->count -= new->count;
+      if (e->count < 0)
+       e->count = 0;
+    }
   return new;
 }
 
 /* Create node representing clone of N executed COUNT times.  Decrease
-   the execution counts from original node too.  */
+   the execution counts from original node too. 
+
+   When UPDATE_ORIGINAL is true, the counts are subtracted from the original
+   function's profile to reflect the fact that part of execution is handled
+   by node.  */
 struct cgraph_node *
-cgraph_clone_node (struct cgraph_node *n, gcov_type count, int loop_nest)
+cgraph_clone_node (struct cgraph_node *n, gcov_type count, int loop_nest,
+                  bool update_original)
 {
   struct cgraph_node *new = cgraph_create_node ();
   struct cgraph_edge *e;
-  int count_scale;
+  gcov_type count_scale;
 
   new->decl = n->decl;
   new->origin = n->origin;
@@ -921,10 +934,16 @@ cgraph_clone_node (struct cgraph_node *n, gcov_type count, int loop_nest)
     count_scale = new->count * REG_BR_PROB_BASE / n->count;
   else
     count_scale = 0;
-  n->count -= count;
+  if (update_original)
+    {
+      n->count -= count;
+      if (n->count < 0)
+       n->count = 0;
+    }
 
   for (e = n->callees;e; e=e->next_callee)
-    cgraph_clone_edge (e, new, e->call_stmt, count_scale, loop_nest);
+    cgraph_clone_edge (e, new, e->call_stmt, count_scale, loop_nest,
+                      update_original);
 
   new->next_clone = n->next_clone;
   new->prev_clone = n;
@@ -977,7 +996,7 @@ cgraph_function_body_availability (struct cgraph_node *node)
 {
   enum availability avail;
   gcc_assert (cgraph_function_flags_ready);
-  if (!node->local.finalized)
+  if (!node->analyzed)
     avail = AVAIL_NOT_AVAILABLE;
   else if (node->local.local)
     avail = AVAIL_LOCAL;