On Wed, 14 Oct 2020, Jan Hubicka wrote:

> Hi,
> here is updated patch with cap on number of iterations.
> I set the limit to 8 and bootstrapped it with additional assert that the
> limit is not met, it did not fire.
> 
> Bootstrapped/regtested x86_64-linux, OK?

OK.

Richard.

> gcc/ChangeLog:
> 
> 2020-10-14  Jan Hubicka  <hubi...@ucw.cz>
> 
>       * doc/invoke.texi: (ipa-jump-function-lookups): Document param.
>       * ipa-modref.c (merge_call_side_effects): Use
>       unadjusted_ptr_and_unit_offset.
>       * ipa-prop.c (unadjusted_ptr_and_unit_offset): New function.
>       * ipa-prop.h (unadjusted_ptr_and_unit_offset): Declare.
>       * params.opt: (-param-ipa-jump-function-lookups): New.
> 
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index c8281ecf502..47aa69530ab 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -13456,6 +13456,9 @@ loop in the loop nest by a given number of 
> iterations.  The strip
>  length can be changed using the @option{loop-block-tile-size}
>  parameter.
>  
> +@item ipa-jump-function-lookups
> +Specifies number of statements visited during jump function offset discovery.
> +
>  @item ipa-cp-value-list-size
>  IPA-CP attempts to track all possible values and types passed to a function's
>  parameter in order to propagate them and perform devirtualization.
> diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
> index 771a0a88f9a..a6dfe1fc401 100644
> --- a/gcc/ipa-modref.c
> +++ b/gcc/ipa-modref.c
> @@ -531,6 +531,10 @@ merge_call_side_effects (modref_summary *cur_summary,
>    for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
>      {
>        tree op = gimple_call_arg (stmt, i);
> +      bool offset_known;
> +      poly_int64 offset;
> +
> +      offset_known = unadjusted_ptr_and_unit_offset (op, &op, &offset);
>        if (TREE_CODE (op) == SSA_NAME
>         && SSA_NAME_IS_DEFAULT_DEF (op)
>         && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL)
> @@ -547,15 +551,23 @@ merge_call_side_effects (modref_summary *cur_summary,
>             index++;
>           }
>         parm_map[i].parm_index = index;
> -       parm_map[i].parm_offset_known = true;
> -       parm_map[i].parm_offset = 0;
> +       parm_map[i].parm_offset_known = offset_known;
> +       parm_map[i].parm_offset = offset;
>       }
>        else if (points_to_local_or_readonly_memory_p (op))
>       parm_map[i].parm_index = -2;
>        else
>       parm_map[i].parm_index = -1;
>        if (dump_file)
> -     fprintf (dump_file, " %i", parm_map[i].parm_index);
> +     {
> +       fprintf (dump_file, " %i", parm_map[i].parm_index);
> +       if (parm_map[i].parm_offset_known)
> +         {
> +           fprintf (dump_file, " offset:");
> +           print_dec ((poly_int64_pod)parm_map[i].parm_offset,
> +                      dump_file, SIGNED);
> +         }
> +     }
>      }
>    if (dump_file)
>      fprintf (dump_file, "\n");
> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
> index 2d09d913051..cf3da6a6568 100644
> --- a/gcc/ipa-prop.c
> +++ b/gcc/ipa-prop.c
> @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "domwalk.h"
>  #include "builtins.h"
>  #include "tree-cfgcleanup.h"
> +#include "options.h"
>  
>  /* Function summary where the parameter infos are actually stored. */
>  ipa_node_params_t *ipa_node_params_sum = NULL;
> @@ -1222,6 +1223,73 @@ load_from_unmodified_param_or_agg (struct 
> ipa_func_body_info *fbi,
>    return index;
>  }
>  
> +/* Walk pointer adjustemnts from OP (such as POINTER_PLUS and ADDR_EXPR)
> +   to find original pointer.  Initialize RET to the pointer which results 
> from
> +   the walk.
> +   If offset is known return true and initialize OFFSET_RET.  */
> +
> +bool
> +unadjusted_ptr_and_unit_offset (tree op, tree *ret, poly_int64 *offset_ret)
> +{
> +  poly_int64 offset = 0;
> +  bool offset_known = true;
> +  int i;
> +
> +  for (i = 0; i < param_ipa_jump_function_lookups; i++)
> +    {
> +      if (TREE_CODE (op) == ADDR_EXPR)
> +     {
> +       poly_int64 extra_offset = 0;
> +       tree base = get_addr_base_and_unit_offset (TREE_OPERAND (op, 0),
> +                                                  &offset);
> +       if (!base)
> +         {
> +           base = get_base_address (TREE_OPERAND (op, 0));
> +           if (TREE_CODE (base) != MEM_REF)
> +             break;
> +           offset_known = false;
> +         }
> +       else
> +         {
> +           if (TREE_CODE (base) != MEM_REF)
> +             break;
> +           offset += extra_offset;
> +         }
> +       op = TREE_OPERAND (base, 0);
> +       if (mem_ref_offset (base).to_shwi (&extra_offset))
> +         offset += extra_offset;
> +       else
> +         offset_known = false;
> +     }
> +      else if (TREE_CODE (op) == SSA_NAME
> +            && !SSA_NAME_IS_DEFAULT_DEF (op))
> +     {
> +       gimple *pstmt = SSA_NAME_DEF_STMT (op);
> +
> +       if (gimple_assign_single_p (pstmt))
> +         op = gimple_assign_rhs1 (pstmt);
> +       else if (is_gimple_assign (pstmt)
> +                && gimple_assign_rhs_code (pstmt) == POINTER_PLUS_EXPR)
> +         {
> +           poly_int64 extra_offset = 0;
> +           if (ptrdiff_tree_p (gimple_assign_rhs2 (pstmt),
> +               &extra_offset))
> +             offset += extra_offset;
> +           else
> +             offset_known = false;
> +           op = gimple_assign_rhs1 (pstmt);
> +         }
> +       else
> +         break;
> +     }
> +      else
> +     break;
> +    }
> +  *ret = op;
> +  *offset_ret = offset;
> +  return offset_known;
> +}
> +
>  /* Given that an actual argument is an SSA_NAME (given in NAME) and is a 
> result
>     of an assignment statement STMT, try to determine whether we are actually
>     handling any of the following cases and construct an appropriate jump
> diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
> index 8b2edf6300c..0bbbbf9bd9f 100644
> --- a/gcc/ipa-prop.h
> +++ b/gcc/ipa-prop.h
> @@ -1144,6 +1144,8 @@ void ipa_dump_param (FILE *, class ipa_node_params 
> *info, int i);
>  void ipa_release_body_info (struct ipa_func_body_info *);
>  tree ipa_get_callee_param_type (struct cgraph_edge *e, int i);
>  bool ipcp_get_parm_bits (tree, tree *, widest_int *);
> +bool unadjusted_ptr_and_unit_offset (tree op, tree *ret,
> +                                  poly_int64 *offset_ret);
>  
>  /* From tree-sra.c:  */
>  tree build_ref_for_offset (location_t, tree, poly_int64, bool, tree,
> diff --git a/gcc/params.opt b/gcc/params.opt
> index d770c55143b..ec69ba04eaf 100644
> --- a/gcc/params.opt
> +++ b/gcc/params.opt
> @@ -253,6 +253,10 @@ The size of translation unit that IPA-CP pass considers 
> large.
>  Common Joined UInteger Var(param_ipa_cp_value_list_size) Init(8) Param 
> Optimization
>  Maximum size of a list of values associated with each parameter for 
> interprocedural constant propagation.
>  
> +-param-ipa-jump-function-lookups=
> +Common Joined UInteger Var(param_ipa_jump_function_lookups) Init(8) Param 
> Optimization
> +Maximum number of statements visited during jump function offset discovery
> +
>  -param=ipa-max-aa-steps=
>  Common Joined UInteger Var(param_ipa_max_aa_steps) Init(25000) Param 
> Optimization
>  Maximum number of statements that will be visited by IPA formal parameter 
> analysis based on alias analysis in any given function.
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imend

Reply via email to