aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Liska <marxin@gcc.gnu.org>2017-03-28 11:37:22 +0000
committerMartin Liska <marxin@gcc.gnu.org>2017-03-28 11:37:22 +0000
commitc5ad24334348a54a8378366613d71a095386e5da (patch)
treeba4975babde9f783968283e700435904bbaaf893 /gcc
parent17722fb9e6f8c79c7016c68ea359d6fe2dd5aadd (diff)
downloadgcc-c5ad24334348a54a8378366613d71a095386e5da.zip
gcc-c5ad24334348a54a8378366613d71a095386e5da.tar.gz
gcc-c5ad24334348a54a8378366613d71a095386e5da.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr80205.C34
-rw-r--r--gcc/tree-inline.c92
4 files changed, 96 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7274aa4..f15a8a8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
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
* gimple-fold.c (gimple_fold_indirect_ref): Do not touch
TYPE_REF_CAN_ALIAS_ALL references.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fe42af1..b3a5471 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/ipa/pr80205.C b/gcc/testsuite/g++.dg/ipa/pr80205.C
new file mode 100644
index 0000000..460bdcb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr80205.C
@@ -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;
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 6b6d489..09e80e6 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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))
- {
- 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))
+ /* 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)
{
- 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;
+
+ /* 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);
+ add_phi_arg (new_phi, new_arg, new_edge, locus);
+ }
}
}
}