Commit 25c84396 by Richard Henderson Committed by Richard Henderson

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
parent 707691d8
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> 2003-09-10 Martin Husemann <martin@duskware.de>
PR target/11965 PR target/11965
......
...@@ -23,7 +23,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -23,7 +23,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define GCC_CGRAPH_H #define GCC_CGRAPH_H
/* Information about the function collected locally. /* Information about the function collected locally.
Available after function is lowered */ Available after function is analyzed. */
struct cgraph_local_info GTY(()) struct cgraph_local_info GTY(())
{ {
...@@ -100,10 +100,9 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) ...@@ -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 /* Set when function is reachable by call from other function
that is either reachable or needed. */ that is either reachable or needed. */
bool reachable; bool reachable;
/* Set when the frontend has been asked to lower representation of this /* Set once the function has been instantiated and its callee
function into trees. Callees lists are not available when lowered lists created. */
is not set. */ bool analyzed;
bool lowered;
/* Set when function is scheduled to be assembled. */ /* Set when function is scheduled to be assembled. */
bool output; bool output;
struct cgraph_local_info local; struct cgraph_local_info local;
......
...@@ -165,7 +165,7 @@ cgraph_finalize_function (tree decl) ...@@ -165,7 +165,7 @@ cgraph_finalize_function (tree decl)
memset (&node->local, 0, sizeof (node->local)); memset (&node->local, 0, sizeof (node->local));
memset (&node->global, 0, sizeof (node->global)); memset (&node->global, 0, sizeof (node->global));
memset (&node->rtl, 0, sizeof (node->rtl)); memset (&node->rtl, 0, sizeof (node->rtl));
node->lowered = false; node->analyzed = false;
if (node->output) if (node->output)
abort (); abort ();
while (node->callees) while (node->callees)
...@@ -209,17 +209,30 @@ cgraph_finalize_function (tree decl) ...@@ -209,17 +209,30 @@ cgraph_finalize_function (tree decl)
static tree static tree
record_call_1 (tree *tp, int *walk_subtrees, void *data) record_call_1 (tree *tp, int *walk_subtrees, void *data)
{ {
if (TREE_CODE (*tp) == VAR_DECL && TREE_STATIC (*tp)) tree t = *tp;
cgraph_varpool_mark_needed_node (cgraph_varpool_node (*tp));
/* Record dereferences to the functions. This makes the functions switch (TREE_CODE (t))
reachable unconditionally. */ {
else if (TREE_CODE (*tp) == ADDR_EXPR && flag_unit_at_a_time) 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); tree decl = TREE_OPERAND (*tp, 0);
if (TREE_CODE (decl) == FUNCTION_DECL) if (TREE_CODE (decl) == FUNCTION_DECL)
cgraph_mark_needed_node (cgraph_node (decl)); cgraph_mark_needed_node (cgraph_node (decl));
} }
else if (TREE_CODE (*tp) == CALL_EXPR) break;
case CALL_EXPR:
{ {
tree decl = get_callee_fndecl (*tp); tree decl = get_callee_fndecl (*tp);
if (decl && TREE_CODE (decl) == FUNCTION_DECL) if (decl && TREE_CODE (decl) == FUNCTION_DECL)
...@@ -239,11 +252,23 @@ record_call_1 (tree *tp, int *walk_subtrees, void *data) ...@@ -239,11 +252,23 @@ record_call_1 (tree *tp, int *walk_subtrees, void *data)
visited_nodes); visited_nodes);
*walk_subtrees = 0; *walk_subtrees = 0;
} }
break;
} }
/* Save some cycles by not walking types and declaration as we won't find anything
usefull there anyway. */ 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_P (*tp) || TYPE_P (*tp))
{
*walk_subtrees = 0; *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;
}
return NULL; return NULL;
} }
...@@ -267,10 +292,7 @@ cgraph_analyze_function (struct cgraph_node *node) ...@@ -267,10 +292,7 @@ cgraph_analyze_function (struct cgraph_node *node)
{ {
tree decl = node->decl; tree decl = node->decl;
if (lang_hooks.callgraph.lower_function) current_function_decl = decl;
(*lang_hooks.callgraph.lower_function) (decl);
current_function_decl = node->decl;
/* First kill forward declaration so reverse inlining works properly. */ /* First kill forward declaration so reverse inlining works properly. */
cgraph_create_edges (decl, DECL_SAVED_TREE (decl)); cgraph_create_edges (decl, DECL_SAVED_TREE (decl));
...@@ -286,13 +308,13 @@ cgraph_analyze_function (struct cgraph_node *node) ...@@ -286,13 +308,13 @@ cgraph_analyze_function (struct cgraph_node *node)
/* Inlining characteristics are maintained by the cgraph_mark_inline. */ /* Inlining characteristics are maintained by the cgraph_mark_inline. */
node->global.insns = node->local.self_insns; node->global.insns = node->local.self_insns;
if (!DECL_EXTERNAL (node->decl)) if (!DECL_EXTERNAL (decl))
{ {
node->global.cloned_times = 1; node->global.cloned_times = 1;
node->global.will_be_output = true; node->global.will_be_output = true;
} }
node->lowered = true; node->analyzed = true;
current_function_decl = NULL; current_function_decl = NULL;
} }
...@@ -341,7 +363,7 @@ cgraph_finalize_compilation_unit (void) ...@@ -341,7 +363,7 @@ cgraph_finalize_compilation_unit (void)
if (!DECL_SAVED_TREE (decl)) if (!DECL_SAVED_TREE (decl))
continue; continue;
if (node->lowered || !node->reachable || !DECL_SAVED_TREE (decl)) if (node->analyzed || !node->reachable || !DECL_SAVED_TREE (decl))
abort (); abort ();
cgraph_analyze_function (node); cgraph_analyze_function (node);
......
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> 2003-09-09 Richard Henderson <rth@redhat.com>
* semantics.c (expand_or_defer_fn): Update call to * semantics.c (expand_or_defer_fn): Update call to
......
...@@ -163,10 +163,10 @@ static void cxx_initialize_diagnostics (diagnostic_context *); ...@@ -163,10 +163,10 @@ static void cxx_initialize_diagnostics (diagnostic_context *);
#undef LANG_HOOKS_EXPR_SIZE #undef LANG_HOOKS_EXPR_SIZE
#define LANG_HOOKS_EXPR_SIZE cp_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 #undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION expand_body #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 #undef LANG_HOOKS_MAKE_TYPE
#define LANG_HOOKS_MAKE_TYPE cxx_make_type #define LANG_HOOKS_MAKE_TYPE cxx_make_type
......
...@@ -3806,7 +3806,7 @@ extern tree build_artificial_parm (tree, tree); ...@@ -3806,7 +3806,7 @@ extern tree build_artificial_parm (tree, tree);
extern tree get_guard (tree); extern tree get_guard (tree);
extern tree get_guard_cond (tree); extern tree get_guard_cond (tree);
extern tree set_guard (tree); extern tree set_guard (tree);
extern void lower_function (tree); extern tree cxx_callgraph_analyze_expr (tree *, int *, tree);
/* XXX Not i18n clean. */ /* XXX Not i18n clean. */
#define cp_deprecated(STR) \ #define cp_deprecated(STR) \
......
...@@ -2557,10 +2557,15 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data) ...@@ -2557,10 +2557,15 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
return 0; return 0;
} }
/* Callgraph code does not understand the member pointers. Mark the methods /* Called via LANGHOOK_CALLGRAPH_ANALYZE_EXPR. It is supposed to mark
referenced as used. */ decls referenced from frontend specific constructs; it will be called
static tree only for language-specific tree nodes.
mark_member_pointers (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
Here we must deal with member pointers. */
tree
cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees,
tree from ATTRIBUTE_UNUSED)
{ {
tree t = *tp; tree t = *tp;
...@@ -2572,22 +2577,10 @@ mark_member_pointers (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) ...@@ -2572,22 +2577,10 @@ mark_member_pointers (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
break; break;
default: default:
/* Avoid useless walking of complex type and declaration nodes. */
if (TYPE_P (t) || DECL_P (t))
*walk_subtrees = 0;
break; break;
} }
return 0; return NULL;
}
/* 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);
} }
/* This routine is called from the last rule in yyparse (). /* This routine is called from the last rule in yyparse ().
......
...@@ -82,6 +82,8 @@ extern int lhd_tree_inlining_start_inlining (tree); ...@@ -82,6 +82,8 @@ extern int lhd_tree_inlining_start_inlining (tree);
extern void lhd_tree_inlining_end_inlining (tree); extern void lhd_tree_inlining_end_inlining (tree);
extern tree lhd_tree_inlining_convert_parm_for_inlining (tree, tree, tree); extern tree lhd_tree_inlining_convert_parm_for_inlining (tree, tree, tree);
extern void lhd_initialize_diagnostics (struct diagnostic_context *); 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_NAME "GNU unknown"
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier) #define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
...@@ -174,15 +176,15 @@ extern void lhd_initialize_diagnostics (struct diagnostic_context *); ...@@ -174,15 +176,15 @@ extern void lhd_initialize_diagnostics (struct diagnostic_context *);
LANG_HOOKS_TREE_INLINING_END_INLINING, \ LANG_HOOKS_TREE_INLINING_END_INLINING, \
LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING, \ LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING, \
LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS \ 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_EXPAND_FUNCTION NULL
#define LANG_HOOKS_CALLGRAPH_INITIALIZER { \ #define LANG_HOOKS_CALLGRAPH_INITIALIZER { \
LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION, \ LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR, \
LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION, \ LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION, \
} \ }
#define LANG_HOOKS_FUNCTION_INITIALIZER { \ #define LANG_HOOKS_FUNCTION_INITIALIZER { \
LANG_HOOKS_FUNCTION_INIT, \ LANG_HOOKS_FUNCTION_INIT, \
......
...@@ -535,4 +535,12 @@ lhd_print_error_function (diagnostic_context *context, const char *file) ...@@ -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" #include "gt-langhooks.h"
...@@ -53,9 +53,10 @@ struct lang_hooks_for_tree_inlining ...@@ -53,9 +53,10 @@ struct lang_hooks_for_tree_inlining
struct lang_hooks_for_callgraph struct lang_hooks_for_callgraph
{ {
/* Function passed as argument is needed and will be compiled. /* The node passed is a language-specific tree node. If its contents
Lower the representation so the calls are explicit. */ are relevant to use of other declarations, mark them. */
void (*lower_function) (tree); tree (*analyze_expr) (tree *, int *, tree);
/* Produce RTL for function passed as argument. */ /* Produce RTL for function passed as argument. */
void (*expand_function) (tree); void (*expand_function) (tree);
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment