Handle PHI nodes w/o a argument (PR ipa/80205).
2017-03-28 Martin Liska <mliska@suse.cz> PR ipa/80205 * g++.dg/ipa/pr80205.C: New test. 2017-03-28 Richard Biener <rguenther@suse.de> PR ipa/80205 * tree-inline.c (copy_phis_for_bb): Do not create PHI node without arguments, generate default definition of a SSA name. From-SVN: r246530
This commit is contained in:
parent
17722fb9e6
commit
c5ad243343
@ -1,3 +1,9 @@
|
||||
2017-03-28 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR ipa/80205
|
||||
* tree-inline.c (copy_phis_for_bb): Do not create PHI node
|
||||
without arguments, generate default definition of a SSA name.
|
||||
|
||||
2017-03-28 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/80222
|
||||
|
@ -1,3 +1,8 @@
|
||||
2017-03-28 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR ipa/80205
|
||||
* g++.dg/ipa/pr80205.C: New test.
|
||||
|
||||
2017-03-28 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
|
||||
|
||||
* gcc.c-torture/execute/pr79121.c:Use __{U}INT32_TYPE__ for targets
|
||||
|
34
gcc/testsuite/g++.dg/ipa/pr80205.C
Normal file
34
gcc/testsuite/g++.dg/ipa/pr80205.C
Normal file
@ -0,0 +1,34 @@
|
||||
// PR ipa/80205
|
||||
// { dg-options "-fnon-call-exceptions --param early-inlining-insns=100 -O2" }
|
||||
|
||||
class a
|
||||
{
|
||||
public:
|
||||
virtual ~a ();
|
||||
};
|
||||
class b
|
||||
{
|
||||
public:
|
||||
template <typename c> b (c);
|
||||
~b () { delete d; }
|
||||
void
|
||||
operator= (b e)
|
||||
{
|
||||
b (e).f (*this);
|
||||
}
|
||||
void
|
||||
f (b &e)
|
||||
{
|
||||
a g;
|
||||
d = e.d;
|
||||
e.d = &g;
|
||||
}
|
||||
a *d;
|
||||
};
|
||||
void
|
||||
h ()
|
||||
{
|
||||
b i = int();
|
||||
void j ();
|
||||
i = j;
|
||||
}
|
@ -2344,50 +2344,60 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
|
||||
if (!virtual_operand_p (res))
|
||||
{
|
||||
walk_tree (&new_res, copy_tree_body_r, id, NULL);
|
||||
new_phi = create_phi_node (new_res, new_bb);
|
||||
FOR_EACH_EDGE (new_edge, ei, new_bb->preds)
|
||||
if (EDGE_COUNT (new_bb->preds) == 0)
|
||||
{
|
||||
edge old_edge = find_edge ((basic_block) new_edge->src->aux, bb);
|
||||
tree arg;
|
||||
tree new_arg;
|
||||
edge_iterator ei2;
|
||||
location_t locus;
|
||||
|
||||
/* When doing partial cloning, we allow PHIs on the entry block
|
||||
as long as all the arguments are the same. Find any input
|
||||
edge to see argument to copy. */
|
||||
if (!old_edge)
|
||||
FOR_EACH_EDGE (old_edge, ei2, bb->preds)
|
||||
if (!old_edge->src->aux)
|
||||
break;
|
||||
|
||||
arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
|
||||
new_arg = arg;
|
||||
walk_tree (&new_arg, copy_tree_body_r, id, NULL);
|
||||
gcc_assert (new_arg);
|
||||
/* With return slot optimization we can end up with
|
||||
non-gimple (foo *)&this->m, fix that here. */
|
||||
if (TREE_CODE (new_arg) != SSA_NAME
|
||||
&& TREE_CODE (new_arg) != FUNCTION_DECL
|
||||
&& !is_gimple_val (new_arg))
|
||||
/* Technically we'd want a SSA_DEFAULT_DEF here... */
|
||||
SSA_NAME_DEF_STMT (new_res) = gimple_build_nop ();
|
||||
}
|
||||
else
|
||||
{
|
||||
new_phi = create_phi_node (new_res, new_bb);
|
||||
FOR_EACH_EDGE (new_edge, ei, new_bb->preds)
|
||||
{
|
||||
gimple_seq stmts = NULL;
|
||||
new_arg = force_gimple_operand (new_arg, &stmts, true, NULL);
|
||||
gsi_insert_seq_on_edge (new_edge, stmts);
|
||||
inserted = true;
|
||||
}
|
||||
locus = gimple_phi_arg_location_from_edge (phi, old_edge);
|
||||
if (LOCATION_BLOCK (locus))
|
||||
{
|
||||
tree *n;
|
||||
n = id->decl_map->get (LOCATION_BLOCK (locus));
|
||||
gcc_assert (n);
|
||||
locus = set_block (locus, *n);
|
||||
}
|
||||
else
|
||||
locus = LOCATION_LOCUS (locus);
|
||||
edge old_edge = find_edge ((basic_block) new_edge->src->aux,
|
||||
bb);
|
||||
tree arg;
|
||||
tree new_arg;
|
||||
edge_iterator ei2;
|
||||
location_t locus;
|
||||
|
||||
add_phi_arg (new_phi, new_arg, new_edge, locus);
|
||||
/* When doing partial cloning, we allow PHIs on the entry
|
||||
block as long as all the arguments are the same.
|
||||
Find any input edge to see argument to copy. */
|
||||
if (!old_edge)
|
||||
FOR_EACH_EDGE (old_edge, ei2, bb->preds)
|
||||
if (!old_edge->src->aux)
|
||||
break;
|
||||
|
||||
arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
|
||||
new_arg = arg;
|
||||
walk_tree (&new_arg, copy_tree_body_r, id, NULL);
|
||||
gcc_assert (new_arg);
|
||||
/* With return slot optimization we can end up with
|
||||
non-gimple (foo *)&this->m, fix that here. */
|
||||
if (TREE_CODE (new_arg) != SSA_NAME
|
||||
&& TREE_CODE (new_arg) != FUNCTION_DECL
|
||||
&& !is_gimple_val (new_arg))
|
||||
{
|
||||
gimple_seq stmts = NULL;
|
||||
new_arg = force_gimple_operand (new_arg, &stmts, true,
|
||||
NULL);
|
||||
gsi_insert_seq_on_edge (new_edge, stmts);
|
||||
inserted = true;
|
||||
}
|
||||
locus = gimple_phi_arg_location_from_edge (phi, old_edge);
|
||||
if (LOCATION_BLOCK (locus))
|
||||
{
|
||||
tree *n;
|
||||
n = id->decl_map->get (LOCATION_BLOCK (locus));
|
||||
gcc_assert (n);
|
||||
locus = set_block (locus, *n);
|
||||
}
|
||||
else
|
||||
locus = LOCATION_LOCUS (locus);
|
||||
|
||||
add_phi_arg (new_phi, new_arg, new_edge, locus);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user