diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-06-29 10:47:46 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-06-29 10:47:46 +0200 |
commit | 5f3cd7c3f31373789dbc8360fa3d46fcaf473f99 (patch) | |
tree | aa9612115c416b5ff9f86c284f36e28909c53190 /gcc/tree-ssa-strlen.c | |
parent | 36d0d9be5585ccc0ea8a44e6d4e93d8d0f7f53a0 (diff) | |
download | gcc-5f3cd7c3f31373789dbc8360fa3d46fcaf473f99.zip gcc-5f3cd7c3f31373789dbc8360fa3d46fcaf473f99.tar.gz gcc-5f3cd7c3f31373789dbc8360fa3d46fcaf473f99.tar.bz2 |
re PR tree-optimization/71625 (missing strlen optimization on different array initialization style)
PR tree-optimization/71625
* tree-ssa-strlen.c (get_addr_stridx): Add PTR argument. Assume list
is sorted by ascending list->offset. If PTR is non-NULL and there is
previous strinfo, call get_stridx_plus_constant.
(get_stridx): Pass exp as second argument to get_addr_stridx.
(addr_stridxptr): Add missing list = list->next, so that there can be
more than one entries in the list. Bump limit from 16 to 32. Ensure
the list is sorted by ascending list->offset.
(get_stridx_plus_constant): Adjust so that it can be also called with
ADDR_EXPR instead of SSA_NAME as PTR.
(handle_char_store): Pass NULL_TREE as second argument to
get_addr_stridx.
* gcc.dg/strlenopt-28.c: New test.
From-SVN: r237841
Diffstat (limited to 'gcc/tree-ssa-strlen.c')
-rw-r--r-- | gcc/tree-ssa-strlen.c | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index f306a9c..232594b 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -159,10 +159,10 @@ get_strinfo (int idx) /* Helper function for get_stridx. */ static int -get_addr_stridx (tree exp) +get_addr_stridx (tree exp, tree ptr) { HOST_WIDE_INT off; - struct stridxlist *list; + struct stridxlist *list, *last = NULL; tree base; if (!decl_to_stridxlist_htab) @@ -180,9 +180,22 @@ get_addr_stridx (tree exp) { if (list->offset == off) return list->idx; + if (list->offset > off) + return 0; + last = list; list = list->next; } while (list); + + if (ptr && last && last->idx > 0) + { + strinfo *si = get_strinfo (last->idx); + if (si + && si->length + && TREE_CODE (si->length) == INTEGER_CST + && compare_tree_int (si->length, off - last->offset) != -1) + return get_stridx_plus_constant (si, off - last->offset, ptr); + } return 0; } @@ -234,7 +247,7 @@ get_stridx (tree exp) if (TREE_CODE (exp) == ADDR_EXPR) { - int idx = get_addr_stridx (TREE_OPERAND (exp, 0)); + int idx = get_addr_stridx (TREE_OPERAND (exp, 0), exp); if (idx != 0) return idx; } @@ -304,15 +317,29 @@ addr_stridxptr (tree exp) if (existed) { int i; - for (i = 0; i < 16; i++) + stridxlist *before = NULL; + for (i = 0; i < 32; i++) { if (list->offset == off) return &list->idx; + if (list->offset > off && before == NULL) + before = list; if (list->next == NULL) break; + list = list->next; } - if (i == 16) + if (i == 32) return NULL; + if (before) + { + list = before; + before = XOBNEW (&stridx_obstack, struct stridxlist); + *before = *list; + list->next = before; + list->offset = off; + list->idx = 0; + return &list->idx; + } list->next = XOBNEW (&stridx_obstack, struct stridxlist); list = list->next; } @@ -613,9 +640,7 @@ verify_related_strinfos (strinfo *origsi) static int get_stridx_plus_constant (strinfo *basesi, HOST_WIDE_INT off, tree ptr) { - gcc_checking_assert (TREE_CODE (ptr) == SSA_NAME); - - if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr)) + if (TREE_CODE (ptr) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr)) return 0; if (basesi->length == NULL_TREE @@ -633,7 +658,8 @@ get_stridx_plus_constant (strinfo *basesi, HOST_WIDE_INT off, tree ptr) || TREE_CODE (si->length) != INTEGER_CST) return 0; - if (ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr)) + if (TREE_CODE (ptr) == SSA_NAME + && ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr)) ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names); gcc_checking_assert (compare_tree_int (si->length, off) != -1); @@ -651,6 +677,7 @@ get_stridx_plus_constant (strinfo *basesi, HOST_WIDE_INT off, tree ptr) { if (r == 0) { + gcc_assert (TREE_CODE (ptr) == SSA_NAME); ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] = si->idx; return si->idx; } @@ -2063,7 +2090,7 @@ handle_char_store (gimple_stmt_iterator *gsi) } } else - idx = get_addr_stridx (lhs); + idx = get_addr_stridx (lhs, NULL_TREE); if (idx > 0) { |