aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-prop.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2020-10-14 11:44:30 +0200
committerJan Hubicka <jh@suse.cz>2020-10-14 11:44:30 +0200
commitc7b6a7587f215e913cec9ed523bf32bb0405fd3f (patch)
treee45f2f02121bc6526d9504f484dec745dea32fc9 /gcc/ipa-prop.c
parent87d75a11a5cb93668ae0bf6d97030e01b2eae3f2 (diff)
downloadgcc-c7b6a7587f215e913cec9ed523bf32bb0405fd3f.zip
gcc-c7b6a7587f215e913cec9ed523bf32bb0405fd3f.tar.gz
gcc-c7b6a7587f215e913cec9ed523bf32bb0405fd3f.tar.bz2
Support ofsetted parameters in local modref
2020-10-14 Jan Hubicka <hubicka@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.
Diffstat (limited to 'gcc/ipa-prop.c')
-rw-r--r--gcc/ipa-prop.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 2d09d91..63c652f 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