From patchwork Thu Jun 10 21:40:06 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [PR,43905] Make IPA-SRA clone functions it modifies Date: Thu, 10 Jun 2010 11:40:06 -0000 From: Martin Jambor X-Patchwork-Id: 55263 Message-Id: <20100610214006.GB3309@alvy.suse.cz> To: GCC Patches Cc: Jan Hubicka , Richard Guenther , Jakub Jelinek Hi, the patch below is basically a different fix to PR 43141 which fixes the still-opened PR 43905 and a number of issues that that first attempt caused (e.g. wrong sharing of parameter chain list and some debug info problems). After trying quite hard to move the body of a function from the old declaration to a new one and all necessary fixing up so that nothing breaks, I gave up and resorted to simple cloning. Fortunately the pass management works in a way that setting the cfun and current_function_decl to the new function is enough to make the subsequent passes work on the correct function. It is a bit of a hack, but I can't think of any substantial improvement. The patch also does not deal with same_body aliases. I hope it is not necessary. And that is what the patch does. I have bootstrapped and tested it on x86_64-linux with no problems. Is it OK for trunk and for 4.5 after a while? Thanks, Martin 2010-06-10 Martin Jambor PR tree-optimization/43905 * tree-sra.c (create_abstract_origin): Removed. (modify_function): Version the call graph node instead of creating abstract origins and dealing with same_body aliases. * testsuite/g++.dg/torture/pr43905.C Index: mine/gcc/tree-sra.c =================================================================== --- mine.orig/gcc/tree-sra.c +++ mine/gcc/tree-sra.c @@ -4224,43 +4224,38 @@ convert_callers (struct cgraph_node *nod return; } -/* Create an abstract origin declaration for OLD_DECL and make it an abstract - origin of the provided decl so that there are preserved parameters for debug - information. */ - -static void -create_abstract_origin (tree old_decl) -{ - if (!DECL_ABSTRACT_ORIGIN (old_decl)) - { - tree new_decl = copy_node (old_decl); - - DECL_ABSTRACT (new_decl) = 1; - SET_DECL_ASSEMBLER_NAME (new_decl, NULL_TREE); - SET_DECL_RTL (new_decl, NULL); - DECL_STRUCT_FUNCTION (new_decl) = NULL; - DECL_ARTIFICIAL (old_decl) = 1; - DECL_ABSTRACT_ORIGIN (old_decl) = new_decl; - } -} - /* Perform all the modification required in IPA-SRA for NODE to have parameters as given in ADJUSTMENTS. */ static void modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments) { - struct cgraph_node *alias; - for (alias = node->same_body; alias; alias = alias->next) - ipa_modify_formal_parameters (alias->decl, adjustments, "ISRA"); - /* current_function_decl must be handled last, after same_body aliases, - as following functions will use what it computed. */ - create_abstract_origin (current_function_decl); + struct cgraph_node *new_node; + struct cgraph_edge *cs; + VEC (cgraph_edge_p, heap) * redirect_callers; + int node_callers; + + node_callers = 0; + for (cs = node->callers; cs != NULL; cs = cs->next_caller) + node_callers++; + redirect_callers = VEC_alloc (cgraph_edge_p, heap, node_callers); + for (cs = node->callers; cs != NULL; cs = cs->next_caller) + VEC_quick_push (cgraph_edge_p, redirect_callers, cs); + + rebuild_cgraph_edges (); + pop_cfun (); + current_function_decl = NULL_TREE; + + new_node = cgraph_function_versioning (node, redirect_callers, NULL, NULL, + NULL, NULL, "isra"); + current_function_decl = new_node->decl; + push_cfun (DECL_STRUCT_FUNCTION (new_node->decl)); + ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA"); ipa_sra_modify_function_body (adjustments); sra_ipa_reset_debug_stmts (adjustments); - convert_callers (node, adjustments); - cgraph_make_node_local (node); + convert_callers (new_node, adjustments); + cgraph_make_node_local (new_node); return; } Index: mine/gcc/testsuite/g++.dg/torture/pr43905.C =================================================================== --- /dev/null +++ mine/gcc/testsuite/g++.dg/torture/pr43905.C @@ -0,0 +1,13 @@ +extern void sf ( __const char *); +struct Matrix{ + int operator[](int n){ + sf ( __PRETTY_FUNCTION__); + } + int operator[](int n)const{ + sf ( __PRETTY_FUNCTION__); + } +}; +void calcmy(Matrix const &b, Matrix &c, int k){ + b[k]; + c[k]; +}