Commit b69539cb by Jakub Jelinek Committed by Jakub Jelinek

re PR ipa/68672 (g++.dg/torture/pr68470.C: ICE: cannot update SSA form:…

re PR ipa/68672 (g++.dg/torture/pr68470.C: ICE: cannot update SSA form: statement uses released SSA name)

	PR ipa/68672
	* ipa-split.c (split_function): Don't compute/use main_part_return_p.
	Compute retval and retbnd early in all cases if split_part_return_p
	and return_bb is not EXIT.  Remove all clobber stmts and reset
	all debug stmts that refer to SSA_NAMEs defined in split part,
	except if it is retval, in that case replace the old retval with the
	lhs of the call to the split part.

	* g++.dg/ipa/pr68672-1.C: New test.
	* g++.dg/ipa/pr68672-2.C: New test.
	* g++.dg/ipa/pr68672-3.C: New test.

From-SVN: r233374
parent 4c707980
2016-02-12 Jakub Jelinek <jakub@redhat.com>
PR ipa/68672
* ipa-split.c (split_function): Don't compute/use main_part_return_p.
Compute retval and retbnd early in all cases if split_part_return_p
and return_bb is not EXIT. Remove all clobber stmts and reset
all debug stmts that refer to SSA_NAMEs defined in split part,
except if it is retval, in that case replace the old retval with the
lhs of the call to the split part.
2016-02-12 Kugan Vivekanandarajah <kuganv@linaro.org>
revert:
......
......@@ -1244,28 +1244,13 @@ split_function (basic_block return_bb, struct split_point *split_point,
args_to_pass.safe_push (arg);
}
/* See if the split function or the main part will return. */
bool main_part_return_p = false;
/* See if the split function will return. */
bool split_part_return_p = false;
FOR_EACH_EDGE (e, ei, return_bb->preds)
{
if (bitmap_bit_p (split_point->split_bbs, e->src->index))
split_part_return_p = true;
else
main_part_return_p = true;
}
/* The main part also returns if we split on a fallthru edge
and the split part returns. */
if (split_part_return_p)
FOR_EACH_EDGE (e, ei, split_point->entry_bb->preds)
{
if (! bitmap_bit_p (split_point->split_bbs, e->src->index)
&& single_succ_p (e->src))
{
main_part_return_p = true;
break;
}
}
/* Add return block to what will become the split function.
We do not return; no return block is needed. */
......@@ -1279,8 +1264,8 @@ split_function (basic_block return_bb, struct split_point *split_point,
FIXME: Once we are able to change return type, we should change function
to return void instead of just outputting function with undefined return
value. For structures this affects quality of codegen. */
else if (!split_point->split_part_set_retval
&& (retval = find_retval (return_bb)))
else if ((retval = find_retval (return_bb))
&& !split_point->split_part_set_retval)
{
bool redirected = true;
basic_block new_return_bb = create_basic_block (NULL, 0, return_bb);
......@@ -1308,12 +1293,10 @@ split_function (basic_block return_bb, struct split_point *split_point,
}
/* When we pass around the value, use existing return block. */
else
bitmap_set_bit (split_point->split_bbs, return_bb->index);
/* If the main part doesn't return pretend the return block wasn't
found for all of the following. */
if (! main_part_return_p)
return_bb = EXIT_BLOCK_PTR_FOR_FN (cfun);
{
bitmap_set_bit (split_point->split_bbs, return_bb->index);
retbnd = find_retbnd (return_bb);
}
/* If RETURN_BB has virtual operand PHIs, they must be removed and the
virtual operand marked for renaming as we change the CFG in a way that
......@@ -1382,6 +1365,44 @@ split_function (basic_block return_bb, struct split_point *split_point,
DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0;
}
/* If return_bb contains any clobbers that refer to SSA_NAMEs
set in the split part, remove them. Also reset debug stmts that
refer to SSA_NAMEs set in the split part. */
if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
{
gimple_stmt_iterator gsi = gsi_start_bb (return_bb);
while (!gsi_end_p (gsi))
{
tree op;
ssa_op_iter iter;
gimple *stmt = gsi_stmt (gsi);
bool remove = false;
if (gimple_clobber_p (stmt) || is_gimple_debug (stmt))
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
{
basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (op));
if (op != retval
&& bb
&& bb != return_bb
&& bitmap_bit_p (split_point->split_bbs, bb->index))
{
if (is_gimple_debug (stmt))
{
gimple_debug_bind_reset_value (stmt);
update_stmt (stmt);
}
else
remove = true;
break;
}
}
if (remove)
gsi_remove (&gsi, true);
else
gsi_next (&gsi);
}
}
/* If the original function is instrumented then it's
part is also instrumented. */
if (with_bounds)
......@@ -1499,9 +1520,7 @@ split_function (basic_block return_bb, struct split_point *split_point,
return value into and put call just before it. */
if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
{
real_retval = retval = find_retval (return_bb);
retbnd = find_retbnd (return_bb);
real_retval = retval;
if (real_retval && split_point->split_part_set_retval)
{
gphi_iterator psi;
......@@ -1545,6 +1564,28 @@ split_function (basic_block return_bb, struct split_point *split_point,
break;
}
update_stmt (gsi_stmt (bsi));
/* Also adjust clobbers and debug stmts in return_bb. */
for (bsi = gsi_start_bb (return_bb); !gsi_end_p (bsi);
gsi_next (&bsi))
{
gimple *stmt = gsi_stmt (bsi);
if (gimple_clobber_p (stmt)
|| is_gimple_debug (stmt))
{
ssa_op_iter iter;
use_operand_p use_p;
bool update = false;
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
SSA_OP_USE)
if (USE_FROM_PTR (use_p) == real_retval)
{
SET_USE (use_p, retval);
update = true;
}
if (update)
update_stmt (stmt);
}
}
}
/* Replace retbnd with new one. */
......
2016-02-12 Jakub Jelinek <jakub@redhat.com>
PR ipa/68672
* g++.dg/ipa/pr68672-1.C: New test.
* g++.dg/ipa/pr68672-2.C: New test.
* g++.dg/ipa/pr68672-3.C: New test.
2016-02-12 Bernd Schmidt <bschmidt@redhat.com>
PR c/69522
......
// PR ipa/68672
// { dg-do compile }
// { dg-options "-O -finline-small-functions -fpartial-inlining --param=partial-inlining-entry-probability=100" }
void f2 (void *);
void *a;
struct C { virtual void m1 (); };
struct D { C *m2 () { if (a) __builtin_abort (); } };
D f1 ();
struct E { int e; ~E () { if (e) f2 (&e); } };
E *b;
struct I { virtual void m3 (); };
void
I::m3 ()
{
if (a)
f1 ().m2 ()->m1 ();
b->~E ();
}
// PR ipa/68672
// { dg-do compile }
// { dg-options "-O3 --param=partial-inlining-entry-probability=100 -g" }
struct S { ~S () {} };
S *a;
int *b;
void bar ();
void baz ();
void fn (int *);
static int
foo ()
{
S *c = a;
if (c)
{
bar ();
if (a)
__builtin_abort ();
baz ();
}
int p = *b;
if (p)
{
fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b);
fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b);
fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b);
fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b);
}
c->~S ();
int q = 2 * p;
int r = 3 * q;
S *d = c;
return p;
}
void
use1 ()
{
foo ();
}
void
use2 ()
{
foo ();
}
void
use3 ()
{
foo ();
}
// PR ipa/68672
// { dg-do compile }
// { dg-options "-O3 --param=partial-inlining-entry-probability=100 -g" }
struct S { ~S () {} };
S *a, *e;
int *b;
void bar ();
void baz ();
void fn (int *);
void fn2 (S *);
static int
foo ()
{
S *c = a;
if (c)
{
bar ();
if (a)
__builtin_abort ();
baz ();
}
int p = *b;
S *f = e;
if (p)
{
fn2 (f);
fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b);
fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b);
fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b);
fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b);
}
f->~S ();
int q = 2 * p;
int r = 3 * q;
S *d = c;
return p;
}
void
use1 ()
{
foo ();
}
void
use2 ()
{
foo ();
}
void
use3 ()
{
foo ();
}
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