* cgraphbuild.c (build_cgraph_edges): Do not walk into debugs.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Aug 2013 14:15:15 +0000 (14:15 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Aug 2013 14:15:15 +0000 (14:15 +0000)
(make_pass_rebuild_cgraph_edges): Also clear references.
* cgraph.c (verify_cgraph_node): Add basic ipa-ref verifier.
* ipa-inline-transform.c (inline_transform): Remove all references
after inlining.
* cgraphunit.c (expand_function): Remove all references after expansion.
* ipa-ref.c (ipa_ref_has_aliases_p): Fix formatting.
(ipa_find_reference): Rewrite to iterator.
(remove_stmt_references): Likewise.
(ipa_clear_stmts_in_references): New function.
* ipa-ref.h (ipa_clear_stmts_in_references): Declare.
* cgraphclones.c (cgraph_materialize_all_clones): Remove or clear references.
* ipa-split.c (split_function): Remove references in split function.

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

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraphbuild.c
gcc/cgraphclones.c
gcc/cgraphunit.c
gcc/ipa-inline-transform.c
gcc/ipa-inline.c
gcc/ipa-ref.c
gcc/ipa-ref.h
gcc/ipa-split.c

index e55b5db..349981c 100644 (file)
@@ -1,3 +1,19 @@
+2013-08-08  Jan Hubicka  <jh@suse.cz>
+
+       * cgraphbuild.c (build_cgraph_edges): Do not walk into debugs.
+       (make_pass_rebuild_cgraph_edges): Also clear references.
+       * cgraph.c (verify_cgraph_node): Add basic ipa-ref verifier.
+       * ipa-inline-transform.c (inline_transform): Remove all references
+       after inlining.
+       * cgraphunit.c (expand_function): Remove all references after expansion.
+       * ipa-ref.c (ipa_ref_has_aliases_p): Fix formatting.
+       (ipa_find_reference): Rewrite to iterator.
+       (remove_stmt_references): Likewise.
+       (ipa_clear_stmts_in_references): New function.
+       * ipa-ref.h (ipa_clear_stmts_in_references): Declare.
+       * cgraphclones.c (cgraph_materialize_all_clones): Remove or clear references.
+       * ipa-split.c (split_function): Remove references in split function.
+
 2013-08-08  Richard Earnshaw  <rearnsha@arm.com>
 
        PR target/57431
index bb7016f..d217b4a 100644 (file)
@@ -2537,55 +2537,75 @@ verify_cgraph_node (struct cgraph_node *node)
     {
       if (this_cfun->cfg)
        {
+         pointer_set_t *stmts = pointer_set_create ();
+         int i;
+         struct ipa_ref *ref;
+
          /* Reach the trees by walking over the CFG, and note the
             enclosing basic-blocks in the call edges.  */
          FOR_EACH_BB_FN (this_block, this_cfun)
-           for (gsi = gsi_start_bb (this_block);
-                 !gsi_end_p (gsi);
-                 gsi_next (&gsi))
-             {
-               gimple stmt = gsi_stmt (gsi);
-               if (is_gimple_call (stmt))
-                 {
-                   struct cgraph_edge *e = cgraph_edge (node, stmt);
-                   tree decl = gimple_call_fndecl (stmt);
-                   if (e)
-                     {
-                       if (e->aux)
-                         {
-                           error ("shared call_stmt:");
-                           cgraph_debug_gimple_stmt (this_cfun, stmt);
-                           error_found = true;
-                         }
-                       if (!e->indirect_unknown_callee)
-                         {
-                           if (verify_edge_corresponds_to_fndecl (e, decl))
-                             {
-                               error ("edge points to wrong declaration:");
-                               debug_tree (e->callee->symbol.decl);
-                               fprintf (stderr," Instead of:");
-                               debug_tree (decl);
-                               error_found = true;
-                             }
-                         }
-                       else if (decl)
-                         {
-                           error ("an indirect edge with unknown callee "
-                                  "corresponding to a call_stmt with "
-                                  "a known declaration:");
-                           error_found = true;
-                           cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
-                         }
-                       e->aux = (void *)1;
-                     }
-                   else if (decl)
-                     {
-                       error ("missing callgraph edge for call stmt:");
-                       cgraph_debug_gimple_stmt (this_cfun, stmt);
-                       error_found = true;
-                     }
-                 }
+           {
+             for (gsi = gsi_start_phis (this_block);
+                  !gsi_end_p (gsi); gsi_next (&gsi))
+               pointer_set_insert (stmts, gsi_stmt (gsi));
+             for (gsi = gsi_start_bb (this_block);
+                  !gsi_end_p (gsi);
+                  gsi_next (&gsi))
+               {
+                 gimple stmt = gsi_stmt (gsi);
+                 pointer_set_insert (stmts, stmt);
+                 if (is_gimple_call (stmt))
+                   {
+                     struct cgraph_edge *e = cgraph_edge (node, stmt);
+                     tree decl = gimple_call_fndecl (stmt);
+                     if (e)
+                       {
+                         if (e->aux)
+                           {
+                             error ("shared call_stmt:");
+                             cgraph_debug_gimple_stmt (this_cfun, stmt);
+                             error_found = true;
+                           }
+                         if (!e->indirect_unknown_callee)
+                           {
+                             if (verify_edge_corresponds_to_fndecl (e, decl))
+                               {
+                                 error ("edge points to wrong declaration:");
+                                 debug_tree (e->callee->symbol.decl);
+                                 fprintf (stderr," Instead of:");
+                                 debug_tree (decl);
+                                 error_found = true;
+                               }
+                           }
+                         else if (decl)
+                           {
+                             error ("an indirect edge with unknown callee "
+                                    "corresponding to a call_stmt with "
+                                    "a known declaration:");
+                             error_found = true;
+                             cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
+                           }
+                         e->aux = (void *)1;
+                       }
+                     else if (decl)
+                       {
+                         error ("missing callgraph edge for call stmt:");
+                         cgraph_debug_gimple_stmt (this_cfun, stmt);
+                         error_found = true;
+                       }
+                   }
+               }
              }
+           for (i = 0;
+                ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref);
+                i++)
+             if (ref->stmt && !pointer_set_contains (stmts, ref->stmt))
+               {
+                 error ("reference to dead statement");
+                 cgraph_debug_gimple_stmt (this_cfun, ref->stmt);
+                 error_found = true;
+               }
+           pointer_set_destroy (stmts);
        }
       else
        /* No CFG available?!  */
index a7872de..333deed 100644 (file)
@@ -318,6 +318,9 @@ build_cgraph_edges (void)
          gimple stmt = gsi_stmt (gsi);
          tree decl;
 
+         if (is_gimple_debug (stmt))
+           continue;
+
          if (is_gimple_call (stmt))
            {
              int freq = compute_call_stmt_bb_frequency (current_function_decl,
@@ -537,7 +540,9 @@ make_pass_rebuild_cgraph_edges (gcc::context *ctxt)
 static unsigned int
 remove_cgraph_callee_edges (void)
 {
-  cgraph_node_remove_callees (cgraph_get_node (current_function_decl));
+  struct cgraph_node *node = cgraph_get_node (current_function_decl);
+  cgraph_node_remove_callees (node);
+  ipa_remove_all_references (&node->symbol.ref_list);
   return 0;
 }
 
index 21ef1f5..464c524 100644 (file)
@@ -876,7 +876,12 @@ cgraph_materialize_all_clones (void)
     }
   FOR_EACH_FUNCTION (node)
     if (!node->symbol.analyzed && node->callees)
-      cgraph_node_remove_callees (node);
+      {
+        cgraph_node_remove_callees (node);
+       ipa_remove_all_references (&node->symbol.ref_list);
+      }
+    else
+      ipa_clear_stmts_in_references ((symtab_node)node);
   if (cgraph_dump_file)
     fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
 #ifdef ENABLE_CHECKING
index 1472483..3cd2b41 100644 (file)
@@ -1677,6 +1677,7 @@ expand_function (struct cgraph_node *node)
   /* Eliminate all call edges.  This is important so the GIMPLE_CALL no longer
      points to the dead function body.  */
   cgraph_node_remove_callees (node);
+  ipa_remove_all_references (&node->symbol.ref_list);
 }
 
 
index 5e666ae..54b113a 100644 (file)
@@ -414,6 +414,7 @@ inline_transform (struct cgraph_node *node)
 
   for (e = node->callees; e; e = e->next_callee)
     cgraph_redirect_edge_call_stmt_to_callee (e);
+  ipa_remove_all_references (&node->symbol.ref_list);
 
   timevar_push (TV_INTEGRATION);
   if (node->callees)
index 96cbc9a..8c5b430 100644 (file)
@@ -2011,6 +2011,7 @@ early_inliner (void)
 #ifdef ENABLE_CHECKING
   verify_cgraph_node (node);
 #endif
+  ipa_remove_all_references (&node->symbol.ref_list);
 
   /* Even when not optimizing or not inlining inline always-inline
      functions.  */
index a6ffdf3..d2c6002 100644 (file)
@@ -218,6 +218,7 @@ ipa_ref_has_aliases_p (struct ipa_ref_list *ref_list)
 {
   struct ipa_ref *ref;
   int i;
+
   for (i = 0; ipa_ref_list_referring_iterate (ref_list, i, ref); i++)
     if (ref->use == IPA_REF_ALIAS)
       return true;
@@ -234,7 +235,7 @@ ipa_find_reference (symtab_node referring_node, symtab_node referred_node,
   struct ipa_ref *r = NULL;
   int i;
 
-  FOR_EACH_VEC_SAFE_ELT (referring_node->symbol.ref_list.references, i, r)
+  for (i = 0; ipa_ref_list_reference_iterate (&referring_node->symbol.ref_list, i, r); i++)
     if (r->referred == referred_node
        && (in_lto_p || r->stmt == stmt))
       return r;
@@ -250,7 +251,20 @@ ipa_remove_stmt_references (symtab_node referring_node, gimple stmt)
   struct ipa_ref *r = NULL;
   int i;
 
-  FOR_EACH_VEC_SAFE_ELT (referring_node->symbol.ref_list.references, i, r)
+  for (i = 0; ipa_ref_list_reference_iterate (&referring_node->symbol.ref_list, i, r); i++)
     if (r->stmt == stmt)
       ipa_remove_reference (r);
 }
+
+/* Remove all stmt references in non-speculative references.
+   Those are not maintained during inlining & clonning. */
+
+void
+ipa_clear_stmts_in_references (symtab_node referring_node)
+{
+  struct ipa_ref *r = NULL;
+  int i;
+
+  for (i = 0; ipa_ref_list_reference_iterate (&referring_node->symbol.ref_list, i, r); i++)
+    r->stmt = NULL;
+}
index c25e4e4..0b37a14 100644 (file)
@@ -75,3 +75,4 @@ bool ipa_ref_cannot_lead_to_return (struct ipa_ref *);
 bool ipa_ref_has_aliases_p (struct ipa_ref_list *);
 struct ipa_ref * ipa_find_reference (symtab_node, symtab_node, gimple);
 void ipa_remove_stmt_references (symtab_node, gimple);
+void ipa_clear_stmts_in_references (symtab_node);
index c83c4d0..faf7c84 100644 (file)
@@ -1223,6 +1223,7 @@ split_function (struct split_point *split_point)
       DECL_FUNCTION_CODE (node->symbol.decl) = (enum built_in_function) 0;
     }
   cgraph_node_remove_callees (cur_node);
+  ipa_remove_all_references (&cur_node->symbol.ref_list);
   if (!split_part_return_p)
     TREE_THIS_VOLATILE (node->symbol.decl) = 1;
   if (dump_file)