|
|
Create a copy of a function's tree.
OLD_DECL and NEW_DECL are FUNCTION_DECL tree nodes
of the original function and the new copied function
respectively. In case we want to replace a DECL
tree with another tree while duplicating the function's
body, TREE_MAP represents the mapping between these
trees. If UPDATE_CLONES is set, the call_stmt fields
of edges of clones of the function will be updated.
Definition at line 2752 of file tree-inline.c.
References allocate_struct_function(), copy_arguments_for_versioning(), copy_decl_no_change(), copy_static_chain(), create_tmp_var_name(), current_function_decl, DECL_ABSTRACT_ORIGIN, DECL_ARGUMENTS, DECL_ARTIFICIAL, DECL_NAME, DECL_ORIGIN, DECL_POSSIBLY_INLINED, DECL_RTL, DECL_SOURCE_LOCATION, DECL_STRUCT_FUNCTION, IDENTIFIER_POINTER, insert_decl_map(), NULL_TREE, SET_DECL_RTL, and TREE_CODE. 02754 {
02755 struct cgraph_node *old_version_node;
02756 struct cgraph_node *new_version_node;
02757 copy_body_data id;
02758 tree p, new_fndecl;
02759 unsigned i;
02760 struct ipa_replace_map *replace_info;
02761 basic_block old_entry_block;
02762 tree t_step;
02763
02764 gcc_assert (TREE_CODE (old_decl) == FUNCTION_DECL
02765 && TREE_CODE (new_decl) == FUNCTION_DECL);
02766 DECL_POSSIBLY_INLINED (old_decl) = 1;
02767
02768 old_version_node = cgraph_node (old_decl);
02769 new_version_node = cgraph_node (new_decl);
02770
02771 allocate_struct_function (new_decl);
02772
02773 cfun->function_end_locus = DECL_SOURCE_LOCATION (new_decl);
02774
02775 DECL_ARTIFICIAL (new_decl) = 1;
02776 DECL_ABSTRACT_ORIGIN (new_decl) = DECL_ORIGIN (old_decl);
02777
02778
02779 if (!update_clones)
02780 DECL_NAME (new_decl) = create_tmp_var_name (NULL);
02781
02782 if (DECL_RTL (old_decl) != NULL)
02783 {
02784 SET_DECL_RTL (new_decl, copy_rtx (DECL_RTL (old_decl)));
02785 XEXP (DECL_RTL (new_decl), 0) =
02786 gen_rtx_SYMBOL_REF (GET_MODE (XEXP (DECL_RTL (old_decl), 0)),
02787 IDENTIFIER_POINTER (DECL_NAME (new_decl)));
02788 }
02789
02790
02791 memset (&id, 0, sizeof (id));
02792
02793 id.decl_map = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
02794 id.src_fn = old_decl;
02795 id.dst_fn = new_decl;
02796 id.src_node = old_version_node;
02797 id.dst_node = new_version_node;
02798 id.src_cfun = DECL_STRUCT_FUNCTION (old_decl);
02799
02800 id.copy_decl = copy_decl_no_change;
02801 id.transform_call_graph_edges
02802 = update_clones ? CB_CGE_MOVE_CLONES : CB_CGE_MOVE;
02803 id.transform_new_cfg = true;
02804 id.transform_return_to_modify = false;
02805 id.transform_lang_insert_block = false;
02806
02807 current_function_decl = new_decl;
02808
02809
02810 p = DECL_STRUCT_FUNCTION (old_decl)->static_chain_decl;
02811 if (p)
02812 DECL_STRUCT_FUNCTION (new_decl)->static_chain_decl =
02813 copy_static_chain (DECL_STRUCT_FUNCTION (old_decl)->static_chain_decl,
02814 &id);
02815
02816 if (DECL_ARGUMENTS (old_decl) != NULL_TREE)
02817 DECL_ARGUMENTS (new_decl) =
02818 copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id);
02819
02820
02821 if (tree_map)
02822 for (i = 0; i < VARRAY_ACTIVE_SIZE (tree_map); i++)
02823 {
02824 replace_info = VARRAY_GENERIC_PTR (tree_map, i);
02825 if (replace_info->replace_p)
02826 insert_decl_map (&id, replace_info->old_tree,
02827 replace_info->new_tree);
02828 }
02829
02830 DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id);
02831
02832
02833 number_blocks (id.dst_fn);
02834
02835 if (DECL_STRUCT_FUNCTION (old_decl)->unexpanded_var_list != NULL_TREE)
02836
02837 for (t_step = DECL_STRUCT_FUNCTION (old_decl)->unexpanded_var_list;
02838 t_step; t_step = TREE_CHAIN (t_step))
02839 {
02840 tree var = TREE_VALUE (t_step);
02841 if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
02842 cfun->unexpanded_var_list = tree_cons (NULL_TREE, var,
02843 cfun->unexpanded_var_list);
02844 else
02845 cfun->unexpanded_var_list =
02846 tree_cons (NULL_TREE, remap_decl (var, &id),
02847 cfun->unexpanded_var_list);
02848 }
02849
02850
02851 old_entry_block = ENTRY_BLOCK_PTR_FOR_FUNCTION
02852 (DECL_STRUCT_FUNCTION (old_decl));
02853 new_fndecl = copy_body (&id,
02854 old_entry_block->count,
02855 old_entry_block->frequency, NULL, NULL);
02856
02857 DECL_SAVED_TREE (new_decl) = DECL_SAVED_TREE (new_fndecl);
02858
02859 DECL_STRUCT_FUNCTION (new_decl)->cfg =
02860 DECL_STRUCT_FUNCTION (new_fndecl)->cfg;
02861 DECL_STRUCT_FUNCTION (new_decl)->eh = DECL_STRUCT_FUNCTION (new_fndecl)->eh;
02862 DECL_STRUCT_FUNCTION (new_decl)->ib_boundaries_block =
02863 DECL_STRUCT_FUNCTION (new_fndecl)->ib_boundaries_block;
02864 DECL_STRUCT_FUNCTION (new_decl)->last_label_uid =
02865 DECL_STRUCT_FUNCTION (new_fndecl)->last_label_uid;
02866
02867 if (DECL_RESULT (old_decl) != NULL_TREE)
02868 {
02869 tree *res_decl = &DECL_RESULT (old_decl);
02870 DECL_RESULT (new_decl) = remap_decl (*res_decl, &id);
02871 lang_hooks.dup_lang_specific_decl (DECL_RESULT (new_decl));
02872 }
02873
02874 current_function_decl = NULL;
02875
02876 number_blocks (new_decl);
02877
02878
02879 splay_tree_delete (id.decl_map);
02880 fold_cond_expr_cond ();
02881 return;
02882 }
|