From 25c84396dd1bfb44ff5365d8ff512f1233101dfd Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@redhat.com>
Date: Wed, 10 Sep 2003 12:16:20 -0700
Subject: [PATCH] cgraph.h (struct cgraph_node): Rename lowered to analyzed.

        * cgraph.h (struct cgraph_node): Rename lowered to analyzed.
        * cgraphunit.c: Update to match.
        (record_call_1): Rearrange.  Call lang hook for language nodes.
        (cgraph_analyze_function): Don't call lower_function.
        * langhooks.h (struct lang_hooks_for_callgraph): Replace
        lower_function with analyze_expr.
        * langhooks-def.h: Update to match.
        * langhooks.c (lhd_callgraph_analyze_expr): New.

        * decl2.c (cxx_callgraph_analyze_expr): New, from corpse of
        mark_member_pointers.
        (lower_function): Remove.
        * cp-tree.h: Update to match.
        * cp-lang.c (LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR): New.
        (LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION): Remove.

From-SVN: r71277
---
 gcc/ChangeLog       | 11 +++++
 gcc/cgraph.h        |  9 ++---
 gcc/cgraphunit.c    | 98 +++++++++++++++++++++++++++------------------
 gcc/cp/ChangeLog    |  9 +++++
 gcc/cp/cp-lang.c    |  4 +-
 gcc/cp/cp-tree.h    |  2 +-
 gcc/cp/decl2.c      | 27 +++++--------
 gcc/langhooks-def.h | 10 +++--
 gcc/langhooks.c     |  8 ++++
 gcc/langhooks.h     |  7 ++--
 10 files changed, 115 insertions(+), 70 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bac59f1963f6..350d0e513e21 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2003-09-10  Richard Henderson  <rth@redhat.com>
