summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-04 08:56:05 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-04 08:56:05 +0000
commit3e9045dd017e57db781b199aba6f2ad9f0313e7b (patch)
treecc1c513083616555771818561214fc727235e351
parent894a47b43cc5eb4302f36c91b9d611b79256e98a (diff)
downloadgcc-3e9045dd017e57db781b199aba6f2ad9f0313e7b.tar.gz
* tree-inline.c (copy_bb): Insert new statements to statements_to_fold
set. (fold_marked_statements): New function. (optimize_inline_calls, tree_function_versioning): Fold new statements. * tree-inline.h (copy_body_data): Add statemetns_to_fold. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120430 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/tree-inline.c38
-rw-r--r--gcc/tree-inline.h3
3 files changed, 49 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b2a3b22d390..80cff346577 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2007-01-04 Jan Hubicka <jh@suse.cz>
+
+ * tree-inline.c (copy_bb): Insert new statements to statements_to_fold
+ set.
+ (fold_marked_statements): New function.
+ (optimize_inline_calls, tree_function_versioning): Fold new statements.
+ * tree-inline.h (copy_body_data): Add statemetns_to_fold.
+
2007-01-03 Daniel Jacobowitz <dan@codesourcery.com>
* config.gcc: Mention libgcc/config.host.
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 20bfc735b2a..bcfdd91b421 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -797,6 +797,20 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, int count_scal
{
stmt = bsi_stmt (copy_bsi);
call = get_call_expr_in (stmt);
+
+ /* Statements produced by inlining can be unfolded, especially
+ when we constant propagated some operands. We can't fold
+ them right now for two reasons:
+ 1) folding require SSA_NAME_DEF_STMTs to be correct
+ 2) we can't change function calls to builtins.
+ So we just mark statement for later folding. We mark
+ all new statements, instead just statements that has changed
+ by some nontrivial substitution so even statements made
+ foldable indirectly are updated. If this turns out to be
+ expensive, copy_body can be told to watch for nontrivial
+ changes. */
+ if (id->statements_to_fold)
+ pointer_set_insert (id->statements_to_fold, stmt);
/* We're duplicating a CALL_EXPR. Find any corresponding
callgraph edges and update or duplicate them. */
if (call && (decl = get_callee_fndecl (call)))
@@ -2571,6 +2585,22 @@ gimple_expand_calls_inline (basic_block bb, copy_body_data *id)
return false;
}
+/* Walk all basic blocks created after FIRST and try to fold every statement
+ in the STATEMENTS pointer set. */
+static void
+fold_marked_statements (int first, struct pointer_set_t *statements)
+{
+ for (;first < n_basic_blocks;first++)
+ if (BASIC_BLOCK (first))
+ {
+ block_stmt_iterator bsi;
+ for (bsi = bsi_start (BASIC_BLOCK (first));
+ !bsi_end_p (bsi); bsi_next (&bsi))
+ if (pointer_set_contains (statements, bsi_stmt (bsi)))
+ fold_stmt (bsi_stmt_ptr (bsi));
+ }
+}
+
/* Expand calls to inline functions in the body of FN. */
void
@@ -2579,6 +2609,7 @@ optimize_inline_calls (tree fn)
copy_body_data id;
tree prev_fn;
basic_block bb;
+ int last = n_basic_blocks;
/* There is no point in performing inlining if errors have already
occurred -- and we might crash if we try to inline invalid
code. */
@@ -2603,6 +2634,7 @@ optimize_inline_calls (tree fn)
id.transform_new_cfg = false;
id.transform_return_to_modify = true;
id.transform_lang_insert_block = false;
+ id.statements_to_fold = pointer_set_create ();
push_gimplify_context ();
@@ -2636,6 +2668,9 @@ optimize_inline_calls (tree fn)
as inlining loops might increase the maximum. */
if (ENTRY_BLOCK_PTR->count)
counts_to_freqs ();
+
+ fold_marked_statements (last, id.statements_to_fold);
+ pointer_set_destroy (id.statements_to_fold);
if (gimple_in_ssa_p (cfun))
{
/* We make no attempts to keep dominance info up-to-date. */
@@ -3188,6 +3223,7 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
id.transform_new_cfg = true;
id.transform_return_to_modify = false;
id.transform_lang_insert_block = false;
+ id.statements_to_fold = pointer_set_create ();
current_function_decl = new_decl;
old_entry_block = ENTRY_BLOCK_PTR_FOR_FUNCTION
@@ -3253,6 +3289,8 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
/* Clean up. */
splay_tree_delete (id.decl_map);
+ fold_marked_statements (0, id.statements_to_fold);
+ pointer_set_destroy (id.statements_to_fold);
fold_cond_expr_cond ();
if (gimple_in_ssa_p (cfun))
{
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index 4755fbbf9fd..e7564478074 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -88,6 +88,9 @@ typedef struct copy_body_data
/* True if lang_hooks.decls.insert_block should be invoked when
duplicating BLOCK nodes. */
bool transform_lang_insert_block;
+
+ /* Statements that might be possibly folded. */
+ struct pointer_set_t *statements_to_fold;
} copy_body_data;
/* Function prototypes. */