Jan Hubicka <hubi...@ucw.cz> 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.  */


Reply via email to