cgraph.h (struct cgraph_edge): Add prev_caller and prev_callee fields.
authorRichard Guenther <rguenth@gcc.gnu.org>
Wed, 2 Mar 2005 11:09:48 +0000 (11:09 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 2 Mar 2005 11:09:48 +0000 (11:09 +0000)
2005-03-02  Richard Guenther  <rguenth@gcc.gnu.org>

* cgraph.h (struct cgraph_edge): Add prev_caller and
prev_callee fields.
(cgraph_node_remove_callees): Export.
* cgraph.c (cgraph_create_edge): Initialize prev_caller
and prev_callee.
(cgraph_edge_remove_callee): New function.
(cgraph_edge_remove_caller): Likewise.
(cgraph_remove_edge): Use.
(cgraph_redirect_edge_callee): Likewise.
(cgraph_node_remove_callees): New function.
(cgraph_node_remove_callers): Likewise.
(cgraph_remove_node): Use.
* tree-optimize.c (tree_rest_of_compilation): Use
cgraph_node_remove_callees instead of manual loop.
* cgraphunit.c (cgraph_finalize_function): Likewise.
(cgraph_expand_function): Likewise.
(cgraph_remove_unreachable_nodes): Likewise.

From-SVN: r95777

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphunit.c
gcc/tree-optimize.c

index 46f4c118758db7db178cd8a2c1596f031926489a..12e90862de424f712e57d58f37cd298123c6eaed 100644 (file)
@@ -1,3 +1,23 @@
+2005-03-02  Richard Guenther  <rguenth@gcc.gnu.org>
+
+       * cgraph.h (struct cgraph_edge): Add prev_caller and
+       prev_callee fields.
+       (cgraph_node_remove_callees): Export.
+       * cgraph.c (cgraph_create_edge): Initialize prev_caller
+       and prev_callee.
+       (cgraph_edge_remove_callee): New function.
+       (cgraph_edge_remove_caller): Likewise.
+       (cgraph_remove_edge): Use.
+       (cgraph_redirect_edge_callee): Likewise.
+       (cgraph_node_remove_callees): New function.
+       (cgraph_node_remove_callers): Likewise.
+       (cgraph_remove_node): Use.
+       * tree-optimize.c (tree_rest_of_compilation): Use
+       cgraph_node_remove_callees instead of manual loop.
+       * cgraphunit.c (cgraph_finalize_function): Likewise.
+       (cgraph_expand_function): Likewise.
+       (cgraph_remove_unreachable_nodes): Likewise.
+
 2005-03-02  Joseph S. Myers  <joseph@codesourcery.com>
 
        PR c/8927
index 7d1cca20df186d7a0c1d76b6638c92d76916e408..11953b46f85a898304c57a6363051e1bf5c9e181 100644 (file)
@@ -96,6 +96,10 @@ The varpool data structure:
 #include "output.h"
 #include "intl.h"
 
+static void cgraph_node_remove_callers (struct cgraph_node *node);
+static inline void cgraph_edge_remove_caller (struct cgraph_edge *e);
+static inline void cgraph_edge_remove_callee (struct cgraph_edge *e);
+
 /* Hash table used to convert declarations into nodes.  */
 static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
 
@@ -289,30 +293,55 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
   edge->caller = caller;
   edge->callee = callee;
   edge->call_expr = call_expr;
+  edge->prev_caller = NULL;
   edge->next_caller = callee->callers;
+  if (callee->callers)
+    callee->callers->prev_caller = edge;
+  edge->prev_callee = NULL;
   edge->next_callee = caller->callees;
+  if (caller->callees)
+    caller->callees->prev_callee = edge;
   caller->callees = edge;
   callee->callers = edge;
   return edge;
 }
 
-/* Remove the edge E the cgraph.  */
+/* Remove the edge E from the list of the callers of the callee.  */
+
+static inline void
+cgraph_edge_remove_callee (struct cgraph_edge *e)
+{
+  if (e->prev_caller)
+    e->prev_caller->next_caller = e->next_caller;
+  if (e->next_caller)
+    e->next_caller->prev_caller = e->prev_caller;
+  if (!e->prev_caller)
+    e->callee->callers = e->next_caller;
+}
+
+/* Remove the edge E from the list of the callees of the caller.  */
+
+static inline void
+cgraph_edge_remove_caller (struct cgraph_edge *e)
+{
+  if (e->prev_callee)
+    e->prev_callee->next_callee = e->next_callee;
+  if (e->next_callee)
+    e->next_callee->prev_callee = e->prev_callee;
+  if (!e->prev_callee)
+    e->caller->callees = e->next_callee;
+}
+
+/* Remove the edge E in the cgraph.  */
 
 void
 cgraph_remove_edge (struct cgraph_edge *e)
 {
-  struct cgraph_edge **edge, **edge2;
+  /* Remove from callers list of the callee.  */
+  cgraph_edge_remove_callee (e);
 
-  for (edge = &e->callee->callers; *edge && *edge != e;
-       edge = &((*edge)->next_caller))
-    continue;
-  gcc_assert (*edge);
-  *edge = (*edge)->next_caller;
-  for (edge2 = &e->caller->callees; *edge2 && *edge2 != e;
-       edge2 = &(*edge2)->next_callee)
-    continue;
-  gcc_assert (*edge2);
-  *edge2 = (*edge2)->next_callee;
+  /* Remove from callees list of the callers.  */
+  cgraph_edge_remove_caller (e);
 }
 
 /* Redirect callee of E to N.  The function does not update underlying
@@ -321,16 +350,46 @@ cgraph_remove_edge (struct cgraph_edge *e)
 void
 cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
 {
-  struct cgraph_edge **edge;
+  /* Remove from callers list of the current callee.  */
+  cgraph_edge_remove_callee (e);
 
-  for (edge = &e->callee->callers; *edge && *edge != e;
-       edge = &((*edge)->next_caller))
-    continue;
-  gcc_assert (*edge);
-  *edge = (*edge)->next_caller;
-  e->callee = n;
+  /* Insert to callers list of the new callee.  */
+  e->prev_caller = NULL;
+  if (n->callers)
+    n->callers->prev_caller = e;
   e->next_caller = n->callers;
   n->callers = e;
+  e->callee = n;
+}
+
+/* Remove all callees from the node.  */
+
+void
+cgraph_node_remove_callees (struct cgraph_node *node)
+{
+  struct cgraph_edge *e;
+
+  /* It is sufficient to remove the edges from the lists of callers of
+     the callees.  The callee list of the node can be zapped with one
+     assignment.  */
+  for (e = node->callees; e; e = e->next_callee)
+    cgraph_edge_remove_callee (e);
+  node->callees = NULL;
+}
+
+/* Remove all callers from the node.  */
+
+static void
+cgraph_node_remove_callers (struct cgraph_node *node)
+{
+  struct cgraph_edge *e;
+
+  /* It is sufficient to remove the edges from the lists of callees of
+     the callers.  The caller list of the node can be zapped with one
+     assignment.  */
+  for (e = node->callers; e; e = e->next_caller)
+    cgraph_edge_remove_caller (e);
+  node->callers = NULL;
 }
 
 /* Remove the node from cgraph.  */
@@ -341,10 +400,8 @@ cgraph_remove_node (struct cgraph_node *node)
   void **slot;
   bool check_dead = 1;
 
-  while (node->callers)
-    cgraph_remove_edge (node->callers);
-  while (node->callees)
-    cgraph_remove_edge (node->callees);
+  cgraph_node_remove_callers (node);
+  cgraph_node_remove_callees (node);
   while (node->nested)
     cgraph_remove_node (node->nested);
   if (node->origin)
index ae902b2ff6cd260abe5f9a52a87501e7217e38e6..b596a36a223635647eccb6d7943b28cfe1dfe1c3 100644 (file)
@@ -119,11 +119,13 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
   bool output;
 };
 
-struct cgraph_edge GTY((chain_next ("%h.next_caller")))
+struct cgraph_edge GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller")))
 {
   struct cgraph_node *caller;
   struct cgraph_node *callee;
+  struct cgraph_edge *prev_caller;
   struct cgraph_edge *next_caller;
+  struct cgraph_edge *prev_callee;
   struct cgraph_edge *next_callee;
   tree call_expr;
   PTR GTY ((skip (""))) aux;
@@ -165,6 +167,7 @@ void dump_cgraph (FILE *);
 void dump_cgraph_node (FILE *, struct cgraph_node *);
 void cgraph_remove_edge (struct cgraph_edge *);
 void cgraph_remove_node (struct cgraph_node *);
+void cgraph_node_remove_callees (struct cgraph_node *node);
 struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
                                        struct cgraph_node *,
                                        tree);
index 3df79a45f37696648f790ae32b72162722382801..1effef6710a947f4c4da0a86bae070707fadaec8 100644 (file)
@@ -356,8 +356,7 @@ cgraph_finalize_function (tree decl, bool nested)
              cgraph_remove_node (n);
        }
 
-      while (node->callees)
-       cgraph_remove_edge (node->callees);
+      cgraph_node_remove_callees (node);
 
       /* We may need to re-queue the node for assembling in case
          we already proceeded it and ignored as not needed.  */
@@ -843,8 +842,7 @@ cgraph_expand_function (struct cgraph_node *node)
       DECL_INITIAL (node->decl) = error_mark_node;
       /* Eliminate all call edges.  This is important so the call_expr no longer
         points to the dead function body.  */
-      while (node->callees)
-       cgraph_remove_edge (node->callees);
+      cgraph_node_remove_callees (node);
     }
 }
 
@@ -1006,8 +1004,7 @@ cgraph_remove_unreachable_nodes (void)
                      DECL_STRUCT_FUNCTION (node->decl) = NULL;
                      DECL_INITIAL (node->decl) = error_mark_node;
                    }
-                 while (node->callees)
-                   cgraph_remove_edge (node->callees);
+                 cgraph_node_remove_callees (node);
                  node->analyzed = false;
                }
              else
index f934c99759486d18715983d6a14e5acec95535b5..78d4ce559343848f074e31e771d2f209f3968202 100644 (file)
@@ -656,8 +656,7 @@ tree_rest_of_compilation (tree fndecl)
 
   /* We are not going to maintain the cgraph edges up to date.
      Kill it so it won't confuse us.  */
-  while (node->callees)
-    cgraph_remove_edge (node->callees);
+  cgraph_node_remove_callees (node);
 
 
   /* Initialize the default bitmap obstack.  */
@@ -688,8 +687,7 @@ tree_rest_of_compilation (tree fndecl)
        {
          struct cgraph_edge *e;
 
-         while (node->callees)
-           cgraph_remove_edge (node->callees);
+         cgraph_node_remove_callees (node);
          node->callees = saved_node->callees;
          saved_node->callees = NULL;
          update_inlined_to_pointers (node, node);