From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4389 invoked by alias); 1 Aug 2013 13:56:01 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 4380 invoked by uid 89); 1 Aug 2013 13:56:00 -0000 X-Spam-SWARE-Status: No, score=2.1 required=5.0 tests=BAYES_99,FREEMAIL_FROM,KHOP_THREADED,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE,RDNS_NONE,SPF_PASS autolearn=no version=3.3.1 Received: from Unknown (HELO mail-ea0-f182.google.com) (209.85.215.182) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Thu, 01 Aug 2013 13:55:59 +0000 Received: by mail-ea0-f182.google.com with SMTP id o10so1029441eaj.27 for ; Thu, 01 Aug 2013 06:55:51 -0700 (PDT) X-Received: by 10.15.99.2 with SMTP id bk2mr1555349eeb.76.1375365350964; Thu, 01 Aug 2013 06:55:50 -0700 (PDT) Received: from noname (p5495B7A8.dip0.t-ipconnect.de. [84.149.183.168]) by mx.google.com with ESMTPSA id c3sm4545403eev.3.2013.08.01.06.55.48 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 01 Aug 2013 06:55:50 -0700 (PDT) User-Agent: K-9 Mail for Android In-Reply-To: <20130801131135.GB22179@kam.mff.cuni.cz> References: <20130801131135.GB22179@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: Re: Do not use PARM_DECLs in ipa-cp and ipa-prop From: Richard Biener Date: Thu, 01 Aug 2013 13:56:00 -0000 To: Jan Hubicka ,gcc-patches@gcc.gnu.org,mjambor@suse.cz Message-ID: X-SW-Source: 2013-08/txt/msg00029.txt.bz2 Jan Hubicka wrote: >Hi, >this is preparation work to move DECL_ARGUMENTS and DECL_RESULT into >function >sections during WPA. Even with some work to release unused ones, there >are 4M >of PARM_DECLs and 2M of RESULT_DECLs streamed during LTO (for 6M of >function_decls) making them one of the most common nodes. > >This patch makes ipa-cp and ipa-prop to not use DECL_ARGUMENTS during >WPA >stage. this only needed to tamn debug info, move logic doing casts >from >get_replacement_map to tree_function_versioning and stream move_cost >that is >computed form parm type. > >Martin, does this patch look OK? What about uses in jump functions, like &parm? Are those sufficiently non-treeish already? Richard. >Honza > > * ipa-cp.c (gather_context_independent_values): Use >ipa_get_param_move_cost. > (get_replacement_map): Remove PARAM; move parameter folding into >tree-inline.c > (create_specialized_node): Update. > * ipa-prop.c (ipa_populate_param_decls): Do not look for origins; > assert that we have gimple body; update move_cost. > (count_formal_params): Assert that we have gimple body. > (ipa_alloc_node_params): Break out from ... > (ipa_initialize_node_params): ... here. > (ipa_get_vector_of_formal_parms): ICE when used in WPA. > (ipa_write_node_info): Stream move costs. > (ipa_read_node_info): Read move costs. > (ipa_update_after_lto_read): Do not recompute node params. > * ipa-prop.h (ipa_param_descriptor): Add move_cost. > (ipa_get_param): Check we are not in WPA. > (ipa_get_param_move_cost): New. > * tree-inline.c (tree_function_versioning): Fold replacement as >needed. >Index: ipa-cp.c >=================================================================== >*** ipa-cp.c (revision 201291) >--- ipa-cp.c (working copy) >*************** gather_context_independent_values (struc >*** 1758,1770 **** > } > else if (removable_params_cost > && !ipa_is_param_used (info, i)) >! *removable_params_cost >! += estimate_move_cost (TREE_TYPE (ipa_get_param (info, i))); > } > else if (removable_params_cost > && !ipa_is_param_used (info, i)) > *removable_params_cost >! += estimate_move_cost (TREE_TYPE (ipa_get_param (info, i))); > > if (known_aggs) > { >--- 1758,1769 ---- > } > else if (removable_params_cost > && !ipa_is_param_used (info, i)) >! *removable_params_cost += ipa_get_param_move_cost (info, i); > } > else if (removable_params_cost > && !ipa_is_param_used (info, i)) > *removable_params_cost >! += ipa_get_param_move_cost (info, i); > > if (known_aggs) > { >*************** gather_edges_for_value (struct ipcp_valu >*** 2480,2515 **** > Return it or NULL if for some reason it cannot be created. */ > > static struct ipa_replace_map * >! get_replacement_map (tree value, tree parm, int parm_num) > { >- tree req_type = TREE_TYPE (parm); > struct ipa_replace_map *replace_map; > >- if (!useless_type_conversion_p (req_type, TREE_TYPE (value))) >- { >- if (fold_convertible_p (req_type, value)) >- value = fold_build1 (NOP_EXPR, req_type, value); >- else if (TYPE_SIZE (req_type) == TYPE_SIZE (TREE_TYPE (value))) >- value = fold_build1 (VIEW_CONVERT_EXPR, req_type, value); >- else >- { >- if (dump_file) >- { >- fprintf (dump_file, " const "); >- print_generic_expr (dump_file, value, 0); >- fprintf (dump_file, " can't be converted to param "); >- print_generic_expr (dump_file, parm, 0); >- fprintf (dump_file, "\n"); >- } >- return NULL; >- } >- } > > replace_map = ggc_alloc_ipa_replace_map (); > if (dump_file) > { >! fprintf (dump_file, " replacing param "); >! print_generic_expr (dump_file, parm, 0); > fprintf (dump_file, " with const "); > print_generic_expr (dump_file, value, 0); > fprintf (dump_file, "\n"); >--- 2479,2494 ---- > Return it or NULL if for some reason it cannot be created. */ > > static struct ipa_replace_map * >! get_replacement_map (tree value, int parm_num) > { > struct ipa_replace_map *replace_map; > > > replace_map = ggc_alloc_ipa_replace_map (); > if (dump_file) > { >! fprintf (dump_file, " replacing param %i", parm_num); >! > fprintf (dump_file, " with const "); > print_generic_expr (dump_file, value, 0); > fprintf (dump_file, "\n"); >*************** create_specialized_node (struct cgraph_n >*** 2697,2703 **** > { > struct ipa_replace_map *replace_map; > >! replace_map = get_replacement_map (t, ipa_get_param (info, i), i); > if (replace_map) > vec_safe_push (replace_trees, replace_map); > } >--- 2676,2682 ---- > { > struct ipa_replace_map *replace_map; > >! replace_map = get_replacement_map (t, i); > if (replace_map) > vec_safe_push (replace_trees, replace_map); > } >Index: ipa-prop.c >=================================================================== >*** ipa-prop.c (revision 201291) >--- ipa-prop.c (working copy) >*************** ipa_populate_param_decls (struct cgraph_ >*** 130,145 **** > tree parm; > int param_num; > >- /* We do not copy DECL_ARGUMENTS to virtual clones. */ >- while (node->clone_of) >- node = node->clone_of; >- > fndecl = node->symbol.decl; > fnargs = DECL_ARGUMENTS (fndecl); > param_num = 0; > for (parm = fnargs; parm; parm = DECL_CHAIN (parm)) > { > descriptors[param_num].decl = parm; > param_num++; > } > } >--- 130,143 ---- > tree parm; > int param_num; > > fndecl = node->symbol.decl; >+ gcc_assert (gimple_has_body_p (fndecl)); > fnargs = DECL_ARGUMENTS (fndecl); > param_num = 0; > for (parm = fnargs; parm; parm = DECL_CHAIN (parm)) > { > descriptors[param_num].decl = parm; >+ descriptors[param_num].move_cost = estimate_move_cost >(TREE_TYPE (parm)); > param_num++; > } > } >*************** count_formal_params (tree fndecl) >*** 151,156 **** >--- 149,155 ---- > { > tree parm; > int count = 0; >+ gcc_assert (gimple_has_body_p (fndecl)); > > for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm)) > count++; >*************** count_formal_params (tree fndecl) >*** 158,163 **** >--- 157,174 ---- > return count; > } > >+ /* Initialize the ipa_node_params structure associated with NODE >+ to hold PARAM_COUNT parameters. */ >+ >+ void >+ ipa_alloc_node_params (struct cgraph_node *node, int param_count) >+ { >+ struct ipa_node_params *info = IPA_NODE_REF (node); >+ >+ if (!info->descriptors.exists () && param_count) >+ info->descriptors.safe_grow_cleared (param_count); >+ } >+ >/* Initialize the ipa_node_params structure associated with NODE by >counting > the function parameters, creating the descriptors and populating their > param_decls. */ >*************** ipa_initialize_node_params (struct cgrap >*** 169,183 **** > > if (!info->descriptors.exists ()) > { >! int param_count; >! gcc_assert (!node->clone_of); >! >! param_count = count_formal_params (node->symbol.decl); >! if (param_count) >! { >! info->descriptors.safe_grow_cleared (param_count); >! ipa_populate_param_decls (node, info->descriptors); >! } > } > } > >--- 180,187 ---- > > if (!info->descriptors.exists ()) > { >! ipa_alloc_node_params (node, count_formal_params >(node->symbol.decl)); >! ipa_populate_param_decls (node, info->descriptors); > } > } > >*************** ipa_get_vector_of_formal_parms (tree fnd >*** 3064,3069 **** >--- 3068,3074 ---- > int count; > tree parm; > >+ gcc_assert (!flag_wpa); > count = count_formal_params (fndecl); > args.create (count); > for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm)) >*************** ipa_write_node_info (struct output_block >*** 3856,3861 **** >--- 3861,3869 ---- > node_ref = lto_symtab_encoder_encode (encoder, (symtab_node) node); > streamer_write_uhwi (ob, node_ref); > >+ streamer_write_uhwi (ob, ipa_get_param_count (info)); >+ for (j = 0; j < ipa_get_param_count (info); j++) >+ streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j)); > bp = bitpack_create (ob->main_stream); > gcc_assert (info->uses_analysis_done > || ipa_get_param_count (info) == 0); >*************** ipa_read_node_info (struct lto_input_blo >*** 3896,3903 **** > struct cgraph_edge *e; > struct bitpack_d bp; > >! ipa_initialize_node_params (node); > > bp = streamer_read_bitpack (ib); > if (ipa_get_param_count (info) != 0) > info->uses_analysis_done = true; >--- 3904,3914 ---- > struct cgraph_edge *e; > struct bitpack_d bp; > >! ipa_alloc_node_params (node, streamer_read_uhwi (ib)); > >+ for (k = 0; k < ipa_get_param_count (info); k++) >+ info->descriptors[k].move_cost = streamer_read_uhwi (ib); >+ > bp = streamer_read_bitpack (ib); > if (ipa_get_param_count (info) != 0) > info->uses_analysis_done = true; >*************** ipa_prop_read_jump_functions (void) >*** 4049,4061 **** > void > ipa_update_after_lto_read (void) > { >- struct cgraph_node *node; >- > ipa_check_create_node_params (); > ipa_check_create_edge_args (); >- >- FOR_EACH_DEFINED_FUNCTION (node) >- ipa_initialize_node_params (node); > } > > void >--- 4060,4067 ---- >Index: ipa-prop.h >=================================================================== >*** ipa-prop.h (revision 201291) >--- ipa-prop.h (working copy) >*************** struct ipa_param_descriptor >*** 320,325 **** >--- 320,326 ---- >says how many there are. If any use could not be described by means of > ipa-prop structures, this is IPA_UNDESCRIBED_USE. */ > int controlled_uses; >+ unsigned int move_cost : 31; > /* The parameter is used. */ > unsigned used : 1; > }; >*************** ipa_get_param_count (struct ipa_node_par >*** 377,385 **** >--- 378,396 ---- > static inline tree > ipa_get_param (struct ipa_node_params *info, int i) > { >+ gcc_checking_assert (!flag_wpa); > return info->descriptors[i].decl; > } > >+ /* Return the move cost of Ith formal parameter of the function >corresponding >+ to INFO. */ >+ >+ static inline int >+ ipa_get_param_move_cost (struct ipa_node_params *info, int i) >+ { >+ return info->descriptors[i].move_cost; >+ } >+ >/* Set the used flag corresponding to the Ith formal parameter of the >function > associated with INFO to VAL. */ > >Index: tree-inline.c >=================================================================== >*** tree-inline.c (revision 201291) >--- tree-inline.c (working copy) >*************** tree_function_versioning (tree old_decl, >*** 5146,5162 **** > { > int i = replace_info->parm_num; > tree parm; > for (parm = DECL_ARGUMENTS (old_decl); i; parm = DECL_CHAIN (parm)) > i --; > replace_info->old_tree = parm; > } >- gcc_assert (TREE_CODE (replace_info->old_tree) == PARM_DECL); >- init = setup_one_parameter (&id, replace_info->old_tree, >- replace_info->new_tree, id.src_fn, >- NULL, >- &vars); >- if (init) >- init_stmts.safe_push (init); > } > } > /* Copy the function's arguments. */ >--- 5150,5192 ---- > { > int i = replace_info->parm_num; > tree parm; >+ tree req_type; >+ > for (parm = DECL_ARGUMENTS (old_decl); i; parm = DECL_CHAIN (parm)) > i --; > replace_info->old_tree = parm; >+ req_type = TREE_TYPE (parm); >+ if (!useless_type_conversion_p (req_type, TREE_TYPE >(replace_info->new_tree))) >+ { >+ if (fold_convertible_p (req_type, replace_info->new_tree)) >+ replace_info->new_tree = fold_build1 (NOP_EXPR, req_type, >replace_info->new_tree); >+ else if (TYPE_SIZE (req_type) == TYPE_SIZE (TREE_TYPE >(replace_info->new_tree))) >+ replace_info->new_tree = fold_build1 (VIEW_CONVERT_EXPR, >req_type, replace_info->new_tree); >+ else >+ { >+ if (dump_file) >+ { >+ fprintf (dump_file, " const "); >+ print_generic_expr (dump_file, replace_info->new_tree, 0); >+ fprintf (dump_file, " can't be converted to param "); >+ print_generic_expr (dump_file, parm, 0); >+ fprintf (dump_file, "\n"); >+ } >+ replace_info->old_tree = NULL; >+ } >+ } >+ } >+ else >+ gcc_assert (TREE_CODE (replace_info->old_tree) == PARM_DECL); >+ if (replace_info->old_tree) >+ { >+ init = setup_one_parameter (&id, replace_info->old_tree, >+ replace_info->new_tree, id.src_fn, >+ NULL, >+ &vars); >+ if (init) >+ init_stmts.safe_push (init); > } > } > } > /* Copy the function's arguments. */