From patchwork Mon Jun 28 16:56:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Jambor X-Patchwork-Id: 57170 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 9CB57B6EEA for ; Tue, 29 Jun 2010 02:58:52 +1000 (EST) Received: (qmail 22782 invoked by alias); 28 Jun 2010 16:58:35 -0000 Received: (qmail 22069 invoked by uid 22791); 28 Jun 2010 16:58:28 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL, BAYES_50, TW_FN, TW_TM X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 28 Jun 2010 16:58:19 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id 2AE558765C for ; Mon, 28 Jun 2010 18:58:16 +0200 (CEST) Resent-From: mjambor@suse.cz Resent-Date: Mon, 28 Jun 2010 18:58:15 +0200 Resent-Message-ID: <20100628165815.GC25493@virgil.arch.suse.de> Resent-To: GCC Patches Message-Id: <20100628165654.809772423@virgil.suse.cz> User-Agent: quilt/0.47-14.9 Date: Mon, 28 Jun 2010 18:56:49 +0200 From: Martin Jambor To: GCC Patches Cc: Jan Hubicka Subject: [PATCH, 4.5 2/2] IPA-SRA versioning for 4.5 References: <20100628165647.460563621@virgil.suse.cz> Content-Disposition: inline; filename=45-version_in_ipasra.diff X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This is a version of the IPA-SRA versioning patch for the 4.5 branch. Unlike in the current trunk, cgraph_function_versioning does redirect recursive calls (and updates cgraph edges accordingly) on the 4.5 branch. Since versioning already demands that we rebuild all outgoing cgraph edges, we can then use those instead of another function body walk. In any case, we must not attempt to use both and so I simply deleted the walk alng with the variable that controlled it. Martin 2010-06-27 Martin Jambor PR tree-optimization/43905 * tree-sra.c (encountered_recursive_call): Removed with all its uses. (convert_callers): Do not handle recursive calls specially. (create_abstract_origin): Removed. (modify_function): Version the call graph node instead of creating abstract origins and dealing with same_body aliases. (ipa_sra_preliminary_function_checks): Check whether the function is versionable. * Makefile.in (tree-sra.o): Add TREE_INLINE_H to dependencies. * testsuite/g++.dg/torture/pr43905.C: New test. Index: gcc/testsuite/g++.dg/torture/pr43905.C =================================================================== --- /dev/null +++ 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]; +} Index: gcc/tree-sra.c =================================================================== --- gcc/tree-sra.c.orig +++ gcc/tree-sra.c @@ -89,6 +89,7 @@ along with GCC; see the file COPYING3. #include "params.h" #include "target.h" #include "flags.h" +#include "tree-inline.h" /* Enumeration of all aggregate reductions we can do. */ enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */ @@ -271,9 +272,6 @@ static int func_param_count; __builtin_apply_args. */ static bool encountered_apply_args; -/* Set by scan_function when it finds a recursive call. */ -static bool encountered_recursive_call; - /* Set by scan_function when it finds a recursive call with less actual arguments than formal parameters.. */ static bool encountered_unchangable_recursive_call; @@ -571,7 +569,6 @@ sra_initialize (void) base_access_vec = pointer_map_create (); memset (&sra_stats, 0, sizeof (sra_stats)); encountered_apply_args = false; - encountered_recursive_call = false; encountered_unchangable_recursive_call = false; } @@ -1169,12 +1166,9 @@ scan_function (bool (*scan_expr) (tree * && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS) encountered_apply_args = true; if (cgraph_get_node (dest) - == cgraph_get_node (current_function_decl)) - { - encountered_recursive_call = true; - if (!callsite_has_enough_arguments_p (stmt)) - encountered_unchangable_recursive_call = true; - } + == cgraph_get_node (current_function_decl) + && !callsite_has_enough_arguments_p (stmt)) + encountered_unchangable_recursive_call = true; } if (final_bbs @@ -4023,7 +4017,6 @@ convert_callers (struct cgraph_node *nod { tree old_cur_fndecl = current_function_decl; struct cgraph_edge *cs; - basic_block this_block; bitmap recomputed_callers = BITMAP_ALLOC (NULL); for (cs = node->callers; cs; cs = cs->next_caller) @@ -4043,7 +4036,8 @@ convert_callers (struct cgraph_node *nod } for (cs = node->callers; cs; cs = cs->next_caller) - if (!bitmap_bit_p (recomputed_callers, cs->caller->uid)) + if (cs->caller != node + && !bitmap_bit_p (recomputed_callers, cs->caller->uid)) { compute_inline_parameters (cs->caller); bitmap_set_bit (recomputed_callers, cs->caller->uid); @@ -4051,71 +4045,41 @@ convert_callers (struct cgraph_node *nod BITMAP_FREE (recomputed_callers); current_function_decl = old_cur_fndecl; - - if (!encountered_recursive_call) - return; - - FOR_EACH_BB (this_block) - { - gimple_stmt_iterator gsi; - - for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - tree call_fndecl; - if (gimple_code (stmt) != GIMPLE_CALL) - continue; - call_fndecl = gimple_call_fndecl (stmt); - if (call_fndecl && cgraph_get_node (call_fndecl) == node) - { - if (dump_file) - fprintf (dump_file, "Adjusting recursive call"); - ipa_modify_call_arguments (NULL, stmt, adjustments); - } - } - } - 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); + current_function_decl = new_node->decl; + push_cfun (DECL_STRUCT_FUNCTION (new_node->decl)); + ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA"); scan_function (sra_ipa_modify_expr, sra_ipa_modify_assign, replace_removed_params_ssa_names, false, 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; } @@ -4130,6 +4094,13 @@ ipa_sra_preliminary_function_checks (str { if (dump_file) fprintf (dump_file, "Function not local to this compilation unit.\n"); + return false; + } + + if (!tree_versionable_function_p (node->decl)) + { + if (dump_file) + fprintf (dump_file, "Function not local to this compilation unit.\n"); return false; } Index: gcc/Makefile.in =================================================================== --- gcc/Makefile.in.orig +++ gcc/Makefile.in @@ -3000,7 +3000,7 @@ tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_F tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \ $(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) $(IPA_PROP_H) \ $(DIAGNOSTIC_H) statistics.h $(TREE_DUMP_H) $(TIMEVAR_H) $(PARAMS_H) \ - $(TARGET_H) $(FLAGS_H) $(EXPR_H) + $(TARGET_H) $(FLAGS_H) $(EXPR_H) $(TREE_INLINE_H) tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \ $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \