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
This commit is contained in:
Jakub Jelinek 2010-07-14 00:56:29 +02:00 committed by Jakub Jelinek
parent 4ca4be7f25
commit 48b195373b
2 changed files with 38 additions and 11 deletions

View File

@ -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.

View File

@ -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))