+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
#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(())
{
/* 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;
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)
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;
}
{
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));
/* 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;
}
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);
+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
#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
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) \
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;
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 ().
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)
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, \
}
}
+tree
+lhd_callgraph_analyze_expr (tree *tp ATTRIBUTE_UNUSED,
+ int *walk_subtrees ATTRIBUTE_UNUSED,
+ tree decl ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
#include "gt-langhooks.h"
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);
};