aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-07-14 00:56:29 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2010-07-14 00:56:29 +0200
commit48b195373b36b34735437677b73c8b6e77dd88fc (patch)
treef5d3f3c705f04acc33aa701dcd1c7fc5a84fe813 /gcc
parent4ca4be7f25a6a4237e98410f1fab2f4578d52d1f (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/fortran/trans-expr.c44
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))