diff options
author | Jing Yu <jingyu@google.com> | 2012-02-15 15:40:16 -0800 |
---|---|---|
committer | Jing Yu <jingyu@google.com> | 2012-02-15 15:40:16 -0800 |
commit | 3f73d6ef90458b45bbbb33ef4c2b174d4662a22d (patch) | |
tree | 1b5f0d96c51b51168b3713058a1b62e92f1136eb /gcc-4.6/gcc/ipa-split.c | |
parent | d7030123e04baab5dbff9c9ee04c0de99bd9a774 (diff) | |
download | toolchain_gcc-3f73d6ef90458b45bbbb33ef4c2b174d4662a22d.tar.gz toolchain_gcc-3f73d6ef90458b45bbbb33ef4c2b174d4662a22d.tar.bz2 toolchain_gcc-3f73d6ef90458b45bbbb33ef4c2b174d4662a22d.zip |
Sync down FSF r184235@google/gcc-4_6_2-mobile branch
1) Get mostly new patches from FSF gcc-4.6 branch
2) Fix PR52129
3) Insert GNU-stack note for all ARM targets
Change-Id: I2b9926981210e517e4021242908074319a91d6bd
Diffstat (limited to 'gcc-4.6/gcc/ipa-split.c')
-rw-r--r-- | gcc-4.6/gcc/ipa-split.c | 60 |
1 files changed, 37 insertions, 23 deletions
diff --git a/gcc-4.6/gcc/ipa-split.c b/gcc-4.6/gcc/ipa-split.c index 3b26f61b1..ab3632c52 100644 --- a/gcc-4.6/gcc/ipa-split.c +++ b/gcc-4.6/gcc/ipa-split.c @@ -946,7 +946,7 @@ split_function (struct split_point *split_point) bitmap args_to_skip = BITMAP_ALLOC (NULL); tree parm; int num = 0; - struct cgraph_node *node; + struct cgraph_node *node, *cur_node = cgraph_node (current_function_decl); basic_block return_bb = find_return_bb (); basic_block call_bb; gimple_stmt_iterator gsi; @@ -956,7 +956,6 @@ split_function (struct split_point *split_point) tree retval = NULL, real_retval = NULL; bool split_part_return_p = false; gimple last_stmt = NULL; - bool conv_needed = false; unsigned int i; tree arg; @@ -966,23 +965,41 @@ split_function (struct split_point *split_point) dump_split_point (dump_file, split_point); } + if (cur_node->local.can_change_signature + && !TYPE_ATTRIBUTES (TREE_TYPE (cur_node->decl))) + args_to_skip = BITMAP_ALLOC (NULL); + else + args_to_skip = NULL; + /* Collect the parameters of new function and args_to_skip bitmap. */ for (parm = DECL_ARGUMENTS (current_function_decl); parm; parm = DECL_CHAIN (parm), num++) - if (!is_gimple_reg (parm) - || !gimple_default_def (cfun, parm) - || !bitmap_bit_p (split_point->ssa_names_to_pass, - SSA_NAME_VERSION (gimple_default_def (cfun, parm)))) + if (args_to_skip + && (!is_gimple_reg (parm) + || !gimple_default_def (cfun, parm) + || !bitmap_bit_p (split_point->ssa_names_to_pass, + SSA_NAME_VERSION (gimple_default_def (cfun, + parm))))) bitmap_set_bit (args_to_skip, num); else { - arg = gimple_default_def (cfun, parm); - if (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)) - != TYPE_MAIN_VARIANT (TREE_TYPE (arg))) + /* This parm might not have been used up to now, but is going to be + used, hence register it. */ + add_referenced_var (parm); + if (is_gimple_reg (parm)) { - conv_needed = true; - arg = fold_convert (DECL_ARG_TYPE (parm), arg); + arg = gimple_default_def (cfun, parm); + if (!arg) + { + arg = make_ssa_name (parm, gimple_build_nop ()); + set_default_def (parm, arg); + } } + else + arg = parm; + + if (!useless_type_conversion_p (DECL_ARG_TYPE (parm), TREE_TYPE (arg))) + arg = fold_convert (DECL_ARG_TYPE (parm), arg); VEC_safe_push (tree, heap, args_to_pass, arg); } @@ -1057,9 +1074,7 @@ split_function (struct split_point *split_point) /* Now create the actual clone. */ rebuild_cgraph_edges (); - node = cgraph_function_versioning (cgraph_node (current_function_decl), - NULL, NULL, - args_to_skip, + node = cgraph_function_versioning (cur_node, NULL, NULL, args_to_skip, split_point->split_bbs, split_point->entry_bb, "part"); /* For usual cloning it is enough to clear builtin only when signature @@ -1070,7 +1085,7 @@ split_function (struct split_point *split_point) DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN; DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0; } - cgraph_node_remove_callees (cgraph_node (current_function_decl)); + cgraph_node_remove_callees (cur_node); if (!split_part_return_p) TREE_THIS_VOLATILE (node->decl) = 1; if (dump_file) @@ -1092,14 +1107,13 @@ split_function (struct split_point *split_point) /* Produce the call statement. */ gsi = gsi_last_bb (call_bb); - if (conv_needed) - FOR_EACH_VEC_ELT (tree, args_to_pass, i, arg) - if (!is_gimple_val (arg)) - { - arg = force_gimple_operand_gsi (&gsi, arg, true, NULL_TREE, - false, GSI_NEW_STMT); - VEC_replace (tree, args_to_pass, i, arg); - } + FOR_EACH_VEC_ELT (tree, args_to_pass, i, arg) + if (!is_gimple_val (arg)) + { + arg = force_gimple_operand_gsi (&gsi, arg, true, NULL_TREE, + false, GSI_CONTINUE_LINKING); + VEC_replace (tree, args_to_pass, i, arg); + } call = gimple_build_call_vec (node->decl, args_to_pass); gimple_set_block (call, DECL_INITIAL (current_function_decl)); |