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? Thanks, Richard. 2013-02-20 Richard Biener <rguent...@suse.de> * 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 afterwards. Index: gcc/tree-call-cdce.c =================================================================== *** gcc/tree-call-cdce.c (revision 196167) --- gcc/tree-call-cdce.c (working copy) *************** 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 (revision 196167) --- gcc/tree-ssa-forwprop.c (working copy) *************** 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 (revision 196167) --- gcc/tree-ssa-dce.c (working copy) *************** 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 (revision 196167) --- gcc/tree-ssa-copyrename.c (working copy) *************** 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 (revision 196167) --- gcc/tree-ssa-ccp.c (working copy) *************** do_ssa_ccp (void) *** 2105,2111 **** 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 (revision 196167) --- gcc/tree-ssanames.c (working copy) *************** struct gimple_opt_pass pass_release_ssa_ *** 456,461 **** 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! 0 /* todo_flags_finish */ } }; --- 456,461 ---- 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! TODO_remove_unused_locals /* todo_flags_finish */ } };