diff options
author | marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-10-14 12:08:27 +0000 |
---|---|---|
committer | marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-10-14 12:08:27 +0000 |
commit | ac8a4f8e58d4925a9771f94336c43bd189b10737 (patch) | |
tree | c896ce6d1d5d5cec3b0369bdda9ddacf3ad4f63f /gcc/fold-const-call.c | |
parent | ff16a800057a4482d46a33e045b5522ee76fe960 (diff) | |
download | gcc-ac8a4f8e58d4925a9771f94336c43bd189b10737.tar.gz |
Fold __builtin_str{n}{case}cmp functions
* builtins.c (fold_builtin_strcmp): Remove function.
(fold_builtin_strncmp): Likewise.
(fold_builtin_2): Remove call of the function.
(fold_builtin_3): Likewise.
* fold-const-call.c (fold_const_call): Add constant folding
for CFN_BUILT_IN_STRCASECMP and CFN_BUILT_IN_STRNCASECMP.
* fold-const-call.h (build_cmp_result): Declare the function.
* gimple-fold.c (gimple_load_first_char): New function.
(gimple_fold_builtin_string_compare): Likewise.
(gimple_fold_builtin): Call the function.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@241159 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const-call.c')
-rw-r--r-- | gcc/fold-const-call.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c index 2bbc8872865..f67b245876c 100644 --- a/gcc/fold-const-call.c +++ b/gcc/fold-const-call.c @@ -69,7 +69,7 @@ host_size_t_cst_p (tree t, size_t *size_out) "equal" and > 0 means "more". Canonicalize it to -1, 0 or 1 and return it in type TYPE. */ -static inline tree +tree build_cmp_result (tree type, int res) { return build_int_cst (type, res < 0 ? -1 : res > 0 ? 1 : 0); @@ -1397,6 +1397,15 @@ fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1) return build_cmp_result (type, strcmp (p0, p1)); return NULL_TREE; + case CFN_BUILT_IN_STRCASECMP: + if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) + { + int r = strcmp (p0, p1); + if (r == 0) + return build_cmp_result (type, r); + } + return NULL_TREE; + default: return fold_const_call_1 (fn, type, arg0, arg1); } @@ -1464,16 +1473,36 @@ tree fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2) { const char *p0, *p1; - size_t s2; + size_t s2 = 0; switch (fn) { case CFN_BUILT_IN_STRNCMP: - if ((p0 = c_getstr (arg0)) - && (p1 = c_getstr (arg1)) - && host_size_t_cst_p (arg2, &s2)) - return build_int_cst (type, strncmp (p0, p1, s2)); - return NULL_TREE; - + { + bool const_size_p = host_size_t_cst_p (arg2, &s2); + if (const_size_p && s2 == 0 + && !TREE_SIDE_EFFECTS (arg0) + && !TREE_SIDE_EFFECTS (arg1)) + return build_int_cst (type, 0); + else if (const_size_p + && (p0 = c_getstr (arg0)) + && (p1 = c_getstr (arg1))) + return build_int_cst (type, strncmp (p0, p1, s2)); + return NULL_TREE; + } + case CFN_BUILT_IN_STRNCASECMP: + { + bool const_size_p = host_size_t_cst_p (arg2, &s2); + if (const_size_p && s2 == 0 + && !TREE_SIDE_EFFECTS (arg0) + && !TREE_SIDE_EFFECTS (arg1)) + return build_int_cst (type, 0); + else if (const_size_p + && (p0 = c_getstr (arg0)) + && (p1 = c_getstr (arg1)) + && strncmp (p0, p1, s2) == 0) + return build_int_cst (type, 0); + return NULL_TREE; + } case CFN_BUILT_IN_BCMP: case CFN_BUILT_IN_MEMCMP: if ((p0 = c_getstr (arg0)) |