Commit b3eb1e0e by Francois-Xavier Coudert Committed by François-Xavier Coudert

re PR fortran/28163 (Calling libgfortran's copy_string is inefficient)

	PR fortran/28163

	* trans-expr.c (gfc_trans_string_copy): Generate inline code
	to perform string copying instead of calling a library function.
	* trans-decl.c (gfc_build_intrinsic_function_decls): Don't build
	decl for copy_string.
	* trans.h (gfor_fndecl_copy_string): Remove prototype.

	* intrinsics/string_intrinsics.c (copy_string): Remove function.

From-SVN: r115372
parent 45e49d96
2006-07-12 Francois-Xavier Coudert <coudert@clipper.ens.fr>
PR fortran/28163
* trans-expr.c (gfc_trans_string_copy): Generate inline code
to perform string copying instead of calling a library function.
* trans-decl.c (gfc_build_intrinsic_function_decls): Don't build
decl for copy_string.
* trans.h (gfor_fndecl_copy_string): Remove prototype.
2006-07-11 Feng Wang <fengwang@nudt.edu.cn>
PR fortran/28213
......
......@@ -121,7 +121,6 @@ tree gfor_fndecl_math_exponent16;
/* String functions. */
tree gfor_fndecl_copy_string;
tree gfor_fndecl_compare_string;
tree gfor_fndecl_concat_string;
tree gfor_fndecl_string_len_trim;
......@@ -1938,13 +1937,6 @@ gfc_build_intrinsic_function_decls (void)
tree gfc_c_int_type_node = gfc_get_int_type (gfc_c_int_kind);
/* String functions. */
gfor_fndecl_copy_string =
gfc_build_library_function_decl (get_identifier (PREFIX("copy_string")),
void_type_node,
4,
gfc_charlen_type_node, pchar_type_node,
gfc_charlen_type_node, pchar_type_node);
gfor_fndecl_compare_string =
gfc_build_library_function_decl (get_identifier (PREFIX("compare_string")),
gfc_int4_type_node,
......
......@@ -31,6 +31,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "toplev.h"
#include "real.h"
#include "tree-gimple.h"
#include "langhooks.h"
#include "flags.h"
#include "gfortran.h"
#include "trans.h"
......@@ -2233,6 +2234,11 @@ gfc_trans_string_copy (stmtblock_t * block, tree dlen, tree dest,
tree dsc;
tree ssc;
tree cond;
tree cond2;
tree tmp2;
tree tmp3;
tree tmp4;
stmtblock_t tempblock;
/* Deal with single character specially. */
dsc = gfc_to_single_character (dlen, dest);
......@@ -2243,15 +2249,63 @@ gfc_trans_string_copy (stmtblock_t * block, tree dlen, tree dest,
return;
}
/* Do nothing if the destination length is zero. */
cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
build_int_cst (gfc_charlen_type_node, 0));
tmp = NULL_TREE;
tmp = gfc_chainon_list (tmp, dlen);
tmp = gfc_chainon_list (tmp, dest);
tmp = gfc_chainon_list (tmp, slen);
tmp = gfc_chainon_list (tmp, src);
tmp = build_function_call_expr (gfor_fndecl_copy_string, tmp);
/* The following code was previously in _gfortran_copy_string:
// The two strings may overlap so we use memmove.
void
copy_string (GFC_INTEGER_4 destlen, char * dest,
GFC_INTEGER_4 srclen, const char * src)
{
if (srclen >= destlen)
{
// This will truncate if too long.
memmove (dest, src, destlen);
}
else
{
memmove (dest, src, srclen);
// Pad with spaces.
memset (&dest[srclen], ' ', destlen - srclen);
}
}
We're now doing it here for better optimization, but the logic
is the same. */
/* Truncate string if source is too long. */
cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
tmp2 = gfc_chainon_list (NULL_TREE, dest);
tmp2 = gfc_chainon_list (tmp2, src);
tmp2 = gfc_chainon_list (tmp2, dlen);
tmp2 = build_function_call_expr (built_in_decls[BUILT_IN_MEMMOVE], tmp2);
/* Else copy and pad with spaces. */
tmp3 = gfc_chainon_list (NULL_TREE, dest);
tmp3 = gfc_chainon_list (tmp3, src);
tmp3 = gfc_chainon_list (tmp3, slen);
tmp3 = build_function_call_expr (built_in_decls[BUILT_IN_MEMMOVE], tmp3);
tmp4 = fold_build2 (PLUS_EXPR, pchar_type_node, dest,
fold_convert (pchar_type_node, slen));
tmp4 = gfc_chainon_list (NULL_TREE, tmp4);
tmp4 = gfc_chainon_list (tmp4, build_int_cst
(gfc_get_int_type (gfc_c_int_kind),
lang_hooks.to_target_charset (' ')));
tmp4 = gfc_chainon_list (tmp4, fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
dlen, slen));
tmp4 = build_function_call_expr (built_in_decls[BUILT_IN_MEMSET], tmp4);
gfc_init_block (&tempblock);
gfc_add_expr_to_block (&tempblock, tmp3);
gfc_add_expr_to_block (&tempblock, tmp4);
tmp3 = gfc_finish_block (&tempblock);
/* The whole copy_string function is there. */
tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, build_empty_stmt ());
gfc_add_expr_to_block (block, tmp);
}
......
......@@ -508,7 +508,6 @@ extern GTY(()) tree gfor_fndecl_math_exponent10;
extern GTY(()) tree gfor_fndecl_math_exponent16;
/* String functions. */
extern GTY(()) tree gfor_fndecl_copy_string;
extern GTY(()) tree gfor_fndecl_compare_string;
extern GTY(()) tree gfor_fndecl_concat_string;
extern GTY(()) tree gfor_fndecl_string_len_trim;
......
2006-07-12 Francois-Xavier Coudert <coudert@clipper.ens.fr>
PR fortran/28163
* intrinsics/string_intrinsics.c (copy_string): Remove function.
2006-07-04 Francois-Xavier Coudert <coudert@clipper.ens.fr>
* intrinsics/date_and_time.c (itime0,idate0,itime_i4,itime_i8,
......
......@@ -44,9 +44,6 @@ Boston, MA 02110-1301, USA. */
/* String functions. */
extern void copy_string (GFC_INTEGER_4, char *, GFC_INTEGER_4, const char *);
export_proto(copy_string);
extern void concat_string (GFC_INTEGER_4, char *,
GFC_INTEGER_4, const char *,
GFC_INTEGER_4, const char *);
......@@ -79,26 +76,6 @@ export_proto(string_trim);
extern void string_repeat (char *, GFC_INTEGER_4, const char *, GFC_INTEGER_4);
export_proto(string_repeat);
/* The two areas may overlap so we use memmove. */
void
copy_string (GFC_INTEGER_4 destlen, char * dest,
GFC_INTEGER_4 srclen, const char * src)
{
if (srclen >= destlen)
{
/* This will truncate if too long. */
memmove (dest, src, destlen);
}
else
{
memmove (dest, src, srclen);
/* Pad with spaces. */
memset (&dest[srclen], ' ', destlen - srclen);
}
}
/* Strings of unequal length are extended with pad characters. */
GFC_INTEGER_4
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment