This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/5] Add cgraph hooks for important events


As I have already said in  the first mail, Honza takes credit for most
of this (and  for deciding to go this way), I  only finished the idea.
There are  four lists  of hooks:  One for node  removal, one  for edge
removal,  one   for  node  duplication   and  another  one   for  node
duplication.  The idea is that  all ipa passes will keep their private
data in  on-the-side arrays and  clean/duplicate them as  necessary in
these hooks.  The patch should be easy to follow.

2008-06-12  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_max_uid): New variable.
	(cgraph_edge_hook): New type.
	(cgraph_node_hook): new type.
	(cgraph_2edge_hook): New type.
	(cgraph_2node_hook): new type.


Index: iinln/gcc/cgraph.h
===================================================================
--- iinln.orig/gcc/cgraph.h
+++ iinln/gcc/cgraph.h
@@ -209,6 +209,8 @@ struct cgraph_edge GTY((chain_next ("%h.
   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
@@ -350,6 +353,26 @@ struct cgraph_node *save_inline_function
 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);
 
Index: iinln/gcc/cgraph.c
===================================================================
--- iinln.orig/gcc/cgraph.c
+++ iinln/gcc/cgraph.c
@@ -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;
 
@@ -135,6 +138,202 @@ int cgraph_order;
 static hashval_t hash_node (const void *);
 static int eq_node (const void *, const void *);
 
+/* 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 = xmalloc (sizeof (*entry));
+  struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook;
+
+  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 = xmalloc (sizeof (*entry));
+  struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook;
+
+  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 = xmalloc (sizeof (*entry));
+  struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook;
+
+  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 = xmalloc (sizeof (*entry));
+  struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook;
+
+  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
@@ -367,6 +566,7 @@ cgraph_create_edge (struct cgraph_node *
   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;
@@ -416,6 +616,7 @@ cgraph_edge_remove_caller (struct cgraph
 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);
 
@@ -497,7 +698,10 @@ cgraph_node_remove_callees (struct cgrap
      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)
     {
@@ -517,7 +721,10 @@ cgraph_node_remove_callers (struct cgrap
      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;
 }
 
@@ -551,6 +758,7 @@ cgraph_remove_node (struct cgraph_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.
@@ -893,6 +1101,7 @@ cgraph_clone_edge (struct cgraph_edge *e
       if (e->count < 0)
 	e->count = 0;
     }
+  cgraph_call_edge_duplication_hooks (e, new);
   return new;
 }
 
@@ -944,6 +1153,7 @@ cgraph_clone_node (struct cgraph_node *n
   if (new->next_clone)
     new->next_clone->prev_clone = new;
 
+  cgraph_call_node_duplication_hooks (n, new);
   return new;
 }
 

-- 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]