diff options
-rw-r--r-- | gcc/ChangeLog | 25 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 6 | ||||
-rw-r--r-- | gcc/cgraph.c | 83 | ||||
-rw-r--r-- | gcc/cgraph.h | 1 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 96 | ||||
-rw-r--r-- | gcc/passes.c | 101 | ||||
-rw-r--r-- | gcc/tree-flow.h | 1 | ||||
-rw-r--r-- | gcc/tree-optimize.c | 146 | ||||
-rw-r--r-- | gcc/tree-ssa.c | 29 |
10 files changed, 252 insertions, 238 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a1dad36b367..dbaf800433f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2012-04-12 Richard Guenther <rguenther@suse.de> + + * Makefile.in (cgraphunit.o): Add $(EXCEPT_H) dependency. + * cgraph.h (tree_rest_of_compilation): Remove. + * cgraph.c (cgraph_add_new_function): Move ... + * cgraphunit.c (cgraph_add_new_function): ... here. + (tree_rest_of_compilation): Make static. + (cgraph_expand_function): Do not set cgraph_function_flags_ready. + * tree-optimize.c (gate_all_optimizations, pass_all_optimizations, + gate_all_early_local_passes, execute_all_early_local_passes, + pass_early_local_passes, gate_all_early_optimizations, + pass_all_early_optimizations): Move ... + * passes.c (gate_all_optimizations, pass_all_optimizations, + gate_all_early_local_passes, execute_all_early_local_passes, + pass_early_local_passes, gate_all_early_optimizations, + pass_all_early_optimizations): ... here. + * tree-optimize.c (execute_free_datastructures): Remove. + * tree-flow.h (execute_free_datastructures): Remove. + * tree-optimize.c (execute_init_datastructures, + pass_init_datastructures): Move ... + * tree-ssa.c (execute_init_datastructures, + pass_init_datastructures): ... here. + * cfgexpand.c (gimple_expand_cfg): Inline-expand call to + execute_free_datastructures. + 2012-04-12 Bernd Schmidt <bernds@codesourcery.com> * dbgcnt.def (ira_move): New counter. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 408182a648a..0f87ea36a69 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2922,7 +2922,7 @@ cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \ gt-cgraphunit.h tree-iterator.h $(COVERAGE_H) $(TREE_DUMP_H) \ tree-pretty-print.h gimple-pretty-print.h ipa-inline.h $(IPA_UTILS_H) \ - $(LTO_STREAMER_H) output.h $(REGSET_H) + $(LTO_STREAMER_H) output.h $(REGSET_H) $(EXCEPT_H) cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \ $(TREE_FLOW_H) $(TREE_PASS_H) $(IPA_UTILS_H) $(EXCEPT_H) \ diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index d148853143b..0c027e298bc 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -4555,7 +4555,11 @@ gimple_expand_cfg (void) if (MAY_HAVE_DEBUG_INSNS) expand_debug_locations (); - execute_free_datastructures (); + /* Free stuff we no longer need after GIMPLE optimizations. */ + free_dominance_info (CDI_DOMINATORS); + free_dominance_info (CDI_POST_DOMINATORS); + delete_tree_cfg_annotations (); + timevar_push (TV_OUT_OF_SSA); finish_out_of_ssa (&SA); timevar_pop (TV_OUT_OF_SSA); diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 61a8e235fe3..9a2c491a28e 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -2397,89 +2397,6 @@ cgraph_function_body_availability (struct cgraph_node *node) return avail; } -/* Add the function FNDECL to the call graph. - Unlike cgraph_finalize_function, this function is intended to be used - by middle end and allows insertion of new function at arbitrary point - of compilation. The function can be either in high, low or SSA form - GIMPLE. - - The function is assumed to be reachable and have address taken (so no - API breaking optimizations are performed on it). - - Main work done by this function is to enqueue the function for later - processing to avoid need the passes to be re-entrant. */ - -void -cgraph_add_new_function (tree fndecl, bool lowered) -{ - struct cgraph_node *node; - switch (cgraph_state) - { - case CGRAPH_STATE_CONSTRUCTION: - /* Just enqueue function to be processed at nearest occurrence. */ - node = cgraph_create_node (fndecl); - node->next_needed = cgraph_new_nodes; - if (lowered) - node->lowered = true; - cgraph_new_nodes = node; - break; - - case CGRAPH_STATE_IPA: - case CGRAPH_STATE_IPA_SSA: - case CGRAPH_STATE_EXPANSION: - /* Bring the function into finalized state and enqueue for later - analyzing and compilation. */ - node = cgraph_get_create_node (fndecl); - node->local.local = false; - node->local.finalized = true; - node->reachable = node->needed = true; - if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION) - { - push_cfun (DECL_STRUCT_FUNCTION (fndecl)); - current_function_decl = fndecl; - gimple_register_cfg_hooks (); - bitmap_obstack_initialize (NULL); - execute_pass_list (all_lowering_passes); - execute_pass_list (pass_early_local_passes.pass.sub); - bitmap_obstack_release (NULL); - pop_cfun (); - current_function_decl = NULL; - - lowered = true; - } - if (lowered) - node->lowered = true; - node->next_needed = cgraph_new_nodes; - cgraph_new_nodes = node; - break; - - case CGRAPH_STATE_FINISHED: - /* At the very end of compilation we have to do all the work up - to expansion. */ - node = cgraph_create_node (fndecl); - if (lowered) - node->lowered = true; - cgraph_analyze_function (node); - push_cfun (DECL_STRUCT_FUNCTION (fndecl)); - current_function_decl = fndecl; - gimple_register_cfg_hooks (); - bitmap_obstack_initialize (NULL); - if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl))) - execute_pass_list (pass_early_local_passes.pass.sub); - bitmap_obstack_release (NULL); - tree_rest_of_compilation (node); - pop_cfun (); - current_function_decl = NULL; - break; - } - - /* Set a personality if required and we already passed EH lowering. */ - if (lowered - && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl)) - == eh_personality_lang)) - DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality (); -} - /* Worker for cgraph_node_can_be_local_p. */ static bool cgraph_node_cannot_be_local_p_1 (struct cgraph_node *node, diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 8740fba7c47..8c0c882ac8b 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -583,7 +583,6 @@ void cgraph_mark_if_needed (tree); void cgraph_analyze_function (struct cgraph_node *); void cgraph_finalize_compilation_unit (void); void cgraph_optimize (void); -void tree_rest_of_compilation (struct cgraph_node *); void cgraph_mark_needed_node (struct cgraph_node *); void cgraph_mark_address_taken_node (struct cgraph_node *); void cgraph_mark_reachable_node (struct cgraph_node *); diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 9d2c46c374e..f603bf500ff 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -142,12 +142,14 @@ along with GCC; see the file COPYING3. If not see #include "ipa-inline.h" #include "ipa-utils.h" #include "lto-streamer.h" +#include "except.h" #include "regset.h" /* FIXME: For reg_obstack. */ 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 tree_rest_of_compilation (struct cgraph_node *); FILE *cgraph_dump_file; @@ -365,6 +367,92 @@ cgraph_finalize_function (tree decl, bool nested) ggc_collect (); } +/* Add the function FNDECL to the call graph. + Unlike cgraph_finalize_function, this function is intended to be used + by middle end and allows insertion of new function at arbitrary point + of compilation. The function can be either in high, low or SSA form + GIMPLE. + + The function is assumed to be reachable and have address taken (so no + API breaking optimizations are performed on it). + + Main work done by this function is to enqueue the function for later + processing to avoid need the passes to be re-entrant. */ + +void +cgraph_add_new_function (tree fndecl, bool lowered) +{ + struct cgraph_node *node; + switch (cgraph_state) + { + case CGRAPH_STATE_CONSTRUCTION: + /* Just enqueue function to be processed at nearest occurrence. */ + node = cgraph_create_node (fndecl); + node->next_needed = cgraph_new_nodes; + if (lowered) + node->lowered = true; + cgraph_new_nodes = node; + break; + + case CGRAPH_STATE_IPA: + case CGRAPH_STATE_IPA_SSA: + case CGRAPH_STATE_EXPANSION: + /* Bring the function into finalized state and enqueue for later + analyzing and compilation. */ + node = cgraph_get_create_node (fndecl); + node->local.local = false; + node->local.finalized = true; + node->reachable = node->needed = true; + if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION) + { + push_cfun (DECL_STRUCT_FUNCTION (fndecl)); + current_function_decl = fndecl; + gimple_register_cfg_hooks (); + bitmap_obstack_initialize (NULL); + execute_pass_list (all_lowering_passes); + execute_pass_list (pass_early_local_passes.pass.sub); + bitmap_obstack_release (NULL); + pop_cfun (); + current_function_decl = NULL; + + lowered = true; + } + if (lowered) + node->lowered = true; + node->next_needed = cgraph_new_nodes; + cgraph_new_nodes = node; + break; + + case CGRAPH_STATE_FINISHED: + /* At the very end of compilation we have to do all the work up + to expansion. */ + node = cgraph_create_node (fndecl); + if (lowered) + node->lowered = true; + cgraph_analyze_function (node); + push_cfun (DECL_STRUCT_FUNCTION (fndecl)); + current_function_decl = fndecl; + gimple_register_cfg_hooks (); + bitmap_obstack_initialize (NULL); + if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl))) + execute_pass_list (pass_early_local_passes.pass.sub); + bitmap_obstack_release (NULL); + tree_rest_of_compilation (node); + pop_cfun (); + current_function_decl = NULL; + break; + + default: + gcc_unreachable (); + } + + /* Set a personality if required and we already passed EH lowering. */ + if (lowered + && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl)) + == eh_personality_lang)) + DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality (); +} + /* C99 extern inline keywords allow changing of declaration after function has been finalized. We need to re-decide if we want to mark the function as needed then. */ @@ -1770,10 +1858,10 @@ assemble_thunks_and_aliases (struct cgraph_node *node) } } -/* For functions-as-trees languages, this performs all optimization and - compilation for FNDECL. */ +/* Perform IPA transforms and all further optimizations and compilation + for FNDECL. */ -void +static void tree_rest_of_compilation (struct cgraph_node *node) { tree fndecl = node->decl; @@ -1891,8 +1979,6 @@ cgraph_expand_function (struct cgraph_node *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; } /* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */ diff --git a/gcc/passes.c b/gcc/passes.c index 0cb97a50153..ad930704299 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -281,6 +281,107 @@ finish_optimization_passes (void) timevar_pop (TV_DUMP); } +static unsigned int +execute_all_early_local_passes (void) +{ + /* Once this pass (and its sub-passes) are complete, all functions + will be in SSA form. Technically this state change is happening + a tad early, since the sub-passes have not yet run, but since + none of the sub-passes are IPA passes and do not create new + functions, this is ok. We're setting this value for the benefit + of IPA passes that follow. */ + if (cgraph_state < CGRAPH_STATE_IPA_SSA) + cgraph_state = CGRAPH_STATE_IPA_SSA; + return 0; +} + +/* Gate: execute, or not, all of the non-trivial optimizations. */ + +static bool +gate_all_early_local_passes (void) +{ + /* Don't bother doing anything if the program has errors. */ + return (!seen_error () && !in_lto_p); +} + +struct simple_ipa_opt_pass pass_early_local_passes = +{ + { + SIMPLE_IPA_PASS, + "early_local_cleanups", /* name */ + gate_all_early_local_passes, /* gate */ + execute_all_early_local_passes, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_EARLY_LOCAL, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_remove_functions /* todo_flags_finish */ + } +}; + +/* Gate: execute, or not, all of the non-trivial optimizations. */ + +static bool +gate_all_early_optimizations (void) +{ + return (optimize >= 1 + /* Don't bother doing anything if the program has errors. */ + && !seen_error ()); +} + +struct gimple_opt_pass pass_all_early_optimizations = +{ + { + GIMPLE_PASS, + "early_optimizations", /* name */ + gate_all_early_optimizations, /* gate */ + NULL, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_NONE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0 /* todo_flags_finish */ + } +}; + +/* Gate: execute, or not, all of the non-trivial optimizations. */ + +static bool +gate_all_optimizations (void) +{ + return (optimize >= 1 + /* Don't bother doing anything if the program has errors. + We have to pass down the queue if we already went into SSA */ + && (!seen_error () || gimple_in_ssa_p (cfun))); +} + +struct gimple_opt_pass pass_all_optimizations = +{ + { + GIMPLE_PASS, + "*all_optimizations", /* name */ + gate_all_optimizations, /* gate */ + NULL, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_OPTIMIZE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0 /* todo_flags_finish */ + } +}; + static bool gate_rest_of_compilation (void) { diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 3dd6a7d019d..ba3adb0e059 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -853,7 +853,6 @@ rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool); void get_address_description (tree, struct mem_address *); tree maybe_fold_tmr (tree); -unsigned int execute_free_datastructures (void); unsigned int execute_fixup_cfg (void); bool fixup_noreturn_call (gimple stmt); diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index 7cd3ef35c97..d69a504d7de 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -46,107 +46,6 @@ along with GCC; see the file COPYING3. If not see #include "except.h" #include "plugin.h" -/* Gate: execute, or not, all of the non-trivial optimizations. */ - -static bool -gate_all_optimizations (void) -{ - return (optimize >= 1 - /* Don't bother doing anything if the program has errors. - We have to pass down the queue if we already went into SSA */ - && (!seen_error () || gimple_in_ssa_p (cfun))); -} - -struct gimple_opt_pass pass_all_optimizations = -{ - { - GIMPLE_PASS, - "*all_optimizations", /* name */ - gate_all_optimizations, /* gate */ - NULL, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_OPTIMIZE, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ - } -}; - -/* Gate: execute, or not, all of the non-trivial optimizations. */ - -static bool -gate_all_early_local_passes (void) -{ - /* Don't bother doing anything if the program has errors. */ - return (!seen_error () && !in_lto_p); -} - -static unsigned int -execute_all_early_local_passes (void) -{ - /* Once this pass (and its sub-passes) are complete, all functions - will be in SSA form. Technically this state change is happening - a tad early, since the sub-passes have not yet run, but since - none of the sub-passes are IPA passes and do not create new - functions, this is ok. We're setting this value for the benefit - of IPA passes that follow. */ - if (cgraph_state < CGRAPH_STATE_IPA_SSA) - cgraph_state = CGRAPH_STATE_IPA_SSA; - return 0; -} - -struct simple_ipa_opt_pass pass_early_local_passes = -{ - { - SIMPLE_IPA_PASS, - "early_local_cleanups", /* name */ - gate_all_early_local_passes, /* gate */ - execute_all_early_local_passes, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_EARLY_LOCAL, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_remove_functions /* todo_flags_finish */ - } -}; - -/* Gate: execute, or not, all of the non-trivial optimizations. */ - -static bool -gate_all_early_optimizations (void) -{ - return (optimize >= 1 - /* Don't bother doing anything if the program has errors. */ - && !seen_error ()); -} - -struct gimple_opt_pass pass_all_early_optimizations = -{ - { - GIMPLE_PASS, - "early_optimizations", /* name */ - gate_all_early_optimizations, /* gate */ - NULL, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_NONE, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ - } -}; - /* Pass: cleanup the CFG just before expanding trees to RTL. This is just a round of label cleanups and case node grouping @@ -213,21 +112,6 @@ struct gimple_opt_pass pass_cleanup_cfg_post_optimizing = } }; -/* Pass: do the actions required to finish with tree-ssa optimization - passes. */ - -unsigned int -execute_free_datastructures (void) -{ - free_dominance_info (CDI_DOMINATORS); - free_dominance_info (CDI_POST_DOMINATORS); - - /* And get rid of annotations we no longer need. */ - delete_tree_cfg_annotations (); - - return 0; -} - /* IPA passes, compilation of earlier functions or inlining might have changed some properties, such as marked functions nothrow, pure, const or noreturn. @@ -335,33 +219,3 @@ struct gimple_opt_pass pass_fixup_cfg = 0 /* todo_flags_finish */ } }; - -/* Do the actions required to initialize internal data structures used - in tree-ssa optimization passes. */ - -static unsigned int -execute_init_datastructures (void) -{ - /* Allocate hash tables, arrays and other structures. */ - init_tree_ssa (cfun); - return 0; -} - -struct gimple_opt_pass pass_init_datastructures = -{ - { - GIMPLE_PASS, - "*init_datastructures", /* name */ - NULL, /* gate */ - execute_init_datastructures, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_NONE, /* tv_id */ - PROP_cfg, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ - } -}; diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 08f908f6a6c..f399833c546 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1120,6 +1120,35 @@ init_tree_ssa (struct function *fn) init_phinodes (); } +/* Do the actions required to initialize internal data structures used + in tree-ssa optimization passes. */ + +static unsigned int +execute_init_datastructures (void) +{ + /* Allocate hash tables, arrays and other structures. */ + init_tree_ssa (cfun); + return 0; +} + +struct gimple_opt_pass pass_init_datastructures = +{ + { + GIMPLE_PASS, + "*init_datastructures", /* name */ + NULL, /* gate */ + execute_init_datastructures, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_NONE, /* tv_id */ + PROP_cfg, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0 /* todo_flags_finish */ + } +}; /* Deallocate memory associated with SSA data structures for FNDECL. */ |