diff options
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r-- | gcc/cgraphunit.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 0a3cc6c..d329dc1 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -132,6 +132,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple.h" #include "tree-iterator.h" #include "tree-pass.h" +#include "tree-dump.h" #include "output.h" #include "coverage.h" @@ -139,6 +140,8 @@ static void cgraph_expand_all_functions (void); static void cgraph_mark_functions_to_output (void); static void cgraph_expand_function (struct cgraph_node *); static void cgraph_output_pending_asms (void); +static void cgraph_optimize (void); +static void cgraph_analyze_function (struct cgraph_node *); static FILE *cgraph_dump_file; @@ -490,6 +493,11 @@ cgraph_lower_function (struct cgraph_node *node) { if (node->lowered) return; + + if (node->nested) + lower_nested_functions (node->decl); + gcc_assert (!node->nested); + tree_lowering_passes (node->decl); node->lowered = true; } @@ -513,9 +521,6 @@ cgraph_finalize_function (tree decl, bool nested) node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL; node->finalized_by_frontend = true; record_cdtor_fn (node->decl); - if (node->nested) - lower_nested_functions (decl); - gcc_assert (!node->nested); if (decide_is_function_needed (node, decl)) cgraph_mark_needed_node (node); @@ -789,18 +794,28 @@ cgraph_output_pending_asms (void) } /* Analyze the function scheduled to be output. */ -void +static void cgraph_analyze_function (struct cgraph_node *node) { + tree save = current_function_decl; tree decl = node->decl; current_function_decl = decl; push_cfun (DECL_STRUCT_FUNCTION (decl)); + + /* Make sure to gimplify bodies only once. During analyzing a + function we lower it, which will require gimplified nested + functions, so we can end up here with an already gimplified + body. */ + if (!gimple_body (decl)) + gimplify_function_tree (decl); + dump_function (TDI_generic, decl); + cgraph_lower_function (node); node->analyzed = true; pop_cfun (); - current_function_decl = NULL; + current_function_decl = save; } /* Look for externally_visible and used attributes and mark cgraph nodes @@ -935,8 +950,6 @@ cgraph_analyze_functions (void) } gcc_assert (!node->analyzed && node->reachable); - gcc_assert (gimple_body (decl)); - cgraph_analyze_function (node); for (edge = node->callees; edge; edge = edge->next_callee) @@ -1010,8 +1023,8 @@ cgraph_analyze_functions (void) void cgraph_finalize_compilation_unit (void) { - if (errorcount || sorrycount) - return; + /* Do not skip analyzing the functions if there were errors, we + miss diagnostics for following functions otherwise. */ finalize_size_functions (); finish_aliases_1 (); @@ -1025,6 +1038,8 @@ cgraph_finalize_compilation_unit (void) timevar_push (TV_CGRAPH); cgraph_analyze_functions (); timevar_pop (TV_CGRAPH); + + cgraph_optimize (); } @@ -1311,7 +1326,7 @@ ipa_passes (void) /* Perform simple optimizations based on callgraph. */ -void +static void cgraph_optimize (void) { if (errorcount || sorrycount) |