+
+	* cgraph.h (struct cgraph_node): Rename lowered to analyzed.
+	* cgraphunit.c: Update to match.
+	(record_call_1): Rearrange.  Call lang hook for language nodes.
+	(cgraph_analyze_function): Don't call lower_function.
+	* langhooks.h (struct lang_hooks_for_callgraph): Replace 
+	lower_function with analyze_expr.
+	* langhooks-def.h: Update to match.
+	* langhooks.c (lhd_callgraph_analyze_expr): New.
+
 2003-09-10  Martin Husemann  <martin@duskware.de>
 
 	PR target/11965
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 2b30f93499f2..2e6e68918ec6 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -23,7 +23,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #define GCC_CGRAPH_H
 
 /* Information about the function collected locally.
-   Available after function is lowered  */
+   Available after function is analyzed.  */
 
 struct cgraph_local_info GTY(())
 {
@@ -100,10 +100,9 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
   /* Set when function is reachable by call from other function
      that is either reachable or needed.  */
   bool reachable;
-  /* Set when the frontend has been asked to lower representation of this
-     function into trees.  Callees lists are not available when lowered
-     is not set.  */
-  bool lowered;
+  /* Set once the function has been instantiated and its callee
+     lists created.  */
+  bool analyzed;
   /* Set when function is scheduled to be assembled.  */
   bool output;
   struct cgraph_local_info local;
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 02edb697d106..bb55d2d3e8ca 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -165,7 +165,7 @@ cgraph_finalize_function (tree decl)
       memset (&node->local, 0, sizeof (node->local));
       memset (&node->global, 0, sizeof (node->global));
       memset (&node->rtl, 0, sizeof (node->rtl));
-      node->lowered = false;
+      node->analyzed = false;
       if (node->output)
 	abort ();
       while (node->callees)
@@ -209,41 +209,66 @@ cgraph_finalize_function (tree decl)
 static tree
 record_call_1 (tree *tp, int *walk_subtrees, void *data)
 {
-  if (TREE_CODE (*tp) == VAR_DECL && TREE_STATIC (*tp))
-    cgraph_varpool_mark_needed_node (cgraph_varpool_node (*tp));
-  /* Record dereferences to the functions.  This makes the functions
-     reachable unconditionally.  */
-  else if (TREE_CODE (*tp) == ADDR_EXPR && flag_unit_at_a_time)
-    {
-      tree decl = TREE_OPERAND (*tp, 0);
-      if (TREE_CODE (decl) == FUNCTION_DECL)
-        cgraph_mark_needed_node (cgraph_node (decl));
-    }
-  else if (TREE_CODE (*tp) == CALL_EXPR)
+  tree t = *tp;
+
+  switch (TREE_CODE (t))
     {
-      tree decl = get_callee_fndecl (*tp);
-      if (decl && TREE_CODE (decl) == FUNCTION_DECL)
+    case VAR_DECL:
+      /* ??? Really, we should mark this decl as *potentially* referenced
+	 by this function and re-examine whether the decl is actually used
+	 after rtl has been generated.  */
+      if (TREE_STATIC (t))
+        cgraph_varpool_mark_needed_node (cgraph_varpool_node (t));
+      break;
+
+    case ADDR_EXPR:
+      if (flag_unit_at_a_time)
+	{
+	  /* Record dereferences to the functions.  This makes the
+	     functions reachable unconditionally.  */
+	  tree decl = TREE_OPERAND (*tp, 0);
+	  if (TREE_CODE (decl) == FUNCTION_DECL)
+	    cgraph_mark_needed_node (cgraph_node (decl));
+	}
+      break;
+
+    case CALL_EXPR:
+      {
+	tree decl = get_callee_fndecl (*tp);
+	if (decl && TREE_CODE (decl) == FUNCTION_DECL)
+	  {
+	    if (DECL_BUILT_IN (decl))
+	      return NULL;
+	    cgraph_record_call (data, decl);
+
+	    /* When we see a function call, we don't want to look at the
+	       function reference in the ADDR_EXPR that is hanging from
+	       the CALL_EXPR we're examining here, because we would
+	       conclude incorrectly that the function's address could be
+	       taken by something that is not a function call.  So only
+	       walk the function parameter list, skip the other subtrees.  */
+
+	    walk_tree (&TREE_OPERAND (*tp, 1), record_call_1, data,
+		       visited_nodes);
+	    *walk_subtrees = 0;
+	  }
+	break;
+      }
+
+    default:
+      /* Save some cycles by not walking types and declaration as we
+	 won't find anything useful there anyway.  */
+      if (DECL_P (*tp) || TYPE_P (*tp))
 	{
-	  if (DECL_BUILT_IN (decl))
-	    return NULL;
-	  cgraph_record_call (data, decl);
-
-	  /* When we see a function call, we don't want to look at the
-	     function reference in the ADDR_EXPR that is hanging from
-	     the CALL_EXPR we're examining here, because we would
-	     conclude incorrectly that the function's address could be
-	     taken by something that is not a function call.  So only
-	     walk the function parameter list, skip the other subtrees.  */
-
-	  walk_tree (&TREE_OPERAND (*tp, 1), record_call_1, data,
-		     visited_nodes);
 	  *walk_subtrees = 0;
+	  break;
 	}
+
+      if ((unsigned int) TREE_CODE (t) >= LAST_AND_UNUSED_TREE_CODE)
+	return (*lang_hooks.callgraph.analyze_expr) (tp, walk_subtrees, data);
+      break;
     }
-  /* Save some cycles by not walking types and declaration as we won't find anything
-     usefull there anyway.  */
-  if (DECL_P (*tp) || TYPE_P (*tp))
-    *walk_subtrees = 0;
+
   return NULL;
 }
 
@@ -267,10 +292,7 @@ cgraph_analyze_function (struct cgraph_node *node)
 {
   tree decl = node->decl;
 
-  if (lang_hooks.callgraph.lower_function)
-    (*lang_hooks.callgraph.lower_function) (decl);
-
-  current_function_decl = node->decl;
+  current_function_decl = decl;
 
   /* First kill forward declaration so reverse inlining works properly.  */
   cgraph_create_edges (decl, DECL_SAVED_TREE (decl));
@@ -286,13 +308,13 @@ cgraph_analyze_function (struct cgraph_node *node)
 
   /* Inlining characteristics are maintained by the cgraph_mark_inline.  */
   node->global.insns = node->local.self_insns;
-  if (!DECL_EXTERNAL (node->decl))
+  if (!DECL_EXTERNAL (decl))
     {
       node->global.cloned_times = 1;
       node->global.will_be_output = true;
     }
 
-  node->lowered = true;
+  node->analyzed = true;
   current_function_decl = NULL;
 }
 
@@ -341,7 +363,7 @@ cgraph_finalize_compilation_unit (void)
       if (!DECL_SAVED_TREE (decl))
 	continue;
 
-      if (node->lowered || !node->reachable || !DECL_SAVED_TREE (decl))
+      if (node->analyzed || !node->reachable || !DECL_SAVED_TREE (decl))
 	abort ();
 
       cgraph_analyze_function (node);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b36f7aa2dd22..918d5dad2ca0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2003-09-10  Richard Henderson  <rth@redhat.com>
+
+	* decl2.c (cxx_callgraph_analyze_expr): New, from corpse of
+	mark_member_pointers.
+	(lower_function): Remove.
+	* cp-tree.h: Update to match.
+	* cp-lang.c (LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR): New.
+	(LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION): Remove.
+
 2003-09-09  Richard Henderson  <rth@redhat.com>
 
 	* semantics.c (expand_or_defer_fn): Update call to 
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index 527054c991f8..e71d53ad281f 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -163,10 +163,10 @@ static void cxx_initialize_diagnostics (diagnostic_context *);
 #undef LANG_HOOKS_EXPR_SIZE
 #define LANG_HOOKS_EXPR_SIZE cp_expr_size
 
+#undef LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR
+#define LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR cxx_callgraph_analyze_expr
 #undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
 #define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION expand_body
-#undef LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION
-#define LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION lower_function
 
 #undef LANG_HOOKS_MAKE_TYPE
 #define LANG_HOOKS_MAKE_TYPE cxx_make_type
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 394514df52b6..8ab8c6c41ce0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3806,7 +3806,7 @@ extern tree build_artificial_parm (tree, tree);
 extern tree get_guard (tree);
 extern tree get_guard_cond (tree);
 extern tree set_guard (tree);
-extern void lower_function (tree);
+extern tree cxx_callgraph_analyze_expr (tree *, int *, tree);
 
 /* XXX Not i18n clean.  */
 #define cp_deprecated(STR)						\
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 8c68a02f68ef..8e2c6c75fd50 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2557,10 +2557,15 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
   return 0;
 }
 
-/* Callgraph code does not understand the member pointers.  Mark the methods
-   referenced as used.  */
-static tree
-mark_member_pointers (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
+/* Called via LANGHOOK_CALLGRAPH_ANALYZE_EXPR.  It is supposed to mark
+   decls referenced from frontend specific constructs; it will be called
+   only for language-specific tree nodes.
+
+   Here we must deal with member pointers.  */
+
+tree
+cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees,
+			    tree from ATTRIBUTE_UNUSED)
 {
   tree t = *tp;
 
@@ -2572,22 +2577,10 @@ mark_member_pointers (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
       break;
 
     default:
-      /* Avoid useless walking of complex type and declaration nodes.  */
-      if (TYPE_P (t) || DECL_P (t))
-	*walk_subtrees = 0;
       break;
     }
 
-  return 0;
-}
-
-/* Called via LANGHOOK_CALLGRAPH_LOWER_FUNCTION.  It is supposed to lower
-   frontend specific constructs that would otherwise confuse the middle end.  */
-void
-lower_function (tree fn)
-{
-  walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
-		  		mark_member_pointers, NULL);
+  return NULL;
 }
 
 /* This routine is called from the last rule in yyparse ().
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 5089fdaba116..57b10da15f45 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -82,6 +82,8 @@ extern int lhd_tree_inlining_start_inlining (tree);
 extern void lhd_tree_inlining_end_inlining (tree);
 extern tree lhd_tree_inlining_convert_parm_for_inlining (tree, tree, tree);
 extern void lhd_initialize_diagnostics (struct diagnostic_context *);
+extern tree lhd_callgraph_analyze_expr (tree *, int *, tree);
+
 
 #define LANG_HOOKS_NAME			"GNU unknown"
 #define LANG_HOOKS_IDENTIFIER_SIZE	sizeof (struct lang_identifier)
@@ -174,15 +176,15 @@ extern void lhd_initialize_diagnostics (struct diagnostic_context *);
   LANG_HOOKS_TREE_INLINING_END_INLINING, \
   LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING, \
   LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS \
-} \
+}
 
-#define LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION NULL
+#define LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR lhd_callgraph_analyze_expr
 #define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION NULL
 
 #define LANG_HOOKS_CALLGRAPH_INITIALIZER { \
-  LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION, \
+  LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR, \
   LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION, \
-} \
+}
 
 #define LANG_HOOKS_FUNCTION_INITIALIZER {	\
   LANG_HOOKS_FUNCTION_INIT,			\
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 7a003bbcc00d..2b9f0ec62b48 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -535,4 +535,12 @@ lhd_print_error_function (diagnostic_context *context, const char *file)
     }
 }
 
+tree
+lhd_callgraph_analyze_expr (tree *tp ATTRIBUTE_UNUSED,
+			    int *walk_subtrees ATTRIBUTE_UNUSED,
+			    tree decl ATTRIBUTE_UNUSED)
+{
+  return NULL;
+}
+
 #include "gt-langhooks.h"
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 0d86478fc647..195446c702c9 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -53,9 +53,10 @@ struct lang_hooks_for_tree_inlining
 
 struct lang_hooks_for_callgraph
 {
-  /* Function passed as argument is needed and will be compiled.
-     Lower the representation so the calls are explicit.  */
-  void (*lower_function) (tree);
+  /* The node passed is a language-specific tree node.  If its contents
+     are relevant to use of other declarations, mark them.  */
+  tree (*analyze_expr) (tree *, int *, tree);
+
   /* Produce RTL for function passed as argument.  */
   void (*expand_function) (tree);
 };
-- 
GitLab