diff options
Diffstat (limited to 'gcc/gimple-fold.cc')
-rw-r--r-- | gcc/gimple-fold.cc | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index b645613..94d5a1e 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -906,20 +906,60 @@ size_must_be_zero_p (tree size) static bool optimize_memcpy_to_memset (gimple_stmt_iterator *gsip, tree dest, tree src, tree len) { + ao_ref read; gimple *stmt = gsi_stmt (*gsip); if (gimple_has_volatile_ops (stmt)) return false; - tree vuse = gimple_vuse (stmt); - if (vuse == NULL || TREE_CODE (vuse) != SSA_NAME) - return false; - gimple *defstmt = SSA_NAME_DEF_STMT (vuse); tree src2 = NULL_TREE, len2 = NULL_TREE; poly_int64 offset, offset2; tree val = integer_zero_node; + bool len_was_null = len == NULL_TREE; + if (len == NULL_TREE) + len = (TREE_CODE (src) == COMPONENT_REF + ? DECL_SIZE_UNIT (TREE_OPERAND (src, 1)) + : TYPE_SIZE_UNIT (TREE_TYPE (src))); + if (len == NULL_TREE + || !poly_int_tree_p (len)) + return false; + + ao_ref_init (&read, src); + tree vuse = gimple_vuse (stmt); + gimple *defstmt; + do { + if (vuse == NULL || TREE_CODE (vuse) != SSA_NAME) + return false; + defstmt = SSA_NAME_DEF_STMT (vuse); + if (is_a <gphi*>(defstmt)) + return false; + + /* If the len was null, then we can use TBBA. */ + if (stmt_may_clobber_ref_p_1 (defstmt, &read, + /* tbaa_p = */ len_was_null)) + break; + vuse = gimple_vuse (defstmt); + } while (true); + if (gimple_store_p (defstmt) && gimple_assign_single_p (defstmt) + && TREE_CODE (gimple_assign_rhs1 (defstmt)) == STRING_CST + && !gimple_clobber_p (defstmt)) + { + tree str = gimple_assign_rhs1 (defstmt); + src2 = gimple_assign_lhs (defstmt); + /* The string must contain all null char's for now. */ + for (int i = 0; i < TREE_STRING_LENGTH (str); i++) + { + if (TREE_STRING_POINTER (str)[i] != 0) + { + src2 = NULL_TREE; + break; + } + } + } + else if (gimple_store_p (defstmt) + && gimple_assign_single_p (defstmt) && TREE_CODE (gimple_assign_rhs1 (defstmt)) == CONSTRUCTOR && !gimple_clobber_p (defstmt)) src2 = gimple_assign_lhs (defstmt); @@ -939,17 +979,11 @@ optimize_memcpy_to_memset (gimple_stmt_iterator *gsip, tree dest, tree src, tree if (src2 == NULL_TREE) return false; - if (len == NULL_TREE) - len = (TREE_CODE (src) == COMPONENT_REF - ? DECL_SIZE_UNIT (TREE_OPERAND (src, 1)) - : TYPE_SIZE_UNIT (TREE_TYPE (src))); if (len2 == NULL_TREE) len2 = (TREE_CODE (src2) == COMPONENT_REF ? DECL_SIZE_UNIT (TREE_OPERAND (src2, 1)) : TYPE_SIZE_UNIT (TREE_TYPE (src2))); - if (len == NULL_TREE - || !poly_int_tree_p (len) - || len2 == NULL_TREE + if (len2 == NULL_TREE || !poly_int_tree_p (len2)) return false; |