2009-07-20 Jan Hubicka <jh@suse.cz>
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 20 Jul 2009 12:15:02 +0000 (12:15 +0000)
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 20 Jul 2009 12:15:02 +0000 (12:15 +0000)
            Martin Jambor  <mjambor@suse.cz>

* cgraph.h (combined_args_to_skip): New field.
* cgraph.c (cgraph_create_virtual_clone): Properly handle
combined_args_to_skip and args_to_skip.
* tree-inline.c (update_clone_info): New function.
(tree_function_versioning): Call update_clone_info.
* cgraphunit.c: (cgraph_materialize_clone): Dump materialized functions.
(cgraph_materialize_all_clones): More extensive dumping, working
with combined_args_to_skip rather than args_to_skip.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149808 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 7e349d5..82a3ab0 100644 (file)
@@ -1,3 +1,15 @@
+2009-07-20  Jan Hubicka  <jh@suse.cz>
+            Martin Jambor  <mjambor@suse.cz>
+
+       * cgraph.h (combined_args_to_skip): New field.
+       * cgraph.c (cgraph_create_virtual_clone): Properly handle
+       combined_args_to_skip and args_to_skip.
+       * tree-inline.c (update_clone_info): New function.
+       (tree_function_versioning): Call update_clone_info.
+       * cgraphunit.c: (cgraph_materialize_clone): Dump materialized functions.
+       (cgraph_materialize_all_clones): More extensive dumping, working
+       with combined_args_to_skip rather than args_to_skip.
+
 2009-07-20  Ira Rosen  <irar@il.ibm.com>
 
        * tree-vectorizer.h (vectorizable_condition): Add parameters.
index 3d0fee5..ea47aa3 100644 (file)
@@ -1716,6 +1716,31 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
   DECL_WEAK (new_node->decl) = 0;
   new_node->clone.tree_map = tree_map;
   new_node->clone.args_to_skip = args_to_skip;
+  if (!args_to_skip)
+    new_node->clone.combined_args_to_skip = old_node->clone.combined_args_to_skip;
+  else if (old_node->clone.combined_args_to_skip)
+    {
+      int newi = 0, oldi = 0;
+      tree arg;
+      bitmap new_args_to_skip = BITMAP_GGC_ALLOC ();
+      struct cgraph_node *orig_node;
+      for (orig_node = old_node; orig_node->clone_of; orig_node = orig_node->clone_of)
+        ;
+      for (arg = DECL_ARGUMENTS (orig_node->decl); arg; arg = TREE_CHAIN (arg), oldi++)
+       {
+         if (bitmap_bit_p (old_node->clone.combined_args_to_skip, oldi))
+           {
+             bitmap_set_bit (new_args_to_skip, oldi);
+             continue;
+           }
+         if (bitmap_bit_p (args_to_skip, newi))
+           bitmap_set_bit (new_args_to_skip, oldi);
+         newi++;
+       }
+      new_node->clone.combined_args_to_skip = new_args_to_skip;
+    }
+  else
+    new_node->clone.combined_args_to_skip = args_to_skip;
   new_node->local.externally_visible = 0;
   new_node->local.local = 1;
   new_node->lowered = true;
index 3e9a6d4..a05541d 100644 (file)
@@ -152,6 +152,7 @@ struct GTY(()) cgraph_clone_info
 {
   VEC(ipa_replace_map_p,gc)* tree_map;
   bitmap args_to_skip;
+  bitmap combined_args_to_skip;
 };
 
 /* The cgraph data structure.
index d329dc1..eb7de10 100644 (file)
@@ -1725,6 +1725,11 @@ cgraph_materialize_clone (struct cgraph_node *node)
   tree_function_versioning (node->clone_of->decl, node->decl,
                            node->clone.tree_map, true,
                            node->clone.args_to_skip);
+  if (cgraph_dump_file)
+    {
+      dump_function_to_file (node->clone_of->decl, cgraph_dump_file, dump_flags);
+      dump_function_to_file (node->decl, cgraph_dump_file, dump_flags);
+    }
 
   /* Function is no longer clone.  */
   if (node->next_sibling_clone)
