diff options
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 96 |
1 files changed, 52 insertions, 44 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index d08a96d3f7b..741f99ed456 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1845,7 +1845,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, call_stmt = dyn_cast <gcall *> (stmt); if (call_stmt && gimple_call_va_arg_pack_p (call_stmt) - && id->call_stmt) + && id->call_stmt + && ! gimple_call_va_arg_pack_p (id->call_stmt)) { /* __builtin_va_arg_pack () should be replaced by all arguments corresponding to ... in the caller. */ @@ -1925,7 +1926,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, && id->call_stmt && (decl = gimple_call_fndecl (stmt)) && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL - && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN) + && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN + && ! gimple_call_va_arg_pack_p (id->call_stmt)) { /* __builtin_va_arg_pack_len () should be replaced by the number of anonymous arguments. */ @@ -2338,50 +2340,56 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id) { 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; + /* Technically we'd want a SSA_DEFAULT_DEF here... */ + SSA_NAME_DEF_STMT (new_res) = gimple_build_nop (); + } + else + FOR_EACH_EDGE (new_edge, ei, new_bb->preds) + { + 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); + 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); + } } } @@ -4538,7 +4546,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) id->src_fn = fn; id->src_node = cg_edge->callee; id->src_cfun = DECL_STRUCT_FUNCTION (fn); - id->call_stmt = stmt; + id->call_stmt = call_stmt; /* If the src function contains an IFN_VA_ARG, then so will the dst function after inlining. */ |