Commit 8f235343 by Jan Hubicka Committed by Jan Hubicka

re PR middle-end/16460 (ICE when compiling glibc (ld-ctype.c))

	PR middle-end/16460

	* cgraph.c (cgraph_unnest_node): New function.
	(c_finalize): Rename to ....
	(c_warn_unused_result_recursivly): ... this one; do only the warning
	(finish_function): Finalize the toplevel function; do not lower nested tree.
	* cgraph.h (cgraph_unnest_node): Declare.
	* cgraphunit.c (decide_is_function_needed): Do not use cgraph
	nestedness datastructure.
	* cse.c (cse_insn): Do not cprop nonlocal LABEL_REFs.
	* reload1.c (set_label_offsets): Fix call of set_label_offsets.
	* tree-nested.c (finlize_nesting_tree_1):  Use un-nesting code.

	* utils.c (gnat_finalize): Remove.
	(end_subprog_body): Directly call cgraph_finalize_function;
	do not lower the nested functions.

	* trans-decl.c (build_entry_thunks): Finalize the function; do not lower
	tree.
	(gfc_generate_function_code): Likewise.

From-SVN: r87770
parent 04161e2b
2004-09-20 Jan Hubicka <jh@suse.cz>
PR middle-end/16460
* cgraph.c (cgraph_unnest_node): New function.
(c_finalize): Rename to ....
(c_warn_unused_result_recursivly): ... this one; do only the warning
(finish_function): Finalize the toplevel function; do not lower nested tree.
* cgraph.h (cgraph_unnest_node): Declare.
* cgraphunit.c (decide_is_function_needed): Do not use cgraph
nestedness datastructure.
* cse.c (cse_insn): Do not cprop nonlocal LABEL_REFs.
* reload1.c (set_label_offsets): Fix call of set_label_offsets.
* tree-nested.c (finlize_nesting_tree_1): Use un-nesting code.
2004-09-20 Richard Henderson <rth@redhat.com> 2004-09-20 Richard Henderson <rth@redhat.com>
* config/alpha/alpha.c (some_small_symbolic_operand_int): Rename * config/alpha/alpha.c (some_small_symbolic_operand_int): Rename
......
2004-09-20 Jan Hubicka <jh@suse.cz>
* utils.c (gnat_finalize): Remove.
(end_subprog_body): Directly call cgraph_finalize_function;
do not lower the nested functions.
2004-09-20 Robert Dewar <dewar@gnat.com> 2004-09-20 Robert Dewar <dewar@gnat.com>
PR ada/17540 PR ada/17540
......
...@@ -125,7 +125,6 @@ static tree compute_related_constant (tree, tree); ...@@ -125,7 +125,6 @@ static tree compute_related_constant (tree, tree);
static tree split_plus (tree, tree *); static tree split_plus (tree, tree *);
static bool value_zerop (tree); static bool value_zerop (tree);
static void gnat_gimplify_function (tree); static void gnat_gimplify_function (tree);
static void gnat_finalize (tree);
static tree float_type_for_precision (int, enum machine_mode); static tree float_type_for_precision (int, enum machine_mode);
static tree convert_to_fat_pointer (tree, tree); static tree convert_to_fat_pointer (tree, tree);
static tree convert_to_thin_pointer (tree, tree); static tree convert_to_thin_pointer (tree, tree);
...@@ -1793,8 +1792,7 @@ end_subprog_body (tree body) ...@@ -1793,8 +1792,7 @@ end_subprog_body (tree body)
if (!DECL_CONTEXT (fndecl)) if (!DECL_CONTEXT (fndecl))
{ {
gnat_gimplify_function (fndecl); gnat_gimplify_function (fndecl);
lower_nested_functions (fndecl); cgraph_finalize_function (fndecl, false);
gnat_finalize (fndecl);
} }
else else
/* Register this function with cgraph just far enough to get it /* Register this function with cgraph just far enough to get it
...@@ -1820,21 +1818,6 @@ gnat_gimplify_function (tree fndecl) ...@@ -1820,21 +1818,6 @@ gnat_gimplify_function (tree fndecl)
for (cgn = cgn->nested; cgn; cgn = cgn->next_nested) for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
gnat_gimplify_function (cgn->decl); gnat_gimplify_function (cgn->decl);
} }
/* Give FNDECL and all its nested functions to cgraph for compilation. */
static void
gnat_finalize (tree fndecl)
{
struct cgraph_node *cgn;
/* Finalize all nested functions now. */
cgn = cgraph_node (fndecl);
for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
gnat_finalize (cgn->decl);
cgraph_finalize_function (fndecl, false);
}
/* Return a definition for a builtin function named NAME and whose data type /* Return a definition for a builtin function named NAME and whose data type
is TYPE. TYPE should be a function type with argument types. is TYPE. TYPE should be a function type with argument types.
......
...@@ -693,4 +693,17 @@ cgraph_clone_node (struct cgraph_node *n) ...@@ -693,4 +693,17 @@ cgraph_clone_node (struct cgraph_node *n)
return new; return new;
} }
/* NODE is no longer nested function; update cgraph accordingly. */
void
cgraph_unnest_node (struct cgraph_node *node)
{
struct cgraph_node **node2 = &node->origin->nested;
gcc_assert (node->origin);
while (*node2 != node)
node2 = &(*node2)->next_nested;
*node2 = node->next_nested;
node->origin = NULL;
}
#include "gt-cgraph.h" #include "gt-cgraph.h"
...@@ -266,6 +266,7 @@ bool cgraph_varpool_assemble_pending_decls (void); ...@@ -266,6 +266,7 @@ bool cgraph_varpool_assemble_pending_decls (void);
void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *); void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
bool cgraph_function_possibly_inlined_p (tree); bool cgraph_function_possibly_inlined_p (tree);
void cgraph_unnest_node (struct cgraph_node *node);
/* In cgraphunit.c */ /* In cgraphunit.c */
bool cgraph_assemble_pending_functions (void); bool cgraph_assemble_pending_functions (void);
......
...@@ -263,7 +263,7 @@ static tree memory_identifier; ...@@ -263,7 +263,7 @@ static tree memory_identifier;
static bool static bool
decide_is_function_needed (struct cgraph_node *node, tree decl) decide_is_function_needed (struct cgraph_node *node, tree decl)
{ {
struct cgraph_node *origin; tree origin;
/* If we decided it was needed before, but at the time we didn't have /* If we decided it was needed before, but at the time we didn't have
the body of the function available, then it's still needed. We have the body of the function available, then it's still needed. We have
...@@ -303,8 +303,9 @@ decide_is_function_needed (struct cgraph_node *node, tree decl) ...@@ -303,8 +303,9 @@ decide_is_function_needed (struct cgraph_node *node, tree decl)
return false; return false;
/* Nested functions of extern inline function shall not be emit unless /* Nested functions of extern inline function shall not be emit unless
we inlined the origin. */ we inlined the origin. */
for (origin = node->origin; origin; origin = origin->origin) for (origin = decl_function_context (decl); origin;
if (DECL_EXTERNAL (origin->decl)) origin = decl_function_context (origin))
if (DECL_EXTERNAL (origin))
return false; return false;
/* We want to emit COMDAT functions only when absolutely necessary. */ /* We want to emit COMDAT functions only when absolutely necessary. */
if (DECL_COMDAT (decl)) if (DECL_COMDAT (decl))
...@@ -586,6 +587,9 @@ cgraph_finalize_function (tree decl, bool nested) ...@@ -586,6 +587,9 @@ cgraph_finalize_function (tree decl, bool nested)
notice_global_symbol (decl); notice_global_symbol (decl);
node->decl = decl; node->decl = decl;
node->local.finalized = true; node->local.finalized = true;
if (node->nested)
lower_nested_functions (decl);
gcc_assert (!node->nested);
/* If not unit at a time, then we need to create the call graph /* If not unit at a time, then we need to create the call graph
now, so that called functions can be queued and emitted now. */ now, so that called functions can be queued and emitted now. */
......
...@@ -5623,7 +5623,8 @@ cse_insn (rtx insn, rtx libcall_insn) ...@@ -5623,7 +5623,8 @@ cse_insn (rtx insn, rtx libcall_insn)
/* If this SET is now setting PC to a label, we know it used to /* If this SET is now setting PC to a label, we know it used to
be a conditional or computed branch. */ be a conditional or computed branch. */
else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF) else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF
&& !LABEL_REF_NONLOCAL_P (src))
{ {
/* Now emit a BARRIER after the unconditional jump. */ /* Now emit a BARRIER after the unconditional jump. */
if (NEXT_INSN (insn) == 0 if (NEXT_INSN (insn) == 0
......
2004-09-20 Jan Hubicka <jh@suse.cz>
* trans-decl.c (build_entry_thunks): Finalize the function; do not lower
tree.
(gfc_generate_function_code): Likewise.
2004-09-20 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de> 2004-09-20 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
PR fortran/15957 PR fortran/15957
......
...@@ -1255,22 +1255,6 @@ create_function_arglist (gfc_symbol * sym) ...@@ -1255,22 +1255,6 @@ create_function_arglist (gfc_symbol * sym)
DECL_ARGUMENTS (fndecl) = arglist; DECL_ARGUMENTS (fndecl) = arglist;
} }
/* Finalize DECL and all nested functions with cgraph. */
static void
gfc_finalize (tree decl)
{
struct cgraph_node *cgn;
cgn = cgraph_node (decl);
for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
gfc_finalize (cgn->decl);
cgraph_finalize_function (decl, false);
}
/* Convert FNDECL's code to GIMPLE and handle any nested functions. */ /* Convert FNDECL's code to GIMPLE and handle any nested functions. */
static void static void
...@@ -1431,8 +1415,7 @@ build_entry_thunks (gfc_namespace * ns) ...@@ -1431,8 +1415,7 @@ build_entry_thunks (gfc_namespace * ns)
current_function_decl = NULL_TREE; current_function_decl = NULL_TREE;
gfc_gimplify_function (thunk_fndecl); gfc_gimplify_function (thunk_fndecl);
lower_nested_functions (thunk_fndecl); cgraph_finalize_function (thunk_fndecl, false);
gfc_finalize (thunk_fndecl);
/* We share the symbols in the formal argument list with other entry /* We share the symbols in the formal argument list with other entry
points and the master function. Clear them so that they are points and the master function. Clear them so that they are
...@@ -2313,8 +2296,7 @@ gfc_generate_function_code (gfc_namespace * ns) ...@@ -2313,8 +2296,7 @@ gfc_generate_function_code (gfc_namespace * ns)
else else
{ {
gfc_gimplify_function (fndecl); gfc_gimplify_function (fndecl);
lower_nested_functions (fndecl); cgraph_finalize_function (fndecl, false);
gfc_finalize (fndecl);
} }
} }
......
...@@ -2185,7 +2185,7 @@ set_label_offsets (rtx x, rtx insn, int initial_p) ...@@ -2185,7 +2185,7 @@ set_label_offsets (rtx x, rtx insn, int initial_p)
return; return;
case LABEL_REF: case LABEL_REF:
set_label_offsets (XEXP (SET_SRC (x), 0), insn, initial_p); set_label_offsets (SET_SRC (x), insn, initial_p);
return; return;
case IF_THEN_ELSE: case IF_THEN_ELSE:
......
...@@ -1207,6 +1207,7 @@ finalize_nesting_tree_1 (struct nesting_info *root) ...@@ -1207,6 +1207,7 @@ finalize_nesting_tree_1 (struct nesting_info *root)
tree stmt_list = NULL; tree stmt_list = NULL;
tree context = root->context; tree context = root->context;
struct function *sf; struct function *sf;
struct cgraph_node *node;
/* If we created a non-local frame type or decl, we need to lay them /* If we created a non-local frame type or decl, we need to lay them
out at this time. */ out at this time. */
...@@ -1317,6 +1318,15 @@ finalize_nesting_tree_1 (struct nesting_info *root) ...@@ -1317,6 +1318,15 @@ finalize_nesting_tree_1 (struct nesting_info *root)
/* Dump the translated tree function. */ /* Dump the translated tree function. */
dump_function (TDI_nested, root->context); dump_function (TDI_nested, root->context);
node = cgraph_node (root->context);
/* For nested functions update the cgraph to reflect unnesting.
We also delay finalizing of these functions up to this point. */
if (node->origin)
{
cgraph_unnest_node (cgraph_node (root->context));
cgraph_finalize_function (root->context, true);
}
} }
static void static void
......
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