@@ -1770,9 +1775,42 @@ cgraph_materialize_all_clones (void)
              if (gimple_has_body_p (node->clone_of->decl))
                {
                  if (cgraph_dump_file)
-                   fprintf (cgraph_dump_file, "  clonning %s to %s",
-                            cgraph_node_name (node->clone_of),
-                            cgraph_node_name (node));
+                   {
+                     fprintf (cgraph_dump_file, "clonning %s to %s\n",
+                              cgraph_node_name (node->clone_of),
+                              cgraph_node_name (node));
+                     if (node->clone.tree_map)
+                       {
+                         unsigned int i;
+                         fprintf (cgraph_dump_file, "   replace map: ");
+                         for (i = 0; i < VEC_length (ipa_replace_map_p,
+                                                     node->clone.tree_map);
+                                                     i++)
+                           {
+                             struct ipa_replace_map *replace_info;
+                             replace_info = VEC_index (ipa_replace_map_p,
+                                                       node->clone.tree_map,
+                                                       i);
+                             print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
+                             fprintf (cgraph_dump_file, " -> ");
+                             print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
+                             fprintf (cgraph_dump_file, "%s%s;",
+                                      replace_info->replace_p ? "(replace)":"",
+                                      replace_info->ref_p ? "(ref)":"");
+                           }
+                         fprintf (cgraph_dump_file, "\n");
+                       }
+                     if (node->clone.args_to_skip)
+                       {
+                         fprintf (cgraph_dump_file, "   args_to_skip: ");
+                         dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
+                       }
+                     if (node->clone.args_to_skip)
+                       {
+                         fprintf (cgraph_dump_file, "   combined_args_to_skip:");
+                         dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
+                       }
+                   }
                  cgraph_materialize_clone (node);
                }
              else
@@ -1811,9 +1849,9 @@ cgraph_materialize_all_clones (void)
                    print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
                  }
 
-               if (e->callee->clone.args_to_skip)
+               if (e->callee->clone.combined_args_to_skip)
                  new_stmt = gimple_call_copy_skip_args (e->call_stmt,
-                                                        e->callee->clone.args_to_skip);
+                                                        e->callee->clone.combined_args_to_skip);
                else
                  new_stmt = e->call_stmt;
                if (gimple_vdef (new_stmt)
index a28f0a4..8b5e1ff 100644 (file)
@@ -4446,6 +4446,42 @@ delete_unreachable_blocks_update_callgraph (copy_body_data *id)
   return changed;
 }
 
+/* Update clone info after duplication.  */
+
+static void
+update_clone_info (copy_body_data * id)
+{
+  struct cgraph_node *node;
+  if (!id->dst_node->clones)
+    return;
+  for (node = id->dst_node->clones; node != id->dst_node;)
+    {
+      /* First update replace maps to match the new body.  */
+      if (node->clone.tree_map)
+        {
+         unsigned int i;
+          for (i = 0; i < VEC_length (ipa_replace_map_p, node->clone.tree_map); i++)
+           {
+             struct ipa_replace_map *replace_info;
+             replace_info = VEC_index (ipa_replace_map_p, node->clone.tree_map, i);
+             walk_tree (&replace_info->old_tree, copy_tree_body_r, id, NULL);
+             walk_tree (&replace_info->new_tree, copy_tree_body_r, id, NULL);
+           }
+       }
+      if (node->clones)
+       node = node->clones;
+      else if (node->next_sibling_clone)
+       node = node->next_sibling_clone;
+      else
+       {
+         while (node != id->dst_node && !node->next_sibling_clone)
+           node = node->clone_of;
+         if (node != id->dst_node)
+           node = node->next_sibling_clone;
+       }
+    }
+}
+
 /* Create a copy of a function's tree.
    OLD_DECL and NEW_DECL are FUNCTION_DECL tree nodes
    of the original function and the new copied function
@@ -4602,6 +4638,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
       while (VEC_length (gimple, init_stmts))
        insert_init_stmt (bb, VEC_pop (gimple, init_stmts));
     }
+  update_clone_info (&id);
 
   /* Remap the nonlocal_goto_save_area, if any.  */
   if (cfun->nonlocal_goto_save_area)