cgraphunit.c (verify_cgraph_node): Do checking that DECL match edge only when checkin...
authorJan Hubicka <jh@suse.cz>
Thu, 27 May 2010 02:07:01 +0000 (04:07 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 27 May 2010 02:07:01 +0000 (02:07 +0000)
* cgraphunit.c (verify_cgraph_node): Do checking that DECL match
edge only when checking is enabled; check using former_clone_of;
check inline clones too.
(cgraph_materialize_clone): Record former_clone_of pointer.
(cgraph_redirect_edge_call_stmt_to_callee): Assert that we are not
combining redirections; dump args_to_skip bitmap
(cgraph_materialize_all_clones): Do no redirection here.
* ipa-inline.c (inline_transform): Do redirection here.
* cgraph.h (struct cgraph_node): Add former_clone_of filed (enabled
cheking only).

From-SVN: r159907

gcc/ChangeLog
gcc/cgraph.h
gcc/cgraphunit.c
gcc/ipa-inline.c

index 669847f..3469a72 100644 (file)
@@ -1,3 +1,16 @@
+2010-05-26  Jan Hubicka  <jh@suse.cz>
+
+       * cgraphunit.c (verify_cgraph_node): Do checking that DECL match
+       edge only when checking is enabled; check using former_clone_of;
+       check inline clones too.
+       (cgraph_materialize_clone): Record former_clone_of pointer.
+       (cgraph_redirect_edge_call_stmt_to_callee): Assert that we are not
+       combining redirections; dump args_to_skip bitmap
+       (cgraph_materialize_all_clones): Do no redirection here.
+       * ipa-inline.c (inline_transform): Do redirection here.
+       * cgraph.h (struct cgraph_node): Add former_clone_of filed (enabled
+       cheking only).
+
 2010-05-26  Steven Bosscher  <steven@gcc.gnu.org>
 
        * config/avr/avr-c.c: Do not include regs.h.
index f352cc6..1080c44 100644 (file)
@@ -226,6 +226,10 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node {
   /* For functions with many calls sites it holds map from call expression
      to the edge to speed up cgraph_edge function.  */
   htab_t GTY((param_is (struct cgraph_edge))) call_site_hash;
+#ifdef ENABLE_CHECKING
+  /* Declaration node used to be clone of.  Used for checking only.  */
+  tree former_clone_of;
+#endif
 
   PTR GTY ((skip)) aux;
 
index 8cd6221..f10d471 100644 (file)
@@ -801,9 +801,12 @@ verify_cgraph_node (struct cgraph_node *node)
                                debug_tree (e->callee->decl);
                                error_found = true;
                              }
-                           else if (!node->global.inlined_to
-                                    && !e->callee->global.inlined_to
+#ifdef ENABLE_CHECKING
+                           else if (!e->callee->global.inlined_to
                                     && decl
+                                    && cgraph_get_node (decl)
+                                    && (e->callee->former_clone_of
+                                        != cgraph_get_node (decl)->decl)
                                     && !clone_of_p (cgraph_node (decl),
                                                     e->callee))
                              {
@@ -813,6 +816,7 @@ verify_cgraph_node (struct cgraph_node *node)
                                debug_tree (decl);
                                error_found = true;
                              }
+#endif
                          }
                        else if (decl)
                          {
@@ -2284,6 +2288,11 @@ static void
 cgraph_materialize_clone (struct cgraph_node *node)
 {
   bitmap_obstack_initialize (NULL);
+#ifdef ENABLE_CHECKING
+  node->former_clone_of = node->clone_of->decl;
+  if (node->clone_of->former_clone_of)
+    node->former_clone_of = node->clone_of->former_clone_of;
+#endif
   /* Copy the OLD_VERSION_NODE function tree to the new version.  */
   tree_function_versioning (node->clone_of->decl, node->decl,
                            node->clone.tree_map, true,
@@ -2324,12 +2333,19 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
       || cgraph_get_node (decl) == cgraph_get_node (e->callee->decl))
     return e->call_stmt;
 
+  gcc_assert (!cgraph_node (decl)->clone.combined_args_to_skip);
+
   if (cgraph_dump_file)
     {
       fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ",
               cgraph_node_name (e->caller), e->caller->uid,
               cgraph_node_name (e->callee), e->callee->uid);
       print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
+      if (e->callee->clone.combined_args_to_skip)
+        {
+          fprintf (cgraph_dump_file, " combined args to skip: ");
+          dump_bitmap (cgraph_dump_file, e->callee->clone.combined_args_to_skip);
+       }
     }
 
   if (e->callee->clone.combined_args_to_skip)
@@ -2436,31 +2452,7 @@ cgraph_materialize_all_clones (void)
     if (!node->analyzed && node->callees)
       cgraph_node_remove_callees (node);
   if (cgraph_dump_file)
-    fprintf (cgraph_dump_file, "Updating call sites\n");
-  for (node = cgraph_nodes; node; node = node->next)
-    if (node->analyzed && !node->clone_of
-       && gimple_has_body_p (node->decl))
-      {
-        struct cgraph_edge *e;
-
-       current_function_decl = node->decl;
-        push_cfun (DECL_STRUCT_FUNCTION (node->decl));
-       for (e = node->callees; e; e = e->next_callee)
-         cgraph_redirect_edge_call_stmt_to_callee (e);
-       gcc_assert (!need_ssa_update_p (cfun));
-       pop_cfun ();
-       current_function_decl = NULL;
-#ifdef ENABLE_CHECKING
-        verify_cgraph_node (node);
-#endif
-      }
-  if (cgraph_dump_file)
     fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
-  /* All changes to parameters have been performed.  In order not to
-     incorrectly repeat them, we simply dispose of the bitmaps that drive the
-     changes. */
-  for (node = cgraph_nodes; node; node = node->next)
-    node->clone.combined_args_to_skip = NULL;
 #ifdef ENABLE_CHECKING
   verify_cgraph ();
 #endif
index 38a9c56..d5f48bd 100644 (file)
@@ -2035,6 +2035,7 @@ inline_transform (struct cgraph_node *node)
 {
   unsigned int todo = 0;
   struct cgraph_edge *e;
+  bool inline_p = false;
 
   /* FIXME: Currently the passmanager is adding inline transform more than once to some
      clones.  This needs revisiting after WPA cleanups.  */
@@ -2047,10 +2048,13 @@ inline_transform (struct cgraph_node *node)
     save_inline_function_body (node);
 
   for (e = node->callees; e; e = e->next_callee)
-    if (!e->inline_failed || warn_inline)
-      break;
+    {
+      cgraph_redirect_edge_call_stmt_to_callee (e);
+      if (!e->inline_failed || warn_inline)
+        inline_p = true;
+    }
 
-  if (e)
+  if (inline_p)
     {
       timevar_push (TV_INTEGRATION);
       todo = optimize_inline_calls (current_function_decl);