summaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c96
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. */