From: hubicka Date: Wed, 3 Sep 2008 18:16:26 +0000 (+0000) Subject: PR tree-optimization/37315 X-Git-Tag: upstream/4.9.2~39908 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1a1a827af5bd68fe66dfb0c7395e7f9feed273bd;p=platform%2Fupstream%2Flinaro-gcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@139945 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0b1b999..b3bad2f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2008-09-03 Jan Hubicka + + 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 PR c++/37346 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 54d5fad..a12ed15 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -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"); diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 43cdfda..d011041 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -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); diff --git a/gcc/gimple.c b/gcc/gimple.c index 6e203b7..7419d85 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -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. */ diff --git a/gcc/gimple.h b/gcc/gimple.h index f8af057..03b6217 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -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); diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 4c8096a..66b9bac 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -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) diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 6bd8a06..ce0649d 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -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; diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 3b77c0e..8b603f0 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -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.