OSDN Git Service

PR fortran/28163
authorfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 12 Jul 2006 15:11:11 +0000 (15:11 +0000)
committerfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 12 Jul 2006 15:11:11 +0000 (15:11 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@115372 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/fortran/ChangeLog
gcc/fortran/trans-decl.c
gcc/fortran/trans-expr.c
gcc/fortran/trans.h
libgfortran/ChangeLog
libgfortran/intrinsics/string_intrinsics.c

index 74d1f71..89497e4 100644 (file)
@@ -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
index 14aee05..7398e16 100644 (file)
@@ -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,
index 30cf80a..5c396ef 100644 (file)
@@ -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);
 }
index ce99793..31d525d 100644 (file)
@@ -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;
index a680112..b4478b4 100644 (file)
@@ -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,
index 1bc4ff2..fdaddef 100644 (file)
@@ -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