From c7b6a7587f215e913cec9ed523bf32bb0405fd3f Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 14 Oct 2020 11:44:30 +0200 Subject: [PATCH] Support ofsetted parameters in local modref 2020-10-14 Jan Hubicka * 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. --- gcc/doc/invoke.texi | 3 ++ gcc/ipa-modref.c | 18 ++++++++++-- gcc/ipa-prop.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ gcc/ipa-prop.h | 2 ++ gcc/params.opt | 4 +++ 5 files changed, 92 insertions(+), 3 deletions(-) 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..63c652f4ffc 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. -- 2.30.2