diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e15b77ceced..8879773e93c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,35 @@ +2007-01-02 Jan Hubicka + + * cgraph.c: Include tree-flow.h + (cgraph_add_new-function): Handle IPA_SSA mode; execute + early_local_passes. + * cgraph.h (enum cgraph_state): Add CGRAPH_STATE_IPA_SSA. + * tree-pass.h (pass_all_early_optimizations): Declare. + * cgraphunit.c (cgraph_process_new_functions): Add IPA_SSA; execute + early_local_passes. + (cgraph_analyze_function): Do early_local_passes. + * tree-mudflap.c (mf_decl_cache_locals, mf_build_check_statement_for): + Do not add referenced vars. + * tree-optimize.c (gate_all_optimizations): Do not execute when not in + SSA form. + (gate_all_early_local_passes): New gate. + (pass_early_local_passes): Use new gate. + (execute_early_local_optimizations): New functions. + (gate_all_early_optimizations): New gate. + (pass_all_early_optimizations): New pass. + (execute_free_datastructures): Free SSA only when initialized. + (gate_init_datastructures): Init only when optimizing. + (tree_lowering_passes): Do early local passes when called late. + * tree-profile.c (do_tree_profiling): Don't profile functions added + late. + (do_early_tree_profiling, pass_early_tree_profile): Kill. + * tree-cfg.c (update_modified_stmts): Do not update when operands are + not active. + * passes.c (init_optimizations_passes): Reorder so we go into SSA + during early_local_passes. + * Makefile.in (cgraph.o): Add dependency on tree-flow.h. + + 2007-01-02 Carlos O'Donell * Makefile.in: Update copyright year. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 35a3b58dcdb..f14088b86cf 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2293,7 +2293,7 @@ simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ langhooks.h toplev.h $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \ gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \ - $(TREE_INLINE_H) $(VARRAY_H) $(TREE_DUMP_H) + $(TREE_INLINE_H) $(VARRAY_H) $(TREE_DUMP_H) $(TREE_FLOW_H) cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(FLAGS_H) $(GGC_H) \ $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(TREE_GIMPLE_H) \ diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 21e821c2b4d..1baed252439 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -83,6 +83,7 @@ The callgraph: #include "intl.h" #include "tree-gimple.h" #include "tree-dump.h" +#include "tree-flow.h" static void cgraph_node_remove_callers (struct cgraph_node *node); static inline void cgraph_edge_remove_caller (struct cgraph_edge *e); @@ -942,6 +943,7 @@ cgraph_add_new_function (tree fndecl, bool lowered) 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. */ @@ -963,6 +965,10 @@ cgraph_add_new_function (tree fndecl, bool lowered) tree_register_cfg_hooks (); if (!lowered) tree_lowering_passes (fndecl); + bitmap_obstack_initialize (NULL); + if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)) && optimize) + execute_pass_list (pass_early_local_passes.sub); + bitmap_obstack_release (NULL); tree_rest_of_compilation (fndecl); pop_cfun (); current_function_decl = NULL; diff --git a/gcc/cgraph.h b/gcc/cgraph.h index e363819f166..6f2d3be9a90 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -260,6 +260,8 @@ enum cgraph_state CGRAPH_STATE_CONSTRUCTION, /* Callgraph is built and IPA passes are being run. */ CGRAPH_STATE_IPA, + /* Callgraph is built and all functions are transformed to SSA form. */ + CGRAPH_STATE_IPA_SSA, /* Functions are now ordered and being passed to RTL expanders. */ CGRAPH_STATE_EXPANSION, /* All cgraph expansion is done. */ diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index d5b7e6d17d1..22727203186 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -294,6 +294,7 @@ cgraph_process_new_functions (void) break; case CGRAPH_STATE_IPA: + case CGRAPH_STATE_IPA_SSA: /* When IPA optimization already started, do all essential transformations that has been already performed on the whole cgraph but not on this function. */ @@ -313,6 +314,12 @@ cgraph_process_new_functions (void) initialize_inline_failed (node); if (flag_really_no_inline && !node->local.disregard_inline_limits) node->local.inlinable = 0; + if ((cgraph_state == CGRAPH_STATE_IPA_SSA + && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl))) + /* When not optimizing, be sure we run early local passes anyway + to expand OMP. */ + || !optimize) + execute_pass_list (pass_early_local_passes.sub); free_dominance_info (CDI_POST_DOMINATORS); free_dominance_info (CDI_DOMINATORS); pop_cfun (); @@ -877,6 +884,15 @@ cgraph_analyze_function (struct cgraph_node *node) node->local.inlinable = 0; /* Inlining characteristics are maintained by the cgraph_mark_inline. */ node->global.insns = node->local.self_insns; + if (!flag_unit_at_a_time) + { + bitmap_obstack_initialize (NULL); + tree_register_cfg_hooks (); + execute_pass_list (pass_early_local_passes.sub); + free_dominance_info (CDI_POST_DOMINATORS); + free_dominance_info (CDI_DOMINATORS); + bitmap_obstack_release (NULL); + } node->analyzed = true; pop_cfun (); diff --git a/gcc/passes.c b/gcc/passes.c index ebf558639d6..d40f84e2688 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -461,19 +461,28 @@ init_optimization_passes (void) NEXT_PASS (pass_lower_complex_O0); NEXT_PASS (pass_lower_vector); NEXT_PASS (pass_warn_function_return); - NEXT_PASS (pass_early_tree_profile); *p = NULL; p = &pass_early_local_passes.sub; NEXT_PASS (pass_tree_profile); NEXT_PASS (pass_cleanup_cfg); + NEXT_PASS (pass_init_datastructures); + NEXT_PASS (pass_expand_omp); + NEXT_PASS (pass_all_early_optimizations); NEXT_PASS (pass_rebuild_cgraph_edges); *p = NULL; + p = &pass_all_early_optimizations.sub; + NEXT_PASS (pass_referenced_vars); + NEXT_PASS (pass_reset_cc_flags); + NEXT_PASS (pass_build_ssa); + NEXT_PASS (pass_early_warn_uninitialized); + NEXT_PASS (pass_cleanup_cfg); + + *p = NULL; + p = &all_passes; NEXT_PASS (pass_fixup_cfg); - NEXT_PASS (pass_init_datastructures); - NEXT_PASS (pass_expand_omp); NEXT_PASS (pass_all_optimizations); NEXT_PASS (pass_warn_function_noreturn); NEXT_PASS (pass_free_datastructures); @@ -485,10 +494,7 @@ init_optimization_passes (void) *p = NULL; p = &pass_all_optimizations.sub; - NEXT_PASS (pass_referenced_vars); - NEXT_PASS (pass_reset_cc_flags); NEXT_PASS (pass_create_structure_vars); - NEXT_PASS (pass_build_ssa); NEXT_PASS (pass_may_alias); NEXT_PASS (pass_return_slot); NEXT_PASS (pass_rename_ssa_copies); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9b38348651d..135b506d332 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-01-02 Jan Hubicka + + * gcc.dg/pr16194.c: We now output error on all three functions, not just + first one. + 2007-01-02 Manuel Lopez-Ibanez PR c/19977 diff --git a/gcc/testsuite/gcc.dg/pr16194.c b/gcc/testsuite/gcc.dg/pr16194.c index 44f34a41008..313f0eaa30d 100644 --- a/gcc/testsuite/gcc.dg/pr16194.c +++ b/gcc/testsuite/gcc.dg/pr16194.c @@ -56,12 +56,12 @@ void bug (void) void bug2 (void) { register char* dst ASMDECL; - __asm__ ("": :"g"(*dst) CLOBBER_LIST); + __asm__ ("": :"g"(*dst) CLOBBER_LIST); /* { dg-error "conflict" } */ } void foo (void) { register struct C *dst ASMDECL; - __asm__ ("" : "=g"(dst->c.b[1].a) INP_CLOBBER_LIST); + __asm__ ("" : "=g"(dst->c.b[1].a) INP_CLOBBER_LIST); /* { dg-error "conflict" } */ } diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index 463349293e4..5be07cb07c5 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -57,8 +57,9 @@ static bool gate_all_optimizations (void) { return (optimize >= 1 - /* Don't bother doing anything if the program has errors. */ - && !(errorcount || sorrycount)); + /* Don't bother doing anything if the program has errors. + We have to pass down the queue if we already went into SSA */ + && (!(errorcount || sorrycount) || gimple_in_ssa_p (cfun))); } struct tree_opt_pass pass_all_optimizations = @@ -78,10 +79,19 @@ struct tree_opt_pass pass_all_optimizations = 0 /* letter */ }; +/* 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 (!errorcount && !sorrycount); +} + struct tree_opt_pass pass_early_local_passes = { - NULL, /* name */ - gate_all_optimizations, /* gate */ + "early_local_cleanups", /* name */ + gate_all_early_local_passes, /* gate */ NULL, /* execute */ NULL, /* sub */ NULL, /* next */ @@ -95,6 +105,41 @@ struct tree_opt_pass pass_early_local_passes = 0 /* letter */ }; +static unsigned int +execute_early_local_optimizations (void) +{ + if (flag_unit_at_a_time) + cgraph_state = CGRAPH_STATE_IPA_SSA; + return 0; +} + +/* 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. */ + && !(errorcount || sorrycount)); +} + +struct tree_opt_pass pass_all_early_optimizations = +{ + "early_optimizations", /* name */ + gate_all_early_optimizations, /* gate */ + execute_early_local_optimizations, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + /* Pass: cleanup the CFG just before expanding trees to RTL. This is just a round of label cleanups and case node grouping because after the tree optimizers have run such cleanups may @@ -170,7 +215,8 @@ execute_free_datastructures (void) /* Remove the ssa structures. Do it here since this includes statement annotations that need to be intact during disband_implicit_edges. */ - delete_tree_ssa (); + if (cfun->gimple_df) + delete_tree_ssa (); return 0; } @@ -376,10 +422,18 @@ execute_init_datastructures (void) return 0; } +/* Gate: initialize or not the SSA datastructures. */ + +static bool +gate_init_datastructures (void) +{ + return (optimize >= 1); +} + struct tree_opt_pass pass_init_datastructures = { NULL, /* name */ - NULL, /* gate */ + gate_init_datastructures, /* gate */ execute_init_datastructures, /* execute */ NULL, /* sub */ NULL, /* next */ @@ -403,7 +457,10 @@ tree_lowering_passes (tree fn) tree_register_cfg_hooks (); bitmap_obstack_initialize (NULL); execute_pass_list (all_lowering_passes); + if (optimize && cgraph_global_info_ready) + execute_pass_list (pass_early_local_passes.sub); free_dominance_info (CDI_POST_DOMINATORS); + free_dominance_info (CDI_DOMINATORS); compact_blocks (); current_function_decl = saved_current_function_decl; bitmap_obstack_release (NULL); diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 649ecef4e97..01a0c7dfcff 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -314,6 +314,7 @@ extern struct tree_opt_pass pass_ipa_pure_const; extern struct tree_opt_pass pass_ipa_type_escape; extern struct tree_opt_pass pass_ipa_pta; extern struct tree_opt_pass pass_early_local_passes; +extern struct tree_opt_pass pass_all_early_optimizations; extern struct tree_opt_pass pass_all_optimizations; extern struct tree_opt_pass pass_cleanup_cfg_post_optimizing; diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index 329ebcd4b6e..3ff39f34aec 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -237,6 +237,10 @@ do_tree_profiling (void) static unsigned int tree_profiling (void) { + /* Don't profile functions produced at destruction time, particularly + the gcov datastructure initializer. */ + if (cgraph_state == CGRAPH_STATE_FINISHED) + return 0; branch_prob (); if (flag_branch_probabilities && flag_profile_values @@ -267,33 +271,6 @@ struct tree_opt_pass pass_tree_profile = 0 /* letter */ }; -/* Return 1 if tree-based profiling is in effect, else 0. - If it is, set up hooks for tree-based profiling. - Gate for pass_tree_profile. */ - -static bool -do_early_tree_profiling (void) -{ - return (do_tree_profiling () && (!flag_unit_at_a_time || !optimize)); -} - -struct tree_opt_pass pass_early_tree_profile = -{ - "early_tree_profile", /* name */ - do_early_tree_profiling, /* gate */ - tree_profiling, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_BRANCH_PROB, /* tv_id */ - PROP_gimple_leh | PROP_cfg, /* properties_required */ - PROP_gimple_leh | PROP_cfg, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_verify_stmts, /* todo_flags_finish */ - 0 /* letter */ -}; - struct profile_hooks tree_profile_hooks = { tree_init_edge_profiler, /* init_edge_profiler */