Commit 39ecc018 by Jan Hubicka Committed by Jan Hubicka

re PR tree-optimization/37315 (gcc.c-torture/execute/931018-1.c int-compare.c…

re PR tree-optimization/37315 (gcc.c-torture/execute/931018-1.c  int-compare.c ieee/inf-2.c mzero6.c)


	PR tree-optimization/37315
	* cgraph.c (cgraph_create_edge): Use gimple_has_body_p.
	* cgraphunit.c (verify_cgraph_node): drop gimple_body check.
	(cgraph_analyze_functions): Use node->analyzed
	(cgraph_mark_functions_to_output): Likewise.
	(cgraph_expand_function): All functions can be released after
	expanding.
	(cgraph_optimize): Use gimple_has_body_p.
	* ipa-inline.c (cgraph_clone_inlined_nodes): Use analyzed flag.
	(cgraph_decide_inlining_incrementally): Likewise.
	(inline_transform): Inline transform.
	* tree-inline.c (initialize_cfun): Do now shallow copy structure;
	copy fields needed.
	(inlinable_function_p): Drop gimple_body check.
	(expand_call_inline): Use gimple_has_body_p.
	* gimple.c (gimple_has_body_p): New.
	* gimple.h (gimple_has_body_p): Add prototype.
	* tree-cfg.c (execute_build_cfg): Remove gimple_body.
	(dump_function_to_file): Use gimple_has_body_p check.

From-SVN: r139945
parent cafea0e4
2008-09-03 Jan Hubicka <jh@suse.cz>
PR tree-optimization/37315
* cgraph.c (cgraph_create_edge): Use gimple_has_body_p.
* cgraphunit.c (verify_cgraph_node): drop gimple_body check.
(cgraph_analyze_functions): Use node->analyzed
(cgraph_mark_functions_to_output): Likewise.
(cgraph_expand_function): All functions can be released after
expanding.
(cgraph_optimize): Use gimple_has_body_p.
* ipa-inline.c (cgraph_clone_inlined_nodes): Use analyzed flag.
(cgraph_decide_inlining_incrementally): Likewise.
(inline_transform): Inline transform.
* tree-inline.c (initialize_cfun): Do now shallow copy structure;
copy fields needed.
(inlinable_function_p): Drop gimple_body check.
(expand_call_inline): Use gimple_has_body_p.
* gimple.c (gimple_has_body_p): New.
* gimple.h (gimple_has_body_p): Add prototype.
* tree-cfg.c (execute_build_cfg): Remove gimple_body.
(dump_function_to_file): Use gimple_has_body_p check.
2008-09-03 Jakub Jelinek <jakub@redhat.com>
PR c++/37346
......
......@@ -645,7 +645,7 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
gcc_assert (is_gimple_call (call_stmt));
if (!gimple_body (callee->decl))
if (!callee->analyzed)
edge->inline_failed = N_("function body not available");
else if (callee->local.redefined_extern_inline)
edge->inline_failed = N_("redefined extern inline functions are not "
......@@ -1073,7 +1073,7 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
fprintf (f, " needed");
else if (node->reachable)
fprintf (f, " reachable");
if (gimple_body (node->decl))
if (gimple_has_body_p (node->decl))
fprintf (f, " body");
if (node->output)
fprintf (f, " output");
......
......@@ -639,7 +639,6 @@ verify_cgraph_node (struct cgraph_node *node)
}
if (node->analyzed
&& gimple_body (node->decl)
&& !TREE_ASM_WRITTEN (node->decl)
&& (!DECL_EXTERNAL (node->decl) || node->global.inlined_to))
{
......@@ -860,7 +859,7 @@ cgraph_analyze_functions (void)
{
fprintf (cgraph_dump_file, "Initial entry points:");
for (node = cgraph_nodes; node != first_analyzed; node = node->next)
if (node->needed && gimple_body (node->decl))
if (node->needed)
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
fprintf (cgraph_dump_file, "\n");
}
......@@ -912,7 +911,7 @@ cgraph_analyze_functions (void)
{
fprintf (cgraph_dump_file, "Unit entry points:");
for (node = cgraph_nodes; node != first_analyzed; node = node->next)
if (node->needed && gimple_body (node->decl))
if (node->needed)
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
fprintf (cgraph_dump_file, "\n\nInitial ");
dump_cgraph (cgraph_dump_file);
......@@ -926,10 +925,10 @@ cgraph_analyze_functions (void)
tree decl = node->decl;
next = node->next;
if (node->local.finalized && !gimple_body (decl))
if (node->local.finalized && !gimple_has_body_p (decl))
cgraph_reset_node (node);
if (!node->reachable && gimple_body (decl))
if (!node->reachable && gimple_has_body_p (decl))
{
if (cgraph_dump_file)
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
......@@ -938,7 +937,7 @@ cgraph_analyze_functions (void)
}
else
node->next_needed = NULL;
gcc_assert (!node->local.finalized || gimple_body (decl));
gcc_assert (!node->local.finalized || gimple_has_body_p (decl));
gcc_assert (node->analyzed == node->local.finalized);
}
if (cgraph_dump_file)
......@@ -991,7 +990,7 @@ cgraph_mark_functions_to_output (void)
/* We need to output all local functions that are used and not
always inlined, as well as those that are reachable from
outside the current compilation unit. */
if (gimple_body (decl)
if (node->analyzed
&& !node->global.inlined_to
&& (node->needed
|| (e && node->reachable))
......@@ -1003,7 +1002,7 @@ cgraph_mark_functions_to_output (void)
/* We should've reclaimed all functions that are not needed. */
#ifdef ENABLE_CHECKING
if (!node->global.inlined_to
&& gimple_body (decl)
&& gimple_has_body_p (decl)
&& !DECL_EXTERNAL (decl))
{
dump_cgraph_node (stderr, node);
......@@ -1011,7 +1010,7 @@ cgraph_mark_functions_to_output (void)
}
#endif
gcc_assert (node->global.inlined_to
|| !gimple_body (decl)
|| !gimple_has_body_p (decl)
|| DECL_EXTERNAL (decl));
}
......@@ -1039,16 +1038,13 @@ cgraph_expand_function (struct cgraph_node *node)
tree_rest_of_compilation (decl);
/* Make sure that BE didn't give up on compiling. */
/* ??? Can happen with nested function of extern inline. */
gcc_assert (TREE_ASM_WRITTEN (decl));
current_function_decl = NULL;
if (!cgraph_preserve_function_body_p (decl))
{
cgraph_release_function_body (node);
/* Eliminate all call edges. This is important so the call_expr no longer
points to the dead function body. */
cgraph_node_remove_callees (node);
}
gcc_assert (!cgraph_preserve_function_body_p (decl));
cgraph_release_function_body (node);
/* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
points to the dead function body. */
cgraph_node_remove_callees (node);
cgraph_function_flags_ready = true;
}
......@@ -1329,7 +1325,7 @@ cgraph_optimize (void)
for (node = cgraph_nodes; node; node = node->next)
if (node->analyzed
&& (node->global.inlined_to
|| gimple_body (node->decl)))
|| gimple_has_body_p (node->decl)))
{
error_found = true;
dump_cgraph_node (stderr, node);
......
......@@ -1816,6 +1816,14 @@ gimple_body (tree fndecl)
return fn ? fn->gimple_body : NULL;
}
/* Return true when FNDECL has Gimple body either in unlowered
or CFG form. */
bool
gimple_has_body_p (tree fndecl)
{
struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
return (gimple_body (fndecl) || (fn && fn->cfg));
}
/* Detect flags from a GIMPLE_CALL. This is just like
call_expr_flags, but for gimple tuples. */
......
......@@ -822,6 +822,7 @@ enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
void sort_case_labels (VEC(tree,heap) *);
void gimple_set_body (tree, gimple_seq);
gimple_seq gimple_body (tree);
bool gimple_has_body_p (tree);
gimple_seq gimple_seq_alloc (void);
void gimple_seq_free (gimple_seq);
void gimple_seq_add_seq (gimple_seq *, gimple_seq);
......
......@@ -212,7 +212,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
&& !cgraph_new_nodes)
{
gcc_assert (!e->callee->global.inlined_to);
if (gimple_body (e->callee->decl))
if (e->callee->analyzed)
overall_insns -= e->callee->global.insns, nfunctions_inlined++;
duplicate = false;
}
......@@ -1388,7 +1388,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
}
continue;
}
if (!gimple_body (e->callee->decl) && !e->callee->inline_decl)
if (!e->callee->analyzed && !e->callee->inline_decl)
{
if (dump_file)
{
......@@ -1463,7 +1463,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
}
continue;
}
if (!gimple_body (e->callee->decl) && !e->callee->inline_decl)
if (!e->callee->analyzed && !e->callee->inline_decl)
{
if (dump_file)
{
......@@ -1706,7 +1706,7 @@ inline_transform (struct cgraph_node *node)
/* We might need the body of this function so that we can expand
it inline somewhere else. */
if (cgraph_preserve_function_body_p (current_function_decl))
if (cgraph_preserve_function_body_p (node->decl))
save_inline_function_body (node);
for (e = node->callees; e; e = e->next_callee)
......
......@@ -217,7 +217,10 @@ build_gimple_cfg (gimple_seq seq)
static unsigned int
execute_build_cfg (void)
{
build_gimple_cfg (gimple_body (current_function_decl));
gimple_seq body = gimple_body (current_function_decl);
build_gimple_cfg (body);
gimple_set_body (current_function_decl, NULL);
return 0;
}
......@@ -5898,7 +5901,7 @@ dump_function_to_file (tree fn, FILE *file, int flags)
if (dsf && (flags & TDF_DETAILS))
dump_eh_tree (file, dsf);
if (flags & TDF_RAW && !gimple_body (fn))
if (flags & TDF_RAW && !gimple_has_body_p (fn))
{
dump_node (fn, TDF_SLIM | flags, file);
return;
......
......@@ -1692,8 +1692,6 @@ static void
initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count,
int frequency)
{
struct function *new_cfun
= (struct function *) ggc_alloc_cleared (sizeof (struct function));
struct function *src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl);
gcov_type count_scale, frequency_scale;
......@@ -1712,14 +1710,40 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count,
/* Register specific tree functions. */
gimple_register_cfg_hooks ();
*new_cfun = *DECL_STRUCT_FUNCTION (callee_fndecl);
new_cfun->funcdef_no = get_next_funcdef_no ();
VALUE_HISTOGRAMS (new_cfun) = NULL;
new_cfun->local_decls = NULL;
new_cfun->cfg = NULL;
new_cfun->decl = new_fndecl /*= copy_node (callee_fndecl)*/;
DECL_STRUCT_FUNCTION (new_fndecl) = new_cfun;
push_cfun (new_cfun);
/* Get clean struct function. */
push_struct_function (new_fndecl);
/* We will rebuild these, so just sanity check that they are empty. */
gcc_assert (VALUE_HISTOGRAMS (cfun) == NULL);
gcc_assert (cfun->local_decls == NULL);
gcc_assert (cfun->cfg == NULL);
gcc_assert (cfun->decl == new_fndecl);
/* No need to copy; this is initialized later in compilation. */
gcc_assert (!src_cfun->calls_setjmp);
gcc_assert (!src_cfun->calls_alloca);
/* Copy items we preserve during clonning. */
cfun->static_chain_decl = src_cfun->static_chain_decl;
cfun->nonlocal_goto_save_area = src_cfun->nonlocal_goto_save_area;
cfun->function_end_locus = src_cfun->function_end_locus;
cfun->curr_properties = src_cfun->curr_properties;
cfun->last_verified = src_cfun->last_verified;
if (src_cfun->ipa_transforms_to_apply)
cfun->ipa_transforms_to_apply = VEC_copy (ipa_opt_pass, heap,
src_cfun->ipa_transforms_to_apply);
cfun->va_list_gpr_size = src_cfun->va_list_gpr_size;
cfun->va_list_fpr_size = src_cfun->va_list_fpr_size;
cfun->function_frequency = src_cfun->function_frequency;
cfun->has_nonlocal_label = src_cfun->has_nonlocal_label;
cfun->stdarg = src_cfun->stdarg;
cfun->dont_save_pending_sizes_p = src_cfun->dont_save_pending_sizes_p;
cfun->after_inlining = src_cfun->after_inlining;
cfun->returns_struct = src_cfun->returns_struct;
cfun->returns_pcc_struct = src_cfun->returns_pcc_struct;
cfun->after_tree_profile = src_cfun->after_tree_profile;
init_empty_tree_cfg ();
ENTRY_BLOCK_PTR->count =
......@@ -2581,12 +2605,6 @@ inlinable_function_p (tree fn)
inlinable = false;
}
/* If we don't have the function body available, we can't inline it.
However, this should not be recorded since we also get here for
forward declared inline functions. Therefore, return at once. */
if (!gimple_body (fn))
return false;
else if (inline_forbidden_p (fn))
{
/* See if we should warn about uninlinable functions. Previously,
......@@ -3089,7 +3107,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
gimple_body. */
if (!DECL_INITIAL (fn)
&& DECL_ABSTRACT_ORIGIN (fn)
&& gimple_body (DECL_ABSTRACT_ORIGIN (fn)))
&& gimple_has_body_p (DECL_ABSTRACT_ORIGIN (fn)))
fn = DECL_ABSTRACT_ORIGIN (fn);
/* Objective C and fortran still calls tree_rest_of_compilation directly.
......
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