OSDN Git Service

2011-01-14 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / cgraphbuild.c
index 9dcb862..7bfeac7 100644 (file)
@@ -1,5 +1,5 @@
 /* Callgraph construction.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Jan Hubicka
 
@@ -234,9 +234,9 @@ compute_call_stmt_bb_frequency (tree decl, basic_block bb)
 /* Mark address taken in STMT.  */
 
 static bool
-mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
-             void *data ATTRIBUTE_UNUSED)
+mark_address (gimple stmt, tree addr, void *data)
 {
+  addr = get_base_address (addr);
   if (TREE_CODE (addr) == FUNCTION_DECL)
     {
       struct cgraph_node *node = cgraph_node (addr);
@@ -245,24 +245,20 @@ mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
                            node, NULL,
                            IPA_REF_ADDR, stmt);
     }
-  else
+  else if (addr && TREE_CODE (addr) == VAR_DECL
+          && (TREE_STATIC (addr) || DECL_EXTERNAL (addr)))
     {
-      addr = get_base_address (addr);
-      if (addr && TREE_CODE (addr) == VAR_DECL
-         && (TREE_STATIC (addr) || DECL_EXTERNAL (addr)))
-       {
-         struct varpool_node *vnode = varpool_node (addr);
-         int walk_subtrees;
+      struct varpool_node *vnode = varpool_node (addr);
+      int walk_subtrees;
 
-         if (lang_hooks.callgraph.analyze_expr)
-           lang_hooks.callgraph.analyze_expr (&addr, &walk_subtrees);
-         varpool_mark_needed_node (vnode);
-         if (vnode->alias && vnode->extra_name)
-           vnode = vnode->extra_name;
-         ipa_record_reference ((struct cgraph_node *)data, NULL,
-                               NULL, vnode,
-                               IPA_REF_ADDR, stmt);
-       }
+      if (lang_hooks.callgraph.analyze_expr)
+       lang_hooks.callgraph.analyze_expr (&addr, &walk_subtrees);
+      varpool_mark_needed_node (vnode);
+      if (vnode->alias && vnode->extra_name)
+       vnode = vnode->extra_name;
+      ipa_record_reference ((struct cgraph_node *)data, NULL,
+                           NULL, vnode,
+                           IPA_REF_ADDR, stmt);
     }
 
   return false;
@@ -271,12 +267,21 @@ mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
 /* Mark load of T.  */
 
 static bool
-mark_load (gimple stmt ATTRIBUTE_UNUSED, tree t,
-          void *data ATTRIBUTE_UNUSED)
+mark_load (gimple stmt, tree t, void *data)
 {
   t = get_base_address (t);
-  if (t && TREE_CODE (t) == VAR_DECL
-      && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
+  if (t && TREE_CODE (t) == FUNCTION_DECL)
+    {
+      /* ??? This can happen on platforms with descriptors when these are
+        directly manipulated in the code.  Pretend that it's an address.  */
+      struct cgraph_node *node = cgraph_node (t);
+      cgraph_mark_address_taken_node (node);
+      ipa_record_reference ((struct cgraph_node *)data, NULL,
+                           node, NULL,
+                           IPA_REF_ADDR, stmt);
+    }
+  else if (t && TREE_CODE (t) == VAR_DECL
+          && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
     {
       struct varpool_node *vnode = varpool_node (t);
       int walk_subtrees;
@@ -296,8 +301,7 @@ mark_load (gimple stmt ATTRIBUTE_UNUSED, tree t,
 /* Mark store of T.  */
 
 static bool
-mark_store (gimple stmt ATTRIBUTE_UNUSED, tree t,
-           void *data ATTRIBUTE_UNUSED)
+mark_store (gimple stmt, tree t, void *data)
 {
   t = get_base_address (t);
   if (t && TREE_CODE (t) == VAR_DECL
@@ -313,7 +317,7 @@ mark_store (gimple stmt ATTRIBUTE_UNUSED, tree t,
        vnode = vnode->extra_name;
       ipa_record_reference ((struct cgraph_node *)data, NULL,
                            NULL, vnode,
-                           IPA_REF_STORE, NULL);
+                           IPA_REF_STORE, stmt);
      }
   return false;
 }
@@ -328,7 +332,8 @@ build_cgraph_edges (void)
   struct cgraph_node *node = cgraph_node (current_function_decl);
   struct pointer_set_t *visited_nodes = pointer_set_create ();
   gimple_stmt_iterator gsi;
-  tree step;
+  tree decl;
+  unsigned ix;
 
   /* Create the callgraph edges and record the nodes referenced by the function.
      body.  */
@@ -360,16 +365,19 @@ build_cgraph_edges (void)
              && gimple_omp_parallel_child_fn (stmt))
            {
              tree fn = gimple_omp_parallel_child_fn (stmt);
-             cgraph_mark_needed_node (cgraph_node (fn));
+             ipa_record_reference (node, NULL, cgraph_node (fn),
+                                   NULL, IPA_REF_ADDR, stmt);
            }
          if (gimple_code (stmt) == GIMPLE_OMP_TASK)
            {
              tree fn = gimple_omp_task_child_fn (stmt);
              if (fn)
-               cgraph_mark_needed_node (cgraph_node (fn));
+               ipa_record_reference (node, NULL, cgraph_node (fn),
+                                     NULL, IPA_REF_ADDR, stmt);
              fn = gimple_omp_task_copy_fn (stmt);
              if (fn)
-               cgraph_mark_needed_node (cgraph_node (fn));
+               ipa_record_reference (node, NULL, cgraph_node (fn),
+                                     NULL, IPA_REF_ADDR, stmt);
            }
        }
       for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -378,15 +386,10 @@ build_cgraph_edges (void)
    }
 
   /* Look for initializers of constant variables and private statics.  */
-  for (step = cfun->local_decls;
-       step;
-       step = TREE_CHAIN (step))
-    {
-      tree decl = TREE_VALUE (step);
-      if (TREE_CODE (decl) == VAR_DECL
-         && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl)))
-       varpool_finalize_decl (decl);
-    }
+  FOR_EACH_LOCAL_DECL (cfun, ix, decl)
+    if (TREE_CODE (decl) == VAR_DECL
+       && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl)))
+      varpool_finalize_decl (decl);
   record_eh_tables (node, cfun);
 
   pointer_set_destroy (visited_nodes);
@@ -522,7 +525,7 @@ struct gimple_opt_pass pass_rebuild_cgraph_edges =
   NULL,                                        /* sub */
   NULL,                                        /* next */
   0,                                   /* static_pass_number */
-  TV_NONE,                             /* tv_id */
+  TV_CGRAPH,                           /* tv_id */
   PROP_cfg,                            /* properties_required */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */