From patchwork Wed Feb 20 13:13:57 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 222078 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 0A04E2C007E for ; Thu, 21 Feb 2013 00:14:29 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1361970870; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Date: From:To:Cc:Subject:In-Reply-To:Message-ID:References:User-Agent: MIME-Version:Content-Type:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=+iFzkNiyQ0YMueNpFFzPY0UOEb0=; b=cFutWi6U136YbjN bLPhjOb5KCb2Tv9LjNPNvA/0K1GcFUNRttpc0K+owEvzAeXwTxf9GlEn5JaGWtmM CApaDxZhxZzv5RaSMqPFjNH5ErjHZsZZfkjlRvjKA0DVXgaLzHr5a2NFE1usAg2i ufSEzlUiz3gFd6GoRjvM1bdD+/9Y= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Date:From:To:Cc:Subject:In-Reply-To:Message-ID:References:User-Agent:MIME-Version:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=vBvu2m89jV4uX2foqGIr2jsmLey4IBJs1WuT/cgwb94QoHVVnnUkt7aStIjI7O M68mwSls7ihPDo5gzyNv0/WimKLBVJirAJ8QAdgJhEVwoXz77+n8n0bZKD0ysu7e v/Y+x9L+peUJxV8lfQkYyZdDmcJtsjTZJGJNya/dkB79I=; Received: (qmail 15296 invoked by alias); 20 Feb 2013 13:14:11 -0000 Received: (qmail 15260 invoked by uid 22791); 20 Feb 2013 13:14:10 -0000 X-SWARE-Spam-Status: No, hits=-6.5 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, TW_FN 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; Wed, 20 Feb 2013 13:14:00 +0000 Received: from relay1.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 0FE96A51D9; Wed, 20 Feb 2013 14:13:58 +0100 (CET) Date: Wed, 20 Feb 2013 14:13:57 +0100 (CET) From: Richard Biener To: gcc-patches@gcc.gnu.org Cc: Jan Hubicka , Jakub Jelinek Subject: Re: [PATCH][RFC] Less TODO_remove_unused_locals In-Reply-To: Message-ID: References: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 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 On Wed, 20 Feb 2013, Richard Biener wrote: > > Hunting for the "we're getting slower" bits I noticed that > TODO_remove_unused_locals is a big part of execute_function_todo > (and accounts for 1% of compile-time of ac.f90). > The following patch removes most of the remove_unused_locals > calls based on the fact that with anonymous SSA names now available > we should never create new locals (wishful thinking of course ...) > and the important places to remove unused stuff are driven by > 1) avoid creating yet another copy of the unused stuff, thus do > it before inlining, on the callee; 2) avoid pinning unused memory > while we operate on other function bodies, thus, do it at the end > of non-IPA pass pipelines > > In the end this asks for more explicit placement and thus a > real pass ... but the following should be enough as a RFC and > be good enough for 4.8. > > We keep doing remove_unused_locals after going into SSA > and now after releasing unused SSA names (that should suffice > to achieve 1) for early and IPA inlining and for 2) pre-IPA. > post-IPA we perform it after IPA inline transform and at right > before expanding to RTL (avoid expanding unused stack vars). > > I'm scheduling a bootstrap & regtest. > > Ok for trunk? As requested, here is some statistics. stage2 gcc/ compiled with -fdump-statistics-stats, summed over all files with clear_unused_block_pointer (); gives us before the patch (first number is the static pass number, last is the pass name, the number of removed vars is second): 20 323409 ssa 23 131864 einline 25 29311 copyrename 26 2178 ccp 27 9771 forwprop 30 29 fre 31 60212 copyprop 33 13849 cddce 35 10 tailr 39 355 local-pure-const 40 4347 fnsplit ----- subtotal 575335 52 46056 inline 59 10834 copyrename 61 3721 ccp 62 83 forwprop 66 826 fre 67 4821 copyprop 69 5017 vrp 70 24764 dce 73 2 ifcombine 74 662 phiopt 76 137 ch 80 2909 copyrename 81 212 dom 82 1472 phicprop 85 1322 dce 86 51 forwprop 87 4 phiopt 90 48 ccp 91 19 copyprop 95 6 pre 101 5 lim 102 883 copyprop 103 3082 dceloop 125 2 loopdone 129 589 vrp 131 49 dom 132 145 phicprop 133 316 cddce 137 5 forwprop 138 1 phiopt 142 458 copyrename 168 2955 optimized -------- total 686791 and after the patch, adjusted as below (eh, I failed to notice we schedule remove_unused_locals if TODO_cleanup_cfg did sth...): 20 323396 ssa 23 107755 einline 41 135260 release_ssa ------ subtotal 566411 52 47513 inline 168 61713 optimized -------- total 675637 as expected the most unused locals are removed before final inlining. I suppose the difference in (sub-)total is because patched we copy less unused locals due to the extra remove-unused locals at release_ssa time. I can't explain the 13 difference for into-SSA. I suppose I should also count the number of remaining locals ... Scheduled for re-bootstrap / regtest. Thanks, Richard. 2013-02-20 Richard Biener * tree-call-cdce.c (tree_call_cdce): Do not remove unused locals. * tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Likewise. * tree-ssa-dce.c (perform_tree_ssa_dce): Likewise. * tree-ssa-copyrename.c (copy_rename_partition_coalesce): Do not return anything. (rename_ssa_copies): Do not remove unused locals. * tree-ssa-ccp.c (do_ssa_ccp): Likewise. * tree-ssanames.c (pass_release_ssa_names): Remove unused locals first. * passes.c (execute_function_todo): Do not schedule unused locals removal if cleanup_tree_cfg did something. * tree-ssa-live.c (remove_unused_locals): Dump statistics about the number of removed locals. Index: gcc/tree-call-cdce.c =================================================================== *** gcc/tree-call-cdce.c.orig 2013-02-20 12:49:24.000000000 +0100 --- gcc/tree-call-cdce.c 2013-02-20 12:51:00.528421709 +0100 *************** tree_call_cdce (void) *** 898,908 **** /* As we introduced new control-flow we need to insert PHI-nodes for the call-clobbers of the remaining call. */ mark_virtual_operands_for_renaming (cfun); ! return (TODO_update_ssa | TODO_cleanup_cfg | TODO_ggc_collect ! | TODO_remove_unused_locals); } ! else ! return 0; } static bool --- 898,907 ---- /* As we introduced new control-flow we need to insert PHI-nodes for the call-clobbers of the remaining call. */ mark_virtual_operands_for_renaming (cfun); ! return TODO_update_ssa; } ! ! return 0; } static bool Index: gcc/tree-ssa-forwprop.c =================================================================== *** gcc/tree-ssa-forwprop.c.orig 2013-02-20 12:49:24.000000000 +0100 --- gcc/tree-ssa-forwprop.c 2013-02-20 12:51:00.556422021 +0100 *************** ssa_forward_propagate_and_combine (void) *** 2936,2942 **** && forward_propagate_addr_expr (lhs, rhs)) { release_defs (stmt); - todoflags |= TODO_remove_unused_locals; gsi_remove (&gsi, true); } else --- 2936,2941 ---- *************** ssa_forward_propagate_and_combine (void) *** 2961,2967 **** off))))) { release_defs (stmt); - todoflags |= TODO_remove_unused_locals; gsi_remove (&gsi, true); } else if (is_gimple_min_invariant (rhs)) --- 2960,2965 ---- Index: gcc/tree-ssa-dce.c =================================================================== *** gcc/tree-ssa-dce.c.orig 2013-02-20 12:49:24.000000000 +0100 --- gcc/tree-ssa-dce.c 2013-02-20 12:51:00.579422275 +0100 *************** perform_tree_ssa_dce (bool aggressive) *** 1607,1616 **** free_edge_list (el); if (something_changed) ! return (TODO_update_ssa | TODO_cleanup_cfg | TODO_ggc_collect ! | TODO_remove_unused_locals); ! else ! return 0; } /* Pass entry points. */ --- 1607,1614 ---- free_edge_list (el); if (something_changed) ! return TODO_update_ssa | TODO_cleanup_cfg; ! return 0; } /* Pass entry points. */ Index: gcc/tree-ssa-copyrename.c =================================================================== *** gcc/tree-ssa-copyrename.c.orig 2013-02-20 12:49:24.000000000 +0100 --- gcc/tree-ssa-copyrename.c 2013-02-20 12:55:59.374738833 +0100 *************** static struct *** 113,119 **** /* Coalesce the partitions in MAP representing VAR1 and VAR2 if it is valid. Choose a representative for the partition, and send debug info to DEBUG. */ ! static bool copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) { int p1, p2, p3; --- 113,119 ---- /* Coalesce the partitions in MAP representing VAR1 and VAR2 if it is valid. Choose a representative for the partition, and send debug info to DEBUG. */ ! static void copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) { int p1, p2, p3; *************** copy_rename_partition_coalesce (var_map *** 146,152 **** { if (debug) fprintf (debug, " : Already coalesced.\n"); ! return false; } rep1 = partition_to_var (map, p1); --- 146,152 ---- { if (debug) fprintf (debug, " : Already coalesced.\n"); ! return; } rep1 = partition_to_var (map, p1); *************** copy_rename_partition_coalesce (var_map *** 154,160 **** root1 = SSA_NAME_VAR (rep1); root2 = SSA_NAME_VAR (rep2); if (!root1 && !root2) ! return false; /* Don't coalesce if one of the variables occurs in an abnormal PHI. */ abnorm = (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rep1) --- 154,160 ---- root1 = SSA_NAME_VAR (rep1); root2 = SSA_NAME_VAR (rep2); if (!root1 && !root2) ! return; /* Don't coalesce if one of the variables occurs in an abnormal PHI. */ abnorm = (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rep1) *************** copy_rename_partition_coalesce (var_map *** 163,169 **** { if (debug) fprintf (debug, " : Abnormal PHI barrier. No coalesce.\n"); ! return false; } /* Partitions already have the same root, simply merge them. */ --- 163,169 ---- { if (debug) fprintf (debug, " : Abnormal PHI barrier. No coalesce.\n"); ! return; } /* Partitions already have the same root, simply merge them. */ *************** copy_rename_partition_coalesce (var_map *** 172,178 **** p1 = partition_union (map->var_partition, p1, p2); if (debug) fprintf (debug, " : Same root, coalesced --> P%d.\n", p1); ! return false; } /* Never attempt to coalesce 2 different parameters. */ --- 172,178 ---- p1 = partition_union (map->var_partition, p1, p2); if (debug) fprintf (debug, " : Same root, coalesced --> P%d.\n", p1); ! return; } /* Never attempt to coalesce 2 different parameters. */ *************** copy_rename_partition_coalesce (var_map *** 181,187 **** { if (debug) fprintf (debug, " : 2 different PARM_DECLS. No coalesce.\n"); ! return false; } if ((root1 && TREE_CODE (root1) == RESULT_DECL) --- 181,187 ---- { if (debug) fprintf (debug, " : 2 different PARM_DECLS. No coalesce.\n"); ! return; } if ((root1 && TREE_CODE (root1) == RESULT_DECL) *************** copy_rename_partition_coalesce (var_map *** 189,195 **** { if (debug) fprintf (debug, " : One root a RESULT_DECL. No coalesce.\n"); ! return false; } ign1 = !root1 || (TREE_CODE (root1) == VAR_DECL && DECL_IGNORED_P (root1)); --- 189,195 ---- { if (debug) fprintf (debug, " : One root a RESULT_DECL. No coalesce.\n"); ! return; } ign1 = !root1 || (TREE_CODE (root1) == VAR_DECL && DECL_IGNORED_P (root1)); *************** copy_rename_partition_coalesce (var_map *** 206,212 **** { if (debug) fprintf (debug, " : 2 different USER vars. No coalesce.\n"); ! return false; } else ign2 = true; --- 206,212 ---- { if (debug) fprintf (debug, " : 2 different USER vars. No coalesce.\n"); ! return; } else ign2 = true; *************** copy_rename_partition_coalesce (var_map *** 220,226 **** { if (debug) fprintf (debug, " : 2 default defs. No coalesce.\n"); ! return false; } else { --- 220,226 ---- { if (debug) fprintf (debug, " : 2 default defs. No coalesce.\n"); ! return; } else { *************** copy_rename_partition_coalesce (var_map *** 240,246 **** { if (debug) fprintf (debug, " : Choosen variable has no root. No coalesce.\n"); ! return false; } /* Don't coalesce if the new chosen root variable would be read-only. --- 240,246 ---- { if (debug) fprintf (debug, " : Choosen variable has no root. No coalesce.\n"); ! return; } /* Don't coalesce if the new chosen root variable would be read-only. *************** copy_rename_partition_coalesce (var_map *** 253,259 **** { if (debug) fprintf (debug, " : Readonly variable. No coalesce.\n"); ! return false; } /* Don't coalesce if the two variables aren't type compatible . */ --- 253,259 ---- { if (debug) fprintf (debug, " : Readonly variable. No coalesce.\n"); ! return; } /* Don't coalesce if the two variables aren't type compatible . */ *************** copy_rename_partition_coalesce (var_map *** 266,272 **** { if (debug) fprintf (debug, " : Incompatible types. No coalesce.\n"); ! return false; } /* Merge the two partitions. */ --- 266,272 ---- { if (debug) fprintf (debug, " : Incompatible types. No coalesce.\n"); ! return; } /* Merge the two partitions. */ *************** copy_rename_partition_coalesce (var_map *** 288,294 **** TDF_SLIM); fprintf (debug, "\n"); } - return true; } --- 288,293 ---- *************** rename_ssa_copies (void) *** 308,314 **** gimple stmt, phi; unsigned x; FILE *debug; - bool updated = false; memset (&stats, 0, sizeof (stats)); --- 307,312 ---- *************** rename_ssa_copies (void) *** 330,336 **** tree lhs = gimple_assign_lhs (stmt); tree rhs = gimple_assign_rhs1 (stmt); ! updated |= copy_rename_partition_coalesce (map, lhs, rhs, debug); } } } --- 328,334 ---- tree lhs = gimple_assign_lhs (stmt); tree rhs = gimple_assign_rhs1 (stmt); ! copy_rename_partition_coalesce (map, lhs, rhs, debug); } } } *************** rename_ssa_copies (void) *** 358,365 **** { tree arg = PHI_ARG_DEF (phi, i); if (TREE_CODE (arg) == SSA_NAME) ! updated |= copy_rename_partition_coalesce (map, res, arg, ! debug); } /* Else if all arguments are in the same partition try to merge it with the result. */ --- 356,363 ---- { tree arg = PHI_ARG_DEF (phi, i); if (TREE_CODE (arg) == SSA_NAME) ! copy_rename_partition_coalesce (map, res, arg, ! debug); } /* Else if all arguments are in the same partition try to merge it with the result. */ *************** rename_ssa_copies (void) *** 390,398 **** } } if (all_p_same == 1) ! updated |= copy_rename_partition_coalesce (map, res, ! PHI_ARG_DEF (phi, 0), ! debug); } } } --- 388,396 ---- } } if (all_p_same == 1) ! copy_rename_partition_coalesce (map, res, ! PHI_ARG_DEF (phi, 0), ! debug); } } } *************** rename_ssa_copies (void) *** 426,432 **** statistics_counter_event (cfun, "copies coalesced", stats.coalesced); delete_var_map (map); ! return updated ? TODO_remove_unused_locals : 0; } /* Return true if copy rename is to be performed. */ --- 424,430 ---- statistics_counter_event (cfun, "copies coalesced", stats.coalesced); delete_var_map (map); ! return 0; } /* Return true if copy rename is to be performed. */ Index: gcc/tree-ssa-ccp.c =================================================================== *** gcc/tree-ssa-ccp.c.orig 2013-02-20 12:49:24.000000000 +0100 --- gcc/tree-ssa-ccp.c 2013-02-20 12:51:00.580422285 +0100 *************** do_ssa_ccp (void) *** 2108,2114 **** ccp_initialize (); ssa_propagate (ccp_visit_stmt, ccp_visit_phi_node); if (ccp_finalize ()) ! todo = (TODO_cleanup_cfg | TODO_update_ssa | TODO_remove_unused_locals); free_dominance_info (CDI_DOMINATORS); return todo; } --- 2108,2114 ---- ccp_initialize (); ssa_propagate (ccp_visit_stmt, ccp_visit_phi_node); if (ccp_finalize ()) ! todo = (TODO_cleanup_cfg | TODO_update_ssa); free_dominance_info (CDI_DOMINATORS); return todo; } Index: gcc/tree-ssanames.c =================================================================== *** gcc/tree-ssanames.c.orig 2013-02-20 12:49:24.000000000 +0100 --- gcc/tree-ssanames.c 2013-02-20 12:51:29.583743873 +0100 *************** struct gimple_opt_pass pass_release_ssa_ *** 455,461 **** PROP_ssa, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ ! 0, /* todo_flags_start */ ! 0 /* todo_flags_finish */ } }; --- 455,461 ---- PROP_ssa, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ ! TODO_remove_unused_locals, /* todo_flags_start */ ! 0 /* todo_flags_finish */ } }; Index: gcc/passes.c =================================================================== *** gcc/passes.c.orig 2013-02-11 11:41:01.000000000 +0100 --- gcc/passes.c 2013-02-20 12:54:45.700917657 +0100 *************** execute_function_todo (void *data) *** 1918,1927 **** /* Always cleanup the CFG before trying to update SSA. */ if (flags & TODO_cleanup_cfg) { ! bool cleanup = cleanup_tree_cfg (); ! ! if (cleanup && (cfun->curr_properties & PROP_ssa)) ! flags |= TODO_remove_unused_locals; /* When cleanup_tree_cfg merges consecutive blocks, it may perform some simplistic propagation when removing single --- 1918,1924 ---- /* Always cleanup the CFG before trying to update SSA. */ if (flags & TODO_cleanup_cfg) { ! cleanup_tree_cfg (); /* When cleanup_tree_cfg merges consecutive blocks, it may perform some simplistic propagation when removing single Index: gcc/tree-ssa-live.c =================================================================== *** gcc/tree-ssa-live.c.orig 2013-01-11 10:54:52.000000000 +0100 --- gcc/tree-ssa-live.c 2013-02-20 12:55:30.066411897 +0100 *************** remove_unused_locals (void) *** 889,895 **** dstidx++; } if (dstidx != num) ! cfun->local_decls->truncate (dstidx); remove_unused_scope_block_p (DECL_INITIAL (current_function_decl)); clear_unused_block_pointer (); --- 889,898 ---- dstidx++; } if (dstidx != num) ! { ! statistics_counter_event (cfun, "unused VAR_DECLs removed", num - dstidx); ! cfun->local_decls->truncate (dstidx); ! } remove_unused_scope_block_p (DECL_INITIAL (current_function_decl)); clear_unused_block_pointer (); Index: gcc/tree-ssa-live.c =================================================================== --- gcc/tree-ssa-live.c (revision 196170) +++ gcc/tree-ssa-live.c (working copy) @@ -889,7 +889,10 @@ remove_unused_locals (void) dstidx++; } if (dstidx != num) - cfun->local_decls->truncate (dstidx); + { + statistics_counter_event (cfun, "unused VAR_DECLs removed", num - dstidx); + cfun->local_decls->truncate (dstidx); + } remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));