diff options
author | Steven Bosscher <stevenb@suse.de> | 2005-05-17 16:56:32 +0000 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2005-05-17 16:56:32 +0000 |
commit | e21aff8abe2079837b599b4975c81b6dfe969a65 (patch) | |
tree | 7ea47e34b08476d032089225675e12ceab4eed76 /gcc/cgraphunit.c | |
parent | 8f2a14065c60b1ac45c9019de43b73664bc7657d (diff) | |
download | gcc-e21aff8abe2079837b599b4975c81b6dfe969a65.zip gcc-e21aff8abe2079837b599b4975c81b6dfe969a65.tar.gz gcc-e21aff8abe2079837b599b4975c81b6dfe969a65.tar.bz2 |
cgraph.h (cgraph_node): Add 'lowered' state.
* 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.
Co-Authored-By: Dale Johannesen <dalej@apple.com>
Co-Authored-By: Jan Hubicka <jh@suse.cz>
Co-Authored-By: Stuart Hastings <stuart@apple.com>
From-SVN: r99840
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r-- | gcc/cgraphunit.c | 82 |
1 files changed, 77 insertions, 5 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 5f6d873..548a5fcb 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -427,6 +427,7 @@ cgraph_finalize_function (tree decl, bool nested) notice_global_symbol (decl); node->decl = decl; node->local.finalized = true; + node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL; if (node->nested) lower_nested_functions (decl); gcc_assert (!node->nested); @@ -459,6 +460,16 @@ cgraph_finalize_function (tree decl, bool nested) do_warn_unused_parameter (decl); } +void +cgraph_lower_function (struct cgraph_node *node) +{ + if (node->lowered) + return; + tree_lowering_passes (node->decl); + node->lowered = true; +} + + /* Walk tree and record all calls. Called via walk_tree. */ static tree record_call_1 (tree *tp, int *walk_subtrees, void *data) @@ -538,6 +549,43 @@ cgraph_create_edges (struct cgraph_node *node, tree body) /* The nodes we're interested in are never shared, so walk the tree ignoring duplicates. */ visited_nodes = pointer_set_create (); + if (TREE_CODE (body) == FUNCTION_DECL) + { + struct function *this_cfun = DECL_STRUCT_FUNCTION (body); + basic_block this_block; + block_stmt_iterator bsi; + tree step; + + /* Reach the trees by walking over the CFG, and note the + enclosing basic-blocks in the call edges. */ + FOR_EACH_BB_FN (this_block, this_cfun) + for (bsi = bsi_start (this_block); !bsi_end_p (bsi); bsi_next (&bsi)) + walk_tree (bsi_stmt_ptr (bsi), record_call_1, node, visited_nodes); + + /* Walk over any private statics that may take addresses of functions. */ + if (TREE_CODE (DECL_INITIAL (body)) == BLOCK) + { + for (step = BLOCK_VARS (DECL_INITIAL (body)); + step; + step = TREE_CHAIN (step)) + if (DECL_INITIAL (step)) + walk_tree (&DECL_INITIAL (step), record_call_1, node, visited_nodes); + } + + /* Also look here for private statics. */ + if (DECL_STRUCT_FUNCTION (body)) + for (step = DECL_STRUCT_FUNCTION (body)->unexpanded_var_list; + step; + step = TREE_CHAIN (step)) + { + tree decl = TREE_VALUE (step); + if (DECL_INITIAL (decl) && TREE_STATIC (decl)) + walk_tree (&DECL_INITIAL (decl), record_call_1, node, visited_nodes); + } + } + else + walk_tree (&body, record_call_1, node, visited_nodes); + walk_tree (&body, record_call_1, node, visited_nodes); pointer_set_destroy (visited_nodes); visited_nodes = NULL; @@ -596,6 +644,9 @@ verify_cgraph_node (struct cgraph_node *node) { struct cgraph_edge *e; struct cgraph_node *main_clone; + struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl); + basic_block this_block; + block_stmt_iterator bsi; timevar_push (TV_CGRAPH_VERIFY); error_found = false; @@ -655,8 +706,23 @@ verify_cgraph_node (struct cgraph_node *node) && DECL_SAVED_TREE (node->decl) && !TREE_ASM_WRITTEN (node->decl) && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to)) { - walk_tree_without_duplicates (&DECL_SAVED_TREE (node->decl), - verify_cgraph_node_1, node); + if (this_cfun->cfg) + { + /* The nodes we're interested in are never shared, so walk + the tree ignoring duplicates. */ + visited_nodes = pointer_set_create (); + /* Reach the trees by walking over the CFG, and note the + enclosing basic-blocks in the call edges. */ + FOR_EACH_BB_FN (this_block, this_cfun) + for (bsi = bsi_start (this_block); !bsi_end_p (bsi); bsi_next (&bsi)) + walk_tree (bsi_stmt_ptr (bsi), verify_cgraph_node_1, node, visited_nodes); + pointer_set_destroy (visited_nodes); + visited_nodes = NULL; + } + else + /* No CFG available?! */ + gcc_unreachable (); + for (e = node->callees; e; e = e->next_callee) { if (!e->aux) @@ -729,12 +795,14 @@ cgraph_analyze_function (struct cgraph_node *node) struct cgraph_edge *e; current_function_decl = decl; + push_cfun (DECL_STRUCT_FUNCTION (decl)); + cgraph_lower_function (node); /* First kill forward declaration so reverse inlining works properly. */ - cgraph_create_edges (node, DECL_SAVED_TREE (decl)); + cgraph_create_edges (node, decl); node->local.inlinable = tree_inlinable_function_p (decl); - node->local.self_insns = estimate_num_insns (DECL_SAVED_TREE (decl)); + node->local.self_insns = estimate_num_insns (decl); if (node->local.inlinable) node->local.disregard_inline_limits = lang_hooks.tree_inlining.disregard_inline_limits (decl); @@ -754,6 +822,7 @@ cgraph_analyze_function (struct cgraph_node *node) node->global.insns = node->local.self_insns; node->analyzed = true; + pop_cfun (); current_function_decl = NULL; } @@ -1178,7 +1247,10 @@ cgraph_build_static_cdtor (char which, tree body, int priority) /* ??? We will get called LATE in the compilation process. */ if (cgraph_global_info_ready) - tree_rest_of_compilation (decl); + { + tree_lowering_passes (decl); + tree_rest_of_compilation (decl); + } else cgraph_finalize_function (decl, 0); |