cgraph.c (cgraph_edge_max_uid): New variable.
authorMartin Jambor <mjambor@suse.cz>
Mon, 7 Jul 2008 19:06:28 +0000 (21:06 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Mon, 7 Jul 2008 19:06:28 +0000 (21:06 +0200)
2008-07-07  Martin Jambor  <mjambor@suse.cz>

* cgraph.c (cgraph_edge_max_uid): New variable.
(struct cgraph_edge_hook_list): New type.
(struct cgraph_node_hook_list): New type.
(struct cgraph_2edge_hook_list): New type.
(struct cgraph_2node_hook_list): New type.
(first_cgraph_edge_removal_hook): New variable.
(first_cgraph_node_removal_hook): New variable.
(first_cgraph_edge_duplicated_hook): New variable.
(first_cgraph_node_duplicated_hook): New variable.
(cgraph_add_edge_removal_hook): New function.
(cgraph_remove_edge_removal_hook): New function.
(cgraph_call_edge_removal_hooks):  New function.
(cgraph_add_node_removal_hook):  New function.
(cgraph_remove_node_removal_hook):  New function.
(cgraph_call_node_removal_hooks):  New function.
(cgraph_add_edge_duplication_hook):  New function.
(cgraph_remove_edge_duplication_hook):  New function.
(cgraph_call_edge_duplication_hooks):  New function.
(cgraph_add_node_duplication_hook):  New function.
(cgraph_remove_node_duplication_hook):  New function.
(cgraph_call_node_duplication_hooks):  New function.
(cgraph_create_edge): Assign to edge uid.
(cgraph_remove_edge): Call edge removal hooks.
(cgraph_node_remove_callees): Call edge removal hooks.
(cgraph_node_remove_callers): Call edge removal hooks.
(cgraph_remove_node): Call node removal hooks.
(cgraph_clone_edge): Call edge duplication hooks.
(cgraph_clone_node): Call node duplication hooks.

* cgraph.h (cgraph_edge): New field uid.
(cgraph_edge_hook): New type.
(cgraph_node_hook): New type.
(cgraph_2edge_hook): New type.
(cgraph_2node_hook): New type.

From-SVN: r137591

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h

index ee62d5d0c98fb666507b17b9e6aa1295646be247..7c37e08446f5e60678f5265ea6551858bd21a5a5 100644 (file)
@@ -1,3 +1,40 @@
+2008-07-07  Martin Jambor  <mjambor@suse.cz>
+
+       * cgraph.c (cgraph_edge_max_uid): New variable.
+       (struct cgraph_edge_hook_list): New type.
+       (struct cgraph_node_hook_list): New type.
+       (struct cgraph_2edge_hook_list): New type.
+       (struct cgraph_2node_hook_list): New type.
+       (first_cgraph_edge_removal_hook): New variable.
+       (first_cgraph_node_removal_hook): New variable.
+       (first_cgraph_edge_duplicated_hook): New variable.
+       (first_cgraph_node_duplicated_hook): New variable.
+       (cgraph_add_edge_removal_hook): New function.
+       (cgraph_remove_edge_removal_hook): New function.
+       (cgraph_call_edge_removal_hooks):  New function.
+       (cgraph_add_node_removal_hook):  New function.
+       (cgraph_remove_node_removal_hook):  New function.
+       (cgraph_call_node_removal_hooks):  New function.
+       (cgraph_add_edge_duplication_hook):  New function.
+       (cgraph_remove_edge_duplication_hook):  New function.
+       (cgraph_call_edge_duplication_hooks):  New function.
+       (cgraph_add_node_duplication_hook):  New function.
+       (cgraph_remove_node_duplication_hook):  New function.
+       (cgraph_call_node_duplication_hooks):  New function.
+       (cgraph_create_edge): Assign to edge uid.
+       (cgraph_remove_edge): Call edge removal hooks.
+       (cgraph_node_remove_callees): Call edge removal hooks.
+       (cgraph_node_remove_callers): Call edge removal hooks.
+       (cgraph_remove_node): Call node removal hooks.
+       (cgraph_clone_edge): Call edge duplication hooks.
+       (cgraph_clone_node): Call node duplication hooks.
+
+       * cgraph.h (cgraph_edge): New field uid.
+       (cgraph_edge_hook): New type.
+       (cgraph_node_hook): New type.
+       (cgraph_2edge_hook): New type.
+       (cgraph_2node_hook): New type.
+
 2008-07-07  Andreas Tobler  <a.tobler@schweiz.org>
 
        * config.in: Regenerate.
index 17ee8f0a63af52a6fff5ae2f095d6f3064895170..6a80bbed0950702e081aaaacde7ba027ef24844e 100644 (file)
@@ -109,6 +109,9 @@ int cgraph_n_nodes;
 /* Maximal uid used in cgraph nodes.  */
 int cgraph_max_uid;
 
+/* Maximal uid used in cgraph edges.  */
+int cgraph_edge_max_uid;
+
 /* Maximal pid used for profiling */
 int cgraph_max_pid;
 
@@ -132,6 +135,206 @@ static GTY(()) struct cgraph_asm_node *cgraph_asm_last_node;
    them, to support -fno-toplevel-reorder.  */
 int cgraph_order;
 
+/* List of hooks trigerred on cgraph_edge events.  */
+struct cgraph_edge_hook_list {
+  cgraph_edge_hook hook;
+  void *data;
+  struct cgraph_edge_hook_list *next;
+};
+
+/* List of hooks trigerred on cgraph_node events.  */
+struct cgraph_node_hook_list {
+  cgraph_node_hook hook;
+  void *data;
+  struct cgraph_node_hook_list *next;
+};
+
+/* List of hooks trigerred on events involving two cgraph_edges.  */
+struct cgraph_2edge_hook_list {
+  cgraph_2edge_hook hook;
+  void *data;
+  struct cgraph_2edge_hook_list *next;
+};
+
+/* List of hooks trigerred on events involving two cgraph_nodes.  */
+struct cgraph_2node_hook_list {
+  cgraph_2node_hook hook;
+  void *data;
+  struct cgraph_2node_hook_list *next;
+};
+
+/* List of hooks triggered when an edge is removed.  */
+struct cgraph_edge_hook_list *first_cgraph_edge_removal_hook;
+/* List of hooks triggered when a node is removed.  */
+struct cgraph_node_hook_list *first_cgraph_node_removal_hook;
+/* List of hooks triggered when an edge is duplicated.  */
+struct cgraph_2edge_hook_list *first_cgraph_edge_duplicated_hook;
+/* List of hooks triggered when a node is duplicated.  */
+struct cgraph_2node_hook_list *first_cgraph_node_duplicated_hook;
+
+
+/* Register HOOK to be called with DATA on each removed edge.  */
+struct cgraph_edge_hook_list *
+cgraph_add_edge_removal_hook (cgraph_edge_hook hook, void *data)
+{
+  struct cgraph_edge_hook_list *entry;
+  struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook;
+
+  entry = (struct cgraph_edge_hook_list *) xmalloc (sizeof (*entry));
+  entry->hook = hook;
+  entry->data = data;
+  entry->next = NULL;
+  while (*ptr)
+    ptr = &(*ptr)->next;
+  *ptr = entry;
+  return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on removing edges.  */
+void
+cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *entry)
+{
+  struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook;
+
+  while (*ptr != entry)
+    ptr = &(*ptr)->next;
+  *ptr = entry->next;
+}
+
+/* Call all edge removal hooks.  */
+static void
+cgraph_call_edge_removal_hooks (struct cgraph_edge *e)
+{
+  struct cgraph_edge_hook_list *entry = first_cgraph_edge_removal_hook;
+  while (entry)
+  {
+    entry->hook (e, entry->data);
+    entry = entry->next;
+  }
+}
+
+/* Register HOOK to be called with DATA on each removed node.  */
+struct cgraph_node_hook_list *
+cgraph_add_node_removal_hook (cgraph_node_hook hook, void *data)
+{
+  struct cgraph_node_hook_list *entry;
+  struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook;
+
+  entry = (struct cgraph_node_hook_list *) xmalloc (sizeof (*entry));
+  entry->hook = hook;
+  entry->data = data;
+  entry->next = NULL;
+  while (*ptr)
+    ptr = &(*ptr)->next;
+  *ptr = entry;
+  return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on removing nodes.  */
+void
+cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *entry)
+{
+  struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook;
+
+  while (*ptr != entry)
+    ptr = &(*ptr)->next;
+  *ptr = entry->next;
+}
+
+/* Call all node removal hooks.  */
+static void
+cgraph_call_node_removal_hooks (struct cgraph_node *node)
+{
+  struct cgraph_node_hook_list *entry = first_cgraph_node_removal_hook;
+  while (entry)
+  {
+    entry->hook (node, entry->data);
+    entry = entry->next;
+  }
+}
+
+/* Register HOOK to be called with DATA on each duplicated edge.  */
+struct cgraph_2edge_hook_list *
+cgraph_add_edge_duplication_hook (cgraph_2edge_hook hook, void *data)
+{
+  struct cgraph_2edge_hook_list *entry;
+  struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook;
+
+  entry = (struct cgraph_2edge_hook_list *) xmalloc (sizeof (*entry));
+  entry->hook = hook;
+  entry->data = data;
+  entry->next = NULL;
+  while (*ptr)
+    ptr = &(*ptr)->next;
+  *ptr = entry;
+  return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on duplicating edges.  */
+void
+cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *entry)
+{
+  struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook;
+
+  while (*ptr != entry)
+    ptr = &(*ptr)->next;
+  *ptr = entry->next;
+}
+
+/* Call all edge duplication hooks.  */
+static void
+cgraph_call_edge_duplication_hooks (struct cgraph_edge *cs1,
+                                   struct cgraph_edge *cs2)
+{
+  struct cgraph_2edge_hook_list *entry = first_cgraph_edge_duplicated_hook;
+  while (entry)
+  {
+    entry->hook (cs1, cs2, entry->data);
+    entry = entry->next;
+  }
+}
+
+/* Register HOOK to be called with DATA on each duplicated node.  */
+struct cgraph_2node_hook_list *
+cgraph_add_node_duplication_hook (cgraph_2node_hook hook, void *data)
+{
+  struct cgraph_2node_hook_list *entry;
+  struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook;
+
+  entry = (struct cgraph_2node_hook_list *) xmalloc (sizeof (*entry));
+  entry->hook = hook;
+  entry->data = data;
+  entry->next = NULL;
+  while (*ptr)
+    ptr = &(*ptr)->next;
+  *ptr = entry;
+  return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on duplicating nodes.  */
+void
+cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *entry)
+{
+  struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook;
+
+  while (*ptr != entry)
+    ptr = &(*ptr)->next;
+  *ptr = entry->next;
+}
+
+/* Call all node duplication hooks.  */
+static void
+cgraph_call_node_duplication_hooks (struct cgraph_node *node1,
+                                   struct cgraph_node *node2)
+{
+  struct cgraph_2node_hook_list *entry = first_cgraph_node_duplicated_hook;
+  while (entry)
+  {
+    entry->hook (node1, node2, entry->data);
+    entry = entry->next;
+  }
+}
+
 /* Returns a hash code for P.  */
 
 static hashval_t
@@ -365,6 +568,7 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
   gcc_assert (freq >= 0);
   gcc_assert (freq <= CGRAPH_FREQ_MAX);
   edge->loop_nest = nest;
+  edge->uid = cgraph_edge_max_uid++;
   if (caller->call_site_hash)
     {
       void **slot;
@@ -414,6 +618,7 @@ cgraph_edge_remove_caller (struct cgraph_edge *e)
 void
 cgraph_remove_edge (struct cgraph_edge *e)
 {
+  cgraph_call_edge_removal_hooks (e);
   /* Remove from callers list of the callee.  */
   cgraph_edge_remove_callee (e);
 
@@ -495,7 +700,10 @@ cgraph_node_remove_callees (struct cgraph_node *node)
      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);
+    {
+      cgraph_call_edge_removal_hooks (e);
+      cgraph_edge_remove_callee (e);
+    }
   node->callees = NULL;
   if (node->call_site_hash)
     {
@@ -515,7 +723,10 @@ cgraph_node_remove_callers (struct cgraph_node *node)
      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);
+    {
+      cgraph_call_edge_removal_hooks (e);
+      cgraph_edge_remove_caller (e);
+    }
   node->callers = NULL;
 }
 
@@ -549,6 +760,7 @@ cgraph_remove_node (struct cgraph_node *node)
   void **slot;
   bool kill_body = false;
 
+  cgraph_call_node_removal_hooks (node);
   cgraph_node_remove_callers (node);
   cgraph_node_remove_callees (node);
   /* Incremental inlining access removed nodes stored in the postorder list.
@@ -891,6 +1103,7 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
       if (e->count < 0)
        e->count = 0;
     }
+  cgraph_call_edge_duplication_hooks (e, new);
   return new;
 }
 
@@ -942,6 +1155,7 @@ cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq, int loop_ne
   if (new->next_clone)
     new->next_clone->prev_clone = new;
 
+  cgraph_call_node_duplication_hooks (n, new);
   return new;
 }
 
index dda2a1891f5421021be8a213e69e98854797bce8..ee79c9200f1a0e599bd7085036a10e4bc8a85391 100644 (file)
@@ -209,6 +209,8 @@ struct cgraph_edge GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_call
   int frequency;
   /* Depth of loop nest, 1 means no loop nest.  */
   int loop_nest;
+  /* Unique id of the edge.  */
+  int uid;
 };
 
 #define CGRAPH_FREQ_BASE 1000
