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
This commit is contained in:
parent
707691d877
commit
25c84396dd
10 changed files with 116 additions and 71 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
100
gcc/cgraphunit.c
100
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 t = *tp;
|
||||
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
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 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)
|
||||
{
|
||||
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;
|
||||
/* 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))
|
||||
{
|
||||
*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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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 ().
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue