From 25c84396dd1bfb44ff5365d8ff512f1233101dfd Mon Sep 17 00:00:00 2001 From: Richard Henderson 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 + + * 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 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 + + * 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 * 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); }; -- 2.39.2