diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-05-17 16:56:32 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-05-17 16:56:32 +0000 |
commit | e27482aa54700157a58b7b2f73afdd6c1709c98e (patch) | |
tree | 7ea47e34b08476d032089225675e12ceab4eed76 /gcc/tree-optimize.c | |
parent | a0007dfa0c2dcf8d6fd784c9e8a7c2690447cbed (diff) | |
download | gcc-e27482aa54700157a58b7b2f73afdd6c1709c98e.tar.gz |
* cgraph.h (cgraph_node): Add 'lowered' state.
(cgraph_lower_function): Declare.
* cgraphunit.c (cgraph_finalize_function): Initialize lowered flag.
(cgraph_lower_function): New function.
(cgraph_create_edges): Deal with lowered function bodies.
(verify_cgraph_node): Likewise.
(cgraph_analyze_function): Do lowering job.
(cgraph_build_static_cdtor): Likewise.
* function.h (struct function): Add saved_eh and saved_cfg.
* integrate.c (copy_decl_for_inlining): Kill LABEL_DECL_UID field.
* tree-cfg.c (fold_cond_expr_cond): Export.
* tree-flow.h (fold_cond_expr_cond): Declare.
* tree-inline.c: Include basic-block, ggc, tree-flow, except.h and
pointer-set.
(struct_inline_data): Kill fnd, first_inlined_fn, ret_label,
in_target_cleanup_p, tree_pruner, tsi; add callee, caller and
callee_cfun, block, eh_region, eh_region_offset.
(inlining_p): New predicate.
(remap_decl): Update for new inline_data; declare newly created inline
vars in low gimple way.
(copy_body_r): Update for new datastructure, simplify some of handling
when we are in gimple; remap LABEL_DECLs for EH; copy TREE_BLOCK;
deal with RESX_EXPRs.
(copy_bb): New.
(copy_edges_for_bb): Likewise.
(remap_decl_1): New.
(copy_cfg_body): New.
(copy_generic_body): Rewrite to work on low gimple.
(copy_body): Turn into simple wrapper around copy_cfg_body.
(setup_one_parameter): Insert new statements into given basic block.
(initialize_initialized_parameters): Likewise, reorganize way things are
gimplified.
(declare_return_variable): Update for new inline data datastructure.
(inline_forbidden_p): Work on low gimple.
(estimate_num_insns): Likewise.
(expand_call_inline): Work on CFG.
(push_cfun, pop_cfun): New functions.
(cfun_stack): New stack.
(add_lexical_block): New function.
(gimple_expand_calls_inline): Work on basic block.
(optimize_inline_calls): Likewise.
(clone_body, save_body, unsave_ewpr_now): Update for new
datastructures.
(declare_inline_vars): Work on block instead of bind_expr.
(inlining_p): New predicate.
* tree-inline.h (push_cfun, pop_cfun): Declare.
* tree-optimize.c: Include except.h
(all_lowering_passes): New variable.
(execute_fixup_cfg, pass_fixup_cfg): New pass.
(init_tree_optimization_passes): Move some to all_lowering_passes.
(tree_lowering_passes): New function.
(tree_rest_of_compilation): Register cfg hooks; save/unsave eh.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@99840 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-optimize.c')
-rw-r--r-- | gcc/tree-optimize.c | 96 |
1 files changed, 86 insertions, 10 deletions
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index ec873fbb250..329c06e3182 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA. */ #include "cgraph.h" #include "graph.h" #include "cfgloop.h" +#include "except.h" /* Global variables used to communicate with passes. */ @@ -55,7 +56,7 @@ int dump_flags; bool in_gimple_form; /* The root of the compilation pass tree, once constructed. */ -static struct tree_opt_pass *all_passes, *all_ipa_passes; +static struct tree_opt_pass *all_passes, *all_ipa_passes, * all_lowering_passes; /* Gate: execute, or not, all of the non-trivial optimizations. */ @@ -158,6 +159,51 @@ static struct tree_opt_pass pass_free_datastructures = 0 /* letter */ }; +/* Pass: fixup_cfg - IPA passes or compilation of earlier functions might've + changed some properties - such as marged functions nothrow. Remove now + redundant edges and basic blocks. */ + +static void +execute_fixup_cfg (void) +{ + basic_block bb; + block_stmt_iterator bsi; + + if (cfun->eh) + FOR_EACH_BB (bb) + { + for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + { + tree stmt = bsi_stmt (bsi); + tree call = get_call_expr_in (stmt); + + if (call && call_expr_flags (call) & (ECF_CONST | ECF_PURE)) + TREE_SIDE_EFFECTS (call) = 0; + if (!tree_could_throw_p (stmt) && lookup_stmt_eh_region (stmt)) + remove_stmt_from_eh_region (stmt); + } + tree_purge_dead_eh_edges (bb); + } + + cleanup_tree_cfg (); +} + +static struct tree_opt_pass pass_fixup_cfg = +{ + NULL, /* name */ + NULL, /* gate */ + execute_fixup_cfg, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + PROP_cfg, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; /* Do the actions required to initialize internal data structures used in tree-ssa optimization passes. */ @@ -320,14 +366,21 @@ init_tree_optimization_passes (void) NEXT_PASS (pass_ipa_inline); *p = NULL; - p = &all_passes; + /* All passes needed to lower the function into shape optimizers can operate + on. These passes are performed before interprocedural passes, unlike rest + of local passes (all_passes). */ + p = &all_lowering_passes; NEXT_PASS (pass_remove_useless_stmts); NEXT_PASS (pass_mudflap_1); - NEXT_PASS (pass_lower_cf); - NEXT_PASS (pass_lower_eh); - NEXT_PASS (pass_build_cfg); + NEXT_PASS (pass_lower_cf); + NEXT_PASS (pass_lower_eh); + NEXT_PASS (pass_build_cfg); NEXT_PASS (pass_pre_expand); NEXT_PASS (pass_warn_function_return); + *p = NULL; + + p = &all_passes; + NEXT_PASS (pass_fixup_cfg); NEXT_PASS (pass_tree_profile); NEXT_PASS (pass_init_datastructures); NEXT_PASS (pass_all_optimizations); @@ -432,6 +485,7 @@ init_tree_optimization_passes (void) #undef NEXT_PASS + register_dump_files (all_lowering_passes, false, 0); register_dump_files (all_passes, false, PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh @@ -606,6 +660,23 @@ execute_pass_list (struct tree_opt_pass *pass) while (pass); } +void +tree_lowering_passes (tree fn) +{ + tree saved_current_function_decl = current_function_decl; + + current_function_decl = fn; + push_cfun (DECL_STRUCT_FUNCTION (fn)); + tree_register_cfg_hooks (); + bitmap_obstack_initialize (NULL); + execute_pass_list (all_lowering_passes); + free_dominance_info (CDI_POST_DOMINATORS); + compact_blocks (); + current_function_decl = saved_current_function_decl; + bitmap_obstack_release (NULL); + pop_cfun (); +} + /* Execute all IPA passes. */ void ipa_passes (void) @@ -675,8 +746,7 @@ tree_rest_of_compilation (tree fndecl) cgraph_clone_inlined_nodes (e, true); } cfun->saved_static_chain_decl = cfun->static_chain_decl; - cfun->saved_tree = save_body (fndecl, &cfun->saved_args, - &cfun->saved_static_chain_decl); + save_body (fndecl, &cfun->saved_args, &cfun->saved_static_chain_decl); } if (flag_inline_trees) @@ -712,6 +782,7 @@ tree_rest_of_compilation (tree fndecl) bitmap_obstack_initialize (NULL); bitmap_obstack_initialize (®_obstack); /* FIXME, only at RTL generation*/ + tree_register_cfg_hooks (); /* Perform all tree transforms and optimizations. */ execute_pass_list (all_passes); @@ -721,12 +792,16 @@ tree_rest_of_compilation (tree fndecl) bitmap_obstack_release (NULL); /* Restore original body if still needed. */ - if (cfun->saved_tree) + if (cfun->saved_cfg) { - DECL_SAVED_TREE (fndecl) = cfun->saved_tree; DECL_ARGUMENTS (fndecl) = cfun->saved_args; + cfun->cfg = cfun->saved_cfg; + cfun->eh = cfun->saved_eh; + cfun->saved_cfg = NULL; + cfun->saved_eh = NULL; + cfun->saved_args = NULL_TREE; cfun->static_chain_decl = cfun->saved_static_chain_decl; - + cfun->saved_static_chain_decl = NULL; /* When not in unit-at-a-time mode, we must preserve out of line copy representing node before inlining. Restore original outgoing edges using clone we created earlier. */ @@ -734,6 +809,7 @@ tree_rest_of_compilation (tree fndecl) { struct cgraph_edge *e; + node = cgraph_node (current_function_decl); cgraph_node_remove_callees (node); node->callees = saved_node->callees; saved_node->callees = NULL; |