This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix tree-inline.c gimple_regimplify_operands callers (PR middle-end/37356)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 9 Sep 2008 15:11:50 -0400
- Subject: [PATCH] Fix tree-inline.c gimple_regimplify_operands callers (PR middle-end/37356)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
gimple_regimplify_operands expects that the stmt passed to it is already
in the sequence (eventually we should change it to just accept a
gimple_stmt_iterator * argument and fetch stmt from there).
The omp-low.c callers already do that, but both tree-inline.c callers did
not. In copy_bb this caused the attached testcase to ICE.
This patch fixes that up, also lets copy_bb loop over all the newly added
stmts instead of just the last one. In insert_init_stmt it removes
some unnecessary code (adding referenced vars and marking syms for renaming
is already handled in gimple_regimplify_operands, also creating of
a gimplify context), and avoids ICEs if init_stmt is NULL
(gimple_regimplify_operands assumes stmt is non-NULL).
Bootstrapped/regtested on x86_64-linux, all languages including Ada, ok for
trunk?
2008-09-09 Jakub Jelinek <jakub@redhat.com>
Jan Hubicka <jh@suse.cz>
PR middle-end/37356
* tree-inline.c (copy_bb): Insert stmt into copy_basic_block before
calling gimple_regimplify_operands on it. Iterate over all newly
added statements, not just the last one.
(insert_init_stmt): Insert stmt into seq first, then call
gimple_regimplify_operands on it. Don't create new gimplification
context, nor find referenced vars.
* g++.dg/tree-ssa/pr37356.C: New test.
--- gcc/tree-inline.c.jj 2008-09-09 16:08:00.000000000 +0200
+++ gcc/tree-inline.c 2008-09-09 17:31:57.000000000 +0200
@@ -1232,7 +1232,7 @@ static basic_block
copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
gcov_type count_scale)
{
- gimple_stmt_iterator gsi, copy_gsi;
+ gimple_stmt_iterator gsi, copy_gsi, seq_gsi;
basic_block copy_basic_block;
tree decl;
@@ -1263,6 +1263,7 @@ copy_bb (copy_body_data *id, basic_block
continue;
gimple_duplicate_stmt_histograms (cfun, stmt, id->src_cfun, orig_stmt);
+ seq_gsi = copy_gsi;
/* With return slot optimization we can end up with
non-gimple (foo *)&this->m, fix that here. */
@@ -1271,21 +1272,31 @@ copy_bb (copy_body_data *id, basic_block
&& !is_gimple_val (gimple_assign_rhs1 (stmt)))
{
tree new_rhs;
- new_rhs = force_gimple_operand_gsi (©_gsi,
+ new_rhs = force_gimple_operand_gsi (&seq_gsi,
gimple_assign_rhs1 (stmt),
true, NULL, true, GSI_SAME_STMT);
gimple_assign_set_rhs1 (stmt, new_rhs);
+ id->regimplify = false;
}
- else if (id->regimplify)
- gimple_regimplify_operands (stmt, ©_gsi);
- gsi_insert_after (©_gsi, stmt, GSI_NEW_STMT);
+ gsi_insert_after (&seq_gsi, stmt, GSI_NEW_STMT);
+
+ if (id->regimplify)
+ gimple_regimplify_operands (stmt, &seq_gsi);
+
+ /* If copy_basic_block has been empty at the start of this iteration,
+ call gsi_start_bb again to get at the newly added statements. */
+ if (gsi_end_p (copy_gsi))
+ copy_gsi = gsi_start_bb (copy_basic_block);
+ else
+ gsi_next (©_gsi);
/* Process the new statement. The call to gimple_regimplify_operands
possibly turned the statement into multiple statements, we
need to process all of them. */
- while (!gsi_end_p (copy_gsi))
+ do
{
+ stmt = gsi_stmt (copy_gsi);
if (is_gimple_call (stmt)
&& gimple_call_va_arg_pack_p (stmt)
&& id->gimple_call)
@@ -1459,6 +1470,7 @@ copy_bb (copy_body_data *id, basic_block
gsi_next (©_gsi);
}
+ while (!gsi_end_p (copy_gsi));
copy_gsi = gsi_last_bb (copy_basic_block);
}
@@ -1889,40 +1901,16 @@ self_inlining_addr_expr (tree value, tre
static void
insert_init_stmt (basic_block bb, gimple init_stmt)
{
- gimple_stmt_iterator si = gsi_last_bb (bb);
- gimple_stmt_iterator i;
- gimple_seq seq = gimple_seq_alloc ();
- struct gimplify_ctx gctx;
-
- push_gimplify_context (&gctx);
-
- i = gsi_start (seq);
- gimple_regimplify_operands (init_stmt, &i);
-
- if (init_stmt
- && !gimple_seq_empty_p (seq))
- {
- /* The replacement can expose previously unreferenced
- variables. */
- if (gimple_in_ssa_p (cfun))
- for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
- find_new_referenced_vars (gsi_stmt (i));
-
- /* Insert the gimplified sequence needed for INIT_STMT
- after SI. INIT_STMT will be inserted after SEQ. */
- gsi_insert_seq_after (&si, seq, GSI_NEW_STMT);
- }
-
- pop_gimplify_context (NULL);
-
/* If VAR represents a zero-sized variable, it's possible that the
assignment statement may result in no gimple statements. */
if (init_stmt)
- gsi_insert_after (&si, init_stmt, GSI_NEW_STMT);
+ {
+ gimple_stmt_iterator si = gsi_last_bb (bb);
- if (gimple_in_ssa_p (cfun))
- for (;!gsi_end_p (si); gsi_next (&si))
- mark_symbols_for_renaming (gsi_stmt (si));
+ gsi_insert_after (&si, init_stmt, GSI_NEW_STMT);
+ gimple_regimplify_operands (init_stmt, &si);
+ mark_symbols_for_renaming (init_stmt);
+ }
}
/* Initialize parameter P with VALUE. If needed, produce init statement
--- gcc/testsuite/g++.dg/tree-ssa/pr37356.C.jj 2008-09-09 16:12:11.000000000 +0200
+++ gcc/testsuite/g++.dg/tree-ssa/pr37356.C 2008-09-09 16:12:11.000000000 +0200
@@ -0,0 +1,34 @@
+// PR middle-end/37356 */
+// { dg-do compile }
+// { dg-options "-O" }
+
+bool foo ();
+int bar ();
+
+bool
+baz (int v)
+{
+ return v == bar ();
+}
+
+struct A
+{
+ A () { baz (1) || foo (); }
+};
+
+struct B
+{
+ static A get () { return A (); }
+ B (const int &x) { }
+ B () : b (get ()) { }
+ A b;
+};
+
+B c;
+
+void
+test ()
+{
+ int d;
+ c = d;
+}
Jakub