diff options
author | Jakub Jelinek <jakub@redhat.com> | 2010-07-14 00:56:29 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-07-14 00:56:29 +0200 |
commit | 48b195373b36b34735437677b73c8b6e77dd88fc (patch) | |
tree | f5d3f3c705f04acc33aa701dcd1c7fc5a84fe813 /gcc | |
parent | 4ca4be7f25a6a4237e98410f1fab2f4578d52d1f (diff) | |
download | gcc-48b195373b36b34735437677b73c8b6e77dd88fc.zip gcc-48b195373b36b34735437677b73c8b6e77dd88fc.tar.gz gcc-48b195373b36b34735437677b73c8b6e77dd88fc.tar.bz2 |
trans-expr.c (string_to_single_character): Also optimize string literals containing a single char followed only by spaces.
* trans-expr.c (string_to_single_character): Also optimize
string literals containing a single char followed only by spaces.
(gfc_trans_string_copy): Remove redundant string_to_single_character
calls.
From-SVN: r162161
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/fortran/trans-expr.c | 44 |
2 files changed, 38 insertions, 11 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 2847d94..e8eeffc 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,10 @@ 2010-07-14 Jakub Jelinek <jakub@redhat.com> + * trans-expr.c (string_to_single_character): Also optimize + string literals containing a single char followed only by spaces. + (gfc_trans_string_copy): Remove redundant string_to_single_character + calls. + * trans-decl.c (gfc_build_intrinsic_function_decls, gfc_build_builtin_function_decls): Mark functions as DECL_PURE_P or TREE_READONLY. diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index ff250fd..9857f44 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -1393,12 +1393,40 @@ string_to_single_character (tree len, tree str, int kind) { gcc_assert (POINTER_TYPE_P (TREE_TYPE (str))); - if (INTEGER_CST_P (len) && TREE_INT_CST_LOW (len) == 1 - && TREE_INT_CST_HIGH (len) == 0) + if (!INTEGER_CST_P (len) || TREE_INT_CST_HIGH (len) != 0) + return NULL_TREE; + + if (TREE_INT_CST_LOW (len) == 1) { str = fold_convert (gfc_get_pchar_type (kind), str); - return build_fold_indirect_ref_loc (input_location, - str); + return build_fold_indirect_ref_loc (input_location, str); + } + + if (kind == 1 + && TREE_CODE (str) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF + && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST + && array_ref_low_bound (TREE_OPERAND (str, 0)) + == TREE_OPERAND (TREE_OPERAND (str, 0), 1) + && TREE_INT_CST_LOW (len) > 1 + && TREE_INT_CST_LOW (len) + == (unsigned HOST_WIDE_INT) + TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0))) + { + tree ret = fold_convert (gfc_get_pchar_type (kind), str); + ret = build_fold_indirect_ref_loc (input_location, ret); + if (TREE_CODE (ret) == INTEGER_CST) + { + tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0); + int i, len = TREE_STRING_LENGTH (string_cst); + const char *ptr = TREE_STRING_POINTER (string_cst); + + for (i = 1; i < len; i++) + if (ptr[i] != ' ') + return NULL_TREE; + + return ret; + } } return NULL_TREE; @@ -3556,7 +3584,7 @@ gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest, if (dlength != NULL_TREE) { dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block)); - dsc = string_to_single_character (slen, dest, dkind); + dsc = string_to_single_character (dlen, dest, dkind); } else { @@ -3564,12 +3592,6 @@ gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest, dsc = dest; } - if (slength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (src))) - ssc = string_to_single_character (slen, src, skind); - if (dlength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (dest))) - dsc = string_to_single_character (dlen, dest, dkind); - - /* Assign directly if the types are compatible. */ if (dsc != NULL_TREE && ssc != NULL_TREE && TREE_TYPE (dsc) == TREE_TYPE (ssc)) |