mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
45e49d9640
commit
b3eb1e0e9c
|
|
@ -1,3 +1,12 @@
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue