CFG fixup after early inlining
Jan Hubicka
jh@suse.cz
Sun Feb 4 13:28:00 GMT 2007
> > * tree-optimize.c (has_abnormal_outgoing_edge_p): Move to tree-inline.
> > (execute_fixup_cfg): Break out the abnormal goto code.
> > * tree-inline.c (has_abnormal_outgoing_edge_p): Move here from
> > tree-inline.c
> > (make_nonlocal_label_edges): Move here from execute_fixup_cfg.
> > (optimize_inline_calls): Call make_nonlocal_label_edges.
>
> Could you install it, if you don't mind? Thanks in advance.
Hi,
sorry for the delay - I was week off and forgot about this before
leaving. This is variant of patch I installed (with updated comment).
I will deal with commonizing the function incrementally.
Index: ChangeLog
===================================================================
--- ChangeLog (revision 121571)
+++ ChangeLog (working copy)
@@ -1,4 +1,14 @@
2007-02-04 Jan Hubicka <jh@suse.cz>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * tree-optimize.c (has_abnormal_outgoing_edge_p): Move to tree-inline.
+ (execute_fixup_cfg): Break out the abnormal goto code.
+ * tree-inline.c (has_abnormal_outgoing_edge_p): Move here from
+ tree-optimize.c.
+ (make_nonlocal_label_edges): Move here from execute_fixup_cfg.
+ (optimize_inline_calls): Call make_nonlocal_label_edges.
+
+2007-02-04 Jan Hubicka <jh@suse.cz>
* tree-ssa-copyrename.c (copy_rename_partition_coalesce): Return
true when something was changed.
Index: tree-inline.c
===================================================================
--- tree-inline.c (revision 121569)
+++ tree-inline.c (working copy)
@@ -2676,6 +2676,75 @@ fold_marked_statements (int first, struc
}
}
+/* Return true if BB has at least one abnormal outgoing edge. */
+
+static inline bool
+has_abnormal_outgoing_edge_p (basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (e->flags & EDGE_ABNORMAL)
+ return true;
+
+ return false;
+}
+
+/* When a block from the inlined function contains a call with side-effects
+ in the middle gets inlined in a function with non-locals labels, the call
+ becomes a potential non-local goto so we need to add appropriate edge. */
+
+static void
+make_nonlocal_label_edges (void)
+{
+ block_stmt_iterator bsi;
+ basic_block bb;
+
+ 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)));
+ }
+ }
+ }
+ }
+ }
+}
+
/* Expand calls to inline functions in the body of FN. */
unsigned int
@@ -2751,6 +2820,8 @@ optimize_inline_calls (tree fn)
fold_marked_statements (last, id.statements_to_fold);
pointer_set_destroy (id.statements_to_fold);
fold_cond_expr_cond ();
+ if (current_function_has_nonlocal_label)
+ make_nonlocal_label_edges ();
/* We make no attempts to keep dominance info up-to-date. */
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
Index: tree-optimize.c
===================================================================
--- tree-optimize.c (revision 121569)
+++ tree-optimize.c (working copy)
@@ -267,25 +267,9 @@ struct tree_opt_pass pass_free_cfg_annot
0 /* letter */
};
-/* Return true if BB has at least one abnormal outgoing edge. */
-
-static inline bool
-has_abnormal_outgoing_edge_p (basic_block bb)
-{
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (e->flags & EDGE_ABNORMAL)
- return true;
-
- return false;
-}
-
/* Pass: fixup_cfg. IPA passes, compilation of earlier functions or inlining
- might have changed some properties, such as marked functions nothrow or
- added calls that can potentially go to non-local labels. Remove redundant
- edges and basic blocks, and create new ones if necessary.
+ might have changed some properties, such as marked functions nothrow.
+ Remove redundant edges and basic blocks, and create new ones if necessary.
This pass can't be executed as stand alone pass from pass manager, because
in between inlining and this fixup the verify_flow_info would fail. */
@@ -327,53 +311,6 @@ execute_fixup_cfg (void)
todo |= TODO_cleanup_cfg;
}
- 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))
- {
- todo |= TODO_update_ssa | TODO_cleanup_cfg;
- gcc_assert (SSA_NAME_OCCURS_IN_ABNORMAL_PHI
- (PHI_RESULT (phi)));
- mark_sym_for_renaming
- (SSA_NAME_VAR (PHI_RESULT (phi)));
- }
- }
- }
- }
- }
- }
-
/* Dump a textual representation of the flowgraph. */
if (dump_file)
dump_tree_cfg (dump_file, dump_flags);
More information about the Gcc-patches
mailing list