@@ -266,6 +268,7 @@ struct cgraph_asm_node GTY(())
 extern GTY(()) struct cgraph_node *cgraph_nodes;
 extern GTY(()) int cgraph_n_nodes;
 extern GTY(()) int cgraph_max_uid;
+extern GTY(()) int cgraph_edge_max_uid;
 extern GTY(()) int cgraph_max_pid;
 extern bool cgraph_global_info_ready;
 enum cgraph_state
@@ -351,6 +354,26 @@ struct cgraph_node *save_inline_function_body (struct cgraph_node *);
 void record_references_in_initializer (tree);
 bool cgraph_process_new_functions (void);
 
+typedef void (*cgraph_edge_hook)(struct cgraph_edge *, void *);
+typedef void (*cgraph_node_hook)(struct cgraph_node *, void *);
+typedef void (*cgraph_2edge_hook)(struct cgraph_edge *, struct cgraph_edge *,
+                                 void *);
+typedef void (*cgraph_2node_hook)(struct cgraph_node *, struct cgraph_node *,
+                                 void *);
+struct cgraph_edge_hook_list;
+struct cgraph_node_hook_list;
+struct cgraph_2edge_hook_list;
+struct cgraph_2node_hook_list;
+struct cgraph_edge_hook_list *cgraph_add_edge_removal_hook (cgraph_edge_hook, void *);
+void cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *);
+struct cgraph_node_hook_list *cgraph_add_node_removal_hook (cgraph_node_hook,
+                                                           void *);
+void cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *);
+struct cgraph_2edge_hook_list *cgraph_add_edge_duplication_hook (cgraph_2edge_hook, void *);
+void cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *);
+struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_hook, void *);
+void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *);
+
 /* In cgraphbuild.c  */
 unsigned int rebuild_cgraph_edges (void);