Commit e21aff8a by Steven Bosscher Committed by Jan Hubicka

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
parent 8f2a1406
2005-05-17 Steven Bosscher <stevenb@suse.de>
Stuart Hastings <stuart@apple.com>
Jan Hubicka <jh@suse.cz>
Dale Johannesen <dalej@apple.com>
* 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.
2005-05-17 Nathan Sidwell <nathan@codesourcery.com> 2005-05-17 Nathan Sidwell <nathan@codesourcery.com>
* unwind-dw2-fde-darwin.c: Include tsystem.h. * unwind-dw2-fde-darwin.c: Include tsystem.h.
......
...@@ -117,6 +117,8 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) ...@@ -117,6 +117,8 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
/* Set when function is reachable by call from other function /* Set when function is reachable by call from other function
that is either reachable or needed. */ that is either reachable or needed. */
bool reachable; bool reachable;
/* Set once the function is lowered (ie it's CFG is built). */
bool lowered;
/* Set once the function has been instantiated and its callee /* Set once the function has been instantiated and its callee
lists created. */ lists created. */
bool analyzed; bool analyzed;
...@@ -215,6 +217,7 @@ bool decide_is_variable_needed (struct cgraph_varpool_node *, tree); ...@@ -215,6 +217,7 @@ bool decide_is_variable_needed (struct cgraph_varpool_node *, tree);
bool cgraph_assemble_pending_functions (void); bool cgraph_assemble_pending_functions (void);
bool cgraph_varpool_assemble_pending_decls (void); bool cgraph_varpool_assemble_pending_decls (void);
void cgraph_finalize_function (tree, bool); void cgraph_finalize_function (tree, bool);
void cgraph_lower_function (struct cgraph_node *);
void cgraph_finalize_compilation_unit (void); void cgraph_finalize_compilation_unit (void);
void cgraph_create_edges (struct cgraph_node *, tree); void cgraph_create_edges (struct cgraph_node *, tree);
void cgraph_optimize (void); void cgraph_optimize (void);
......
...@@ -427,6 +427,7 @@ cgraph_finalize_function (tree decl, bool nested) ...@@ -427,6 +427,7 @@ cgraph_finalize_function (tree decl, bool nested)
notice_global_symbol (decl); notice_global_symbol (decl);
node->decl = decl; node->decl = decl;
node->local.finalized = true; node->local.finalized = true;
node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
if (node->nested) if (node->nested)
lower_nested_functions (decl); lower_nested_functions (decl);
gcc_assert (!node->nested); gcc_assert (!node->nested);
...@@ -459,6 +460,16 @@ cgraph_finalize_function (tree decl, bool nested) ...@@ -459,6 +460,16 @@ cgraph_finalize_function (tree decl, bool nested)
do_warn_unused_parameter (decl); 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. */ /* Walk tree and record all calls. Called via walk_tree. */
static tree static tree
record_call_1 (tree *tp, int *walk_subtrees, void *data) record_call_1 (tree *tp, int *walk_subtrees, void *data)
...@@ -538,6 +549,43 @@ cgraph_create_edges (struct cgraph_node *node, tree body) ...@@ -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 nodes we're interested in are never shared, so walk
the tree ignoring duplicates. */ the tree ignoring duplicates. */
visited_nodes = pointer_set_create (); 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); walk_tree (&body, record_call_1, node, visited_nodes);
pointer_set_destroy (visited_nodes); pointer_set_destroy (visited_nodes);
visited_nodes = NULL; visited_nodes = NULL;
...@@ -596,6 +644,9 @@ verify_cgraph_node (struct cgraph_node *node) ...@@ -596,6 +644,9 @@ verify_cgraph_node (struct cgraph_node *node)
{ {
struct cgraph_edge *e; struct cgraph_edge *e;
struct cgraph_node *main_clone; 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); timevar_push (TV_CGRAPH_VERIFY);
error_found = false; error_found = false;
...@@ -655,8 +706,23 @@ verify_cgraph_node (struct cgraph_node *node) ...@@ -655,8 +706,23 @@ verify_cgraph_node (struct cgraph_node *node)
&& DECL_SAVED_TREE (node->decl) && !TREE_ASM_WRITTEN (node->decl) && DECL_SAVED_TREE (node->decl) && !TREE_ASM_WRITTEN (node->decl)
&& (!DECL_EXTERNAL (node->decl) || node->global.inlined_to)) && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to))
{ {
walk_tree_without_duplicates (&DECL_SAVED_TREE (node->decl), if (this_cfun->cfg)
verify_cgraph_node_1, node); {
/* 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) for (e = node->callees; e; e = e->next_callee)
{ {
if (!e->aux) if (!e->aux)
...@@ -729,12 +795,14 @@ cgraph_analyze_function (struct cgraph_node *node) ...@@ -729,12 +795,14 @@ cgraph_analyze_function (struct cgraph_node *node)
struct cgraph_edge *e; struct cgraph_edge *e;
current_function_decl = decl; current_function_decl = decl;
push_cfun (DECL_STRUCT_FUNCTION (decl));
cgraph_lower_function (node);
/* First kill forward declaration so reverse inlining works properly. */ /* 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.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) if (node->local.inlinable)
node->local.disregard_inline_limits node->local.disregard_inline_limits
= lang_hooks.tree_inlining.disregard_inline_limits (decl); = lang_hooks.tree_inlining.disregard_inline_limits (decl);
...@@ -754,6 +822,7 @@ cgraph_analyze_function (struct cgraph_node *node) ...@@ -754,6 +822,7 @@ cgraph_analyze_function (struct cgraph_node *node)
node->global.insns = node->local.self_insns; node->global.insns = node->local.self_insns;
node->analyzed = true; node->analyzed = true;
pop_cfun ();
current_function_decl = NULL; current_function_decl = NULL;
} }
...@@ -1178,7 +1247,10 @@ cgraph_build_static_cdtor (char which, tree body, int priority) ...@@ -1178,7 +1247,10 @@ cgraph_build_static_cdtor (char which, tree body, int priority)
/* ??? We will get called LATE in the compilation process. */ /* ??? We will get called LATE in the compilation process. */
if (cgraph_global_info_ready) if (cgraph_global_info_ready)
tree_rest_of_compilation (decl); {
tree_lowering_passes (decl);
tree_rest_of_compilation (decl);
}
else else
cgraph_finalize_function (decl, 0); cgraph_finalize_function (decl, 0);
......
...@@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h" #include "toplev.h"
#include "tm_p.h" #include "tm_p.h"
#include "target.h" #include "target.h"
#include "tree-pass.h"
/* Various flags to control the mangling process. */ /* Various flags to control the mangling process. */
...@@ -504,7 +505,9 @@ use_thunk (tree thunk_fndecl, bool emit_p) ...@@ -504,7 +505,9 @@ use_thunk (tree thunk_fndecl, bool emit_p)
/* Re-enable access control. */ /* Re-enable access control. */
pop_deferring_access_checks (); pop_deferring_access_checks ();
expand_body (finish_function (0)); thunk_fndecl = finish_function (0);
tree_lowering_passes (thunk_fndecl);
expand_body (thunk_fndecl);
} }
pop_from_top_level (); pop_from_top_level ();
......
...@@ -162,19 +162,20 @@ struct expr_status GTY(()) ...@@ -162,19 +162,20 @@ struct expr_status GTY(())
struct function GTY(()) struct function GTY(())
{ {
struct eh_status *eh; struct eh_status *eh;
struct eh_status *saved_eh;
struct expr_status *expr; struct expr_status *expr;
struct emit_status *emit; struct emit_status *emit;
struct varasm_status *varasm; struct varasm_status *varasm;
/* The control flow graph for this function. */ /* The control flow graph for this function. */
struct control_flow_graph *cfg; struct control_flow_graph *cfg;
struct control_flow_graph *saved_cfg;
bool after_inlining; bool after_inlining;
/* For tree-optimize.c. */ /* For tree-optimize.c. */
/* Saved tree and arguments during tree optimization. Used later for /* Saved tree and arguments during tree optimization. Used later for
inlining */ inlining */
tree saved_tree;
tree saved_args; tree saved_args;
tree saved_static_chain_decl; tree saved_static_chain_decl;
......
...@@ -121,6 +121,7 @@ copy_decl_for_inlining (tree decl, tree from_fn, tree to_fn) ...@@ -121,6 +121,7 @@ copy_decl_for_inlining (tree decl, tree from_fn, tree to_fn)
if (TREE_CODE (copy) == LABEL_DECL) if (TREE_CODE (copy) == LABEL_DECL)
{ {
TREE_ADDRESSABLE (copy) = 0; TREE_ADDRESSABLE (copy) = 0;
LABEL_DECL_UID (copy) = -1;
} }
} }
......
...@@ -7,5 +7,5 @@ ...@@ -7,5 +7,5 @@
The warning about "no return statement in function The warning about "no return statement in function
returning non-void" is PR 13000. */ returning non-void" is PR 13000. */
static int foo (int a __attribute__((unused)) ) { } static int foo (int a __attribute__((unused)) ) { } /* { dg-warning "control reaches end of non-void" } */
int main (void) { return foo (0); } /* { dg-warning "control may reach end" } */ int main (void) { return foo (0); }
...@@ -446,7 +446,7 @@ create_bb (void *h, void *e, basic_block after) ...@@ -446,7 +446,7 @@ create_bb (void *h, void *e, basic_block after)
/* Fold COND_EXPR_COND of each COND_EXPR. */ /* Fold COND_EXPR_COND of each COND_EXPR. */
static void void
fold_cond_expr_cond (void) fold_cond_expr_cond (void)
{ {
basic_block bb; basic_block bb;
......
...@@ -542,6 +542,7 @@ extern tree gimplify_build2 (block_stmt_iterator *, enum tree_code, ...@@ -542,6 +542,7 @@ extern tree gimplify_build2 (block_stmt_iterator *, enum tree_code,
extern tree gimplify_build3 (block_stmt_iterator *, enum tree_code, extern tree gimplify_build3 (block_stmt_iterator *, enum tree_code,
tree, tree, tree, tree); tree, tree, tree, tree);
extern void init_empty_tree_cfg (void); extern void init_empty_tree_cfg (void);
extern void fold_cond_expr_cond (void);
/* In tree-pretty-print.c. */ /* In tree-pretty-print.c. */
extern void dump_generic_bb (FILE *, basic_block, int, int); extern void dump_generic_bb (FILE *, basic_block, int, int);
......
...@@ -28,8 +28,10 @@ void optimize_inline_calls (tree); ...@@ -28,8 +28,10 @@ void optimize_inline_calls (tree);
bool tree_inlinable_function_p (tree); bool tree_inlinable_function_p (tree);
tree copy_tree_r (tree *, int *, void *); tree copy_tree_r (tree *, int *, void *);
void clone_body (tree, tree, void *); void clone_body (tree, tree, void *);
tree save_body (tree, tree *, tree *); void save_body (tree, tree *, tree *);
int estimate_move_cost (tree type); int estimate_move_cost (tree type);
void push_cfun (struct function *new_cfun);
void pop_cfun (void);
int estimate_num_insns (tree expr); int estimate_num_insns (tree expr);
/* 0 if we should not perform inlining. /* 0 if we should not perform inlining.
......
...@@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA. */
#include "cgraph.h" #include "cgraph.h"
#include "graph.h" #include "graph.h"
#include "cfgloop.h" #include "cfgloop.h"
#include "except.h"
/* Global variables used to communicate with passes. */ /* Global variables used to communicate with passes. */
...@@ -55,7 +56,7 @@ int dump_flags; ...@@ -55,7 +56,7 @@ int dump_flags;
bool in_gimple_form; bool in_gimple_form;
/* The root of the compilation pass tree, once constructed. */ /* 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. */ /* Gate: execute, or not, all of the non-trivial optimizations. */
...@@ -158,6 +159,51 @@ static struct tree_opt_pass pass_free_datastructures = ...@@ -158,6 +159,51 @@ static struct tree_opt_pass pass_free_datastructures =
0 /* letter */ 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 /* Do the actions required to initialize internal data structures used
in tree-ssa optimization passes. */ in tree-ssa optimization passes. */
...@@ -320,14 +366,21 @@ init_tree_optimization_passes (void) ...@@ -320,14 +366,21 @@ init_tree_optimization_passes (void)
NEXT_PASS (pass_ipa_inline); NEXT_PASS (pass_ipa_inline);
*p = NULL; *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_remove_useless_stmts);
NEXT_PASS (pass_mudflap_1); NEXT_PASS (pass_mudflap_1);
NEXT_PASS (pass_lower_cf); NEXT_PASS (pass_lower_cf);
NEXT_PASS (pass_lower_eh); NEXT_PASS (pass_lower_eh);
NEXT_PASS (pass_build_cfg); NEXT_PASS (pass_build_cfg);
NEXT_PASS (pass_pre_expand); NEXT_PASS (pass_pre_expand);
NEXT_PASS (pass_warn_function_return); NEXT_PASS (pass_warn_function_return);
*p = NULL;
p = &all_passes;
NEXT_PASS (pass_fixup_cfg);
NEXT_PASS (pass_tree_profile); NEXT_PASS (pass_tree_profile);
NEXT_PASS (pass_init_datastructures); NEXT_PASS (pass_init_datastructures);
NEXT_PASS (pass_all_optimizations); NEXT_PASS (pass_all_optimizations);
...@@ -432,6 +485,7 @@ init_tree_optimization_passes (void) ...@@ -432,6 +485,7 @@ init_tree_optimization_passes (void)
#undef NEXT_PASS #undef NEXT_PASS
register_dump_files (all_lowering_passes, false, 0);
register_dump_files (all_passes, false, PROP_gimple_any register_dump_files (all_passes, false, PROP_gimple_any
| PROP_gimple_lcf | PROP_gimple_lcf
| PROP_gimple_leh | PROP_gimple_leh
...@@ -606,6 +660,23 @@ execute_pass_list (struct tree_opt_pass *pass) ...@@ -606,6 +660,23 @@ execute_pass_list (struct tree_opt_pass *pass)
while (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. */ /* Execute all IPA passes. */
void void
ipa_passes (void) ipa_passes (void)
...@@ -675,8 +746,7 @@ tree_rest_of_compilation (tree fndecl) ...@@ -675,8 +746,7 @@ tree_rest_of_compilation (tree fndecl)
cgraph_clone_inlined_nodes (e, true); cgraph_clone_inlined_nodes (e, true);
} }
cfun->saved_static_chain_decl = cfun->static_chain_decl; cfun->saved_static_chain_decl = cfun->static_chain_decl;
cfun->saved_tree = save_body (fndecl, &cfun->saved_args, save_body (fndecl, &cfun->saved_args, &cfun->saved_static_chain_decl);
&cfun->saved_static_chain_decl);
} }
if (flag_inline_trees) if (flag_inline_trees)
...@@ -712,6 +782,7 @@ tree_rest_of_compilation (tree fndecl) ...@@ -712,6 +782,7 @@ tree_rest_of_compilation (tree fndecl)
bitmap_obstack_initialize (NULL); bitmap_obstack_initialize (NULL);
bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/ bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
tree_register_cfg_hooks ();
/* Perform all tree transforms and optimizations. */ /* Perform all tree transforms and optimizations. */
execute_pass_list (all_passes); execute_pass_list (all_passes);
...@@ -721,12 +792,16 @@ tree_rest_of_compilation (tree fndecl) ...@@ -721,12 +792,16 @@ tree_rest_of_compilation (tree fndecl)
bitmap_obstack_release (NULL); bitmap_obstack_release (NULL);
/* Restore original body if still needed. */ /* 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; 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->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 /* When not in unit-at-a-time mode, we must preserve out of line copy
representing node before inlining. Restore original outgoing edges representing node before inlining. Restore original outgoing edges
using clone we created earlier. */ using clone we created earlier. */
...@@ -734,6 +809,7 @@ tree_rest_of_compilation (tree fndecl) ...@@ -734,6 +809,7 @@ tree_rest_of_compilation (tree fndecl)
{ {
struct cgraph_edge *e; struct cgraph_edge *e;
node = cgraph_node (current_function_decl);
cgraph_node_remove_callees (node); cgraph_node_remove_callees (node);
node->callees = saved_node->callees; node->callees = saved_node->callees;
saved_node->callees = NULL; saved_node->callees = NULL;
......
...@@ -155,6 +155,7 @@ struct dump_file_info ...@@ -155,6 +155,7 @@ struct dump_file_info
(TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts) (TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts)
extern void ipa_passes (void); extern void ipa_passes (void);
extern void tree_lowering_passes (tree decl);
extern struct tree_opt_pass pass_mudflap_1; extern struct tree_opt_pass pass_mudflap_1;
extern struct tree_opt_pass pass_mudflap_2; extern struct tree_opt_pass pass_mudflap_2;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment