OSDN Git Service

* cgraphbuild.c (record_reference): Use cgraph_mark_address_taken_node.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 May 2009 15:11:01 +0000 (15:11 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 May 2009 15:11:01 +0000 (15:11 +0000)
* cgraph.c (cgraph_mark_address_taken_node): New function.
(dump_cgraph_node): Dump new flag.
* cgraph.h (struct cgraph_node): Add address_taken.
(cgraph_mark_address_taken_node): New function.
* cp/decl2.c (cxx_callgraph_analyze_expr): Use
cgraph_mark_address_taken.
* ipa.c (cgraph_postorder): Prioritize functions with address taken
since new direct calls can be born.

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

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphbuild.c
gcc/cp/decl2.c
gcc/ipa.c

index 7ea0881..935aaa4 100644 (file)
@@ -1,3 +1,15 @@
+2009-05-10  Jan Hubicka  <jh@suse.cz>
+
+       * cgraphbuild.c (record_reference): Use cgraph_mark_address_taken_node.
+       * cgraph.c (cgraph_mark_address_taken_node): New function.
+       (dump_cgraph_node): Dump new flag.
+       * cgraph.h (struct cgraph_node): Add address_taken.
+       (cgraph_mark_address_taken_node): New function.
+       * cp/decl2.c (cxx_callgraph_analyze_expr): Use
+       cgraph_mark_address_taken.
+       * ipa.c (cgraph_postorder): Prioritize functions with address taken
+       since new direct calls can be born.
+
 2009-05-10  Joseph Myers  <joseph@codesourcery.com>
 
        * c-lex.c (c_lex_with_flags): Expect cpp_hashnode in
index 5d2cc1d..60ff168 100644 (file)
@@ -1293,6 +1293,15 @@ cgraph_mark_needed_node (struct cgraph_node *node)
   cgraph_mark_reachable_node (node);
 }
 
+/* Likewise indicate that a node is having address taken.  */
+
+void
+cgraph_mark_address_taken_node (struct cgraph_node *node)
+{
+  node->address_taken = 1;
+  cgraph_mark_needed_node (node);
+}
+
 /* Return local info for the compiled function.  */
 
 struct cgraph_local_info *
@@ -1397,6 +1406,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
     fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
   if (node->needed)
     fprintf (f, " needed");
+  if (node->address_taken)
+    fprintf (f, " address_taken");
   else if (node->reachable)
     fprintf (f, " reachable");
   if (gimple_has_body_p (node->decl))
index c1a1a0a..2e4201e 100644 (file)
@@ -189,6 +189,8 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node {
   /* Set when function must be output - it is externally visible
      or its address is taken.  */
   unsigned needed : 1;
+  /* Set when function has address taken.  */
+  unsigned address_taken : 1;
   /* Set when decl is an abstract function pointed to by the
      ABSTRACT_DECL_ORIGIN of a reachable function.  */
   unsigned abstract_and_needed : 1;
@@ -417,6 +419,7 @@ void cgraph_mark_if_needed (tree);
 void cgraph_finalize_compilation_unit (void);
 void cgraph_optimize (void);
 void cgraph_mark_needed_node (struct cgraph_node *);
+void cgraph_mark_address_taken_node (struct cgraph_node *);
 void cgraph_mark_reachable_node (struct cgraph_node *);
 bool cgraph_inline_p (struct cgraph_edge *, cgraph_inline_failed_t *reason);
 bool cgraph_preserve_function_body_p (tree);
index fb56ce5..a7a8bd2 100644 (file)
@@ -58,7 +58,7 @@ record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
         functions reachable unconditionally.  */
       decl = TREE_OPERAND (*tp, 0);
       if (TREE_CODE (decl) == FUNCTION_DECL)
-       cgraph_mark_needed_node (cgraph_node (decl));
+       cgraph_mark_address_taken_node (cgraph_node (decl));
       break;
 
     default:
index 8196b54..1f8e848 100644 (file)
@@ -3250,11 +3250,11 @@ cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED)
     {
     case PTRMEM_CST:
       if (TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
-       cgraph_mark_needed_node (cgraph_node (PTRMEM_CST_MEMBER (t)));
+       cgraph_mark_address_taken_node (cgraph_node (PTRMEM_CST_MEMBER (t)));
       break;
     case BASELINK:
       if (TREE_CODE (BASELINK_FUNCTIONS (t)) == FUNCTION_DECL)
-       cgraph_mark_needed_node (cgraph_node (BASELINK_FUNCTIONS (t)));
+       cgraph_mark_address_taken_node (cgraph_node (BASELINK_FUNCTIONS (t)));
       break;
     case VAR_DECL:
       if (DECL_VTABLE_OR_VTT_P (t))
index b51c219..fb3c749 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -38,6 +38,7 @@ cgraph_postorder (struct cgraph_node **order)
   int stack_size = 0;
   int order_pos = 0;
   struct cgraph_edge *edge, last;
+  int pass;
 
   struct cgraph_node **stack =
     XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
@@ -48,44 +49,46 @@ cgraph_postorder (struct cgraph_node **order)
      right through inline functions.  */
   for (node = cgraph_nodes; node; node = node->next)
     node->aux = NULL;
-  for (node = cgraph_nodes; node; node = node->next)
-    if (!node->aux)
-      {
-       node2 = node;
-       if (!node->callers)
-         node->aux = &last;
-       else
-         node->aux = node->callers;
-       while (node2)
-         {
-           while (node2->aux != &last)
-             {
-               edge = (struct cgraph_edge *) node2->aux;
-               if (edge->next_caller)
-                 node2->aux = edge->next_caller;
-               else
-                 node2->aux = &last;
-               if (!edge->caller->aux)
-                 {
-                   if (!edge->caller->callers)
-                     edge->caller->aux = &last;
-                   else
-                     edge->caller->aux = edge->caller->callers;
-                   stack[stack_size++] = node2;
-                   node2 = edge->caller;
-                   break;
-                 }
-             }
-           if (node2->aux == &last)
-             {
-               order[order_pos++] = node2;
-               if (stack_size)
-                 node2 = stack[--stack_size];
-               else
-                 node2 = NULL;
-             }
-         }
-      }
+  for (pass = 0; pass < 2; pass++)
+    for (node = cgraph_nodes; node; node = node->next)
+      if (!node->aux
+         && (pass || (node->needed && !node->address_taken)))
+       {
+         node2 = node;
+         if (!node->callers)
+           node->aux = &last;
+         else
+           node->aux = node->callers;
+         while (node2)
+           {
+             while (node2->aux != &last)
+               {
+                 edge = (struct cgraph_edge *) node2->aux;
+                 if (edge->next_caller)
+                   node2->aux = edge->next_caller;
+                 else
+                   node2->aux = &last;
+                 if (!edge->caller->aux)
+                   {
+                     if (!edge->caller->callers)
+                       edge->caller->aux = &last;
+                     else
+                       edge->caller->aux = edge->caller->callers;
+                     stack[stack_size++] = node2;
+                     node2 = edge->caller;
+                     break;
+                   }
+               }
+             if (node2->aux == &last)
+               {
+                 order[order_pos++] = node2;
+                 if (stack_size)
+                   node2 = stack[--stack_size];
+                 else
+                   node2 = NULL;
+               }
+           }
+       }
   free (stack);
   for (node = cgraph_nodes; node; node = node->next)
     node->aux = NULL;