This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
IPA merge: make fixup_cfg to deal with SSA
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org, dnovillo at redhat dot com
- Date: Thu, 28 Dec 2006 20:41:01 +0100
- Subject: IPA merge: make fixup_cfg to deal with SSA
Hi,
this patch makes execute_fixup_cfg to work fluently in all side cases on SSA.
There are two extra cases to care on SSA: when new edges to nonlocal goto
receivers are added, the appropriate PHI node has to be updated. THe update_ssa
has to be called manually (instead of using TODO flag) as fixup_cfg is used
with and without optimizing. This is probably cleaner than making
tree-optimize to silently ignore the flag when function don't seem to be in SSA
or having two fixup passes (SSA and non-SSA one).
While debugging the problem I also noticed that DECL_NOTHROW is set incorrectly
and additionally after_inlining flag is set too late so we hit some false
sanity checks in update_ssa.
Bootstrapped/regtested i686-linux without IPA-SSA and x86_64-linux with
IPA-SSA. OK?
Honza
* tree-optimize (execute_fixup_cfg): Set after_inlining flag;
set NOTHROW flag on call statements proved to be nothrow;
update statement of local calls so new pure/const functions are
updated; update_ssa when in ssa form; mark PHI nodes of nonlocal
goto receivers.
(tree_rest_of_compilation): Register hooks and initialize bitmap
early; do not set after_inlining flag.
Index: tree-optimize.c
===================================================================
*** tree-optimize.c (revision 120209)
--- tree-optimize.c (working copy)
*************** execute_fixup_cfg (void)
*** 264,269 ****
--- 318,325 ----
basic_block bb;
block_stmt_iterator bsi;
+ cfun->after_inlining = true;
+
if (cfun->eh)
FOR_EACH_BB (bb)
{
*************** execute_fixup_cfg (void)
*** 271,279 ****
{
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);
}
--- 327,342 ----
{
tree stmt = bsi_stmt (bsi);
tree call = get_call_expr_in (stmt);
+ tree decl = call ? get_callee_fndecl (call) : NULL;
! if (decl && call_expr_flags (call) & (ECF_CONST | ECF_PURE)
! && TREE_SIDE_EFFECTS (call))
! {
! update_stmt (stmt);
! TREE_SIDE_EFFECTS (call) = 0;
! }
! if (decl && TREE_NOTHROW (decl))
! TREE_NOTHROW (call) = 1;
if (!tree_could_throw_p (stmt) && lookup_stmt_eh_region (stmt))
remove_stmt_from_eh_region (stmt);
}
*************** execute_fixup_cfg (void)
*** 281,309 ****
}
if (current_function_has_nonlocal_label)
! FOR_EACH_BB (bb)
! {
! for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
! {
! tree stmt = bsi_stmt (bsi);
! if (tree_can_make_abnormal_goto (stmt))
! {
! if (stmt == bsi_stmt (bsi_last (bb)))
! {
! if (!has_abnormal_outgoing_edge_p (bb))
make_abnormal_goto_edges (bb, true);
! }
! else
! {
! edge e = split_block (bb, stmt);
! bb = e->src;
! make_abnormal_goto_edges (bb, true);
! }
! break;
! }
! }
! }
cleanup_tree_cfg ();
/* Dump a textual representation of the flowgraph. */
--- 344,398 ----
}
if (current_function_has_nonlocal_label)
! {
! FOR_EACH_BB (bb)
! {
! for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
! {
! tree stmt = bsi_stmt (bsi);
! if (tree_can_make_abnormal_goto (stmt))
! {
! if (stmt == bsi_stmt (bsi_last (bb)))
! {
! if (!has_abnormal_outgoing_edge_p (bb))
! make_abnormal_goto_edges (bb, true);
! }
! else
! {
! edge e = split_block (bb, stmt);
! bb = e->src;
make_abnormal_goto_edges (bb, true);
! }
! break;
! }
!
! /* Update PHIs on nonlocal goto receivers we (possibly)
! just created new edges into. */
! if (TREE_CODE (stmt) == LABEL_EXPR
! && gimple_in_ssa_p (cfun))
! {
! tree target = LABEL_EXPR_LABEL (stmt);
! if (DECL_NONLOCAL (target))
! {
! tree phi;
! for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
! {
! gcc_assert (SSA_NAME_OCCURS_IN_ABNORMAL_PHI
! (PHI_RESULT (phi)));
! mark_sym_for_renaming
! (SSA_NAME_VAR (PHI_RESULT (phi)));
! }
! }
! }
! }
! }
! }
+ if (gimple_in_ssa_p (cfun))
+ {
+ delete_unreachable_blocks ();
+ update_ssa (TODO_update_ssa);
+ }
cleanup_tree_cfg ();
/* Dump a textual representation of the flowgraph. */
*************** tree_rest_of_compilation (tree fndecl)
*** 408,413 ****
--- 508,516 ----
node = cgraph_node (fndecl);
+ /* Initialize the default bitmap obstack. */
+ bitmap_obstack_initialize (NULL);
+
/* We might need the body of this function so that we can expand
it inline somewhere else. */
if (cgraph_preserve_function_body_p (fndecl))
*************** tree_rest_of_compilation (tree fndecl)
*** 424,430 ****
We haven't necessarily assigned RTL to all variables yet, so it's
not safe to try to expand expressions involving them. */
cfun->x_dont_save_pending_sizes_p = 1;
! cfun->after_inlining = true;
if (flag_inline_trees)
{
--- 527,534 ----
We haven't necessarily assigned RTL to all variables yet, so it's
not safe to try to expand expressions involving them. */
cfun->x_dont_save_pending_sizes_p = 1;
!
! tree_register_cfg_hooks ();
if (flag_inline_trees)
{
*************** tree_rest_of_compilation (tree fndecl)
*** 453,464 ****
Kill it so it won't confuse us. */
cgraph_node_remove_callees (node);
-
- /* Initialize the default bitmap obstack. */
- 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);
--- 557,563 ----