aboutsummaryrefslogtreecommitdiff
path: root/gcc/cgraphunit.c
diff options
context:
space:
mode:
authorSteven Bosscher <stevenb@suse.de>2005-05-17 16:56:32 +0000
committerJan Hubicka <hubicka@gcc.gnu.org>2005-05-17 16:56:32 +0000
commite21aff8abe2079837b599b4975c81b6dfe969a65 (patch)
tree7ea47e34b08476d032089225675e12ceab4eed76 /gcc/cgraphunit.c
parent8f2a14065c60b1ac45c9019de43b73664bc7657d (diff)
downloadgcc-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.c82
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);