diff options
author | Martin Liska <marxin@gcc.gnu.org> | 2017-03-28 11:37:22 +0000 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2017-03-28 11:37:22 +0000 |
commit | c5ad24334348a54a8378366613d71a095386e5da (patch) | |
tree | ba4975babde9f783968283e700435904bbaaf893 /gcc/tree-inline.c | |
parent | 17722fb9e6f8c79c7016c68ea359d6fe2dd5aadd (diff) | |
download | gcc-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/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 92 |
1 files changed, 51 insertions, 41 deletions
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); + } } } } |