tree-flow.h (find_new_referenced_vars): Add prototype.
authorJakub Jelinek <jakub@gcc.gnu.org>
Thu, 23 Sep 2004 21:01:02 +0000 (23:01 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 23 Sep 2004 21:01:02 +0000 (23:01 +0200)
2004-09-23  Diego Novillo  <dnovillo@redhat.com>
    Jakub Jelinek  <jakub@redhat.com>

* tree-flow.h (find_new_referenced_vars): Add prototype.
* tree-sra.c (find_new_referenced_vars_1, find_new_referenced_vars):
Move to...
* tree-dfa.c (find_new_referenced_vars_1, find_new_referenced_vars):
... here.
(mark_new_vars_to_rename): Walk through all operands.
* tree-ssa-ccp.c (convert_to_gimple_builtin): New function.
(execute_fold_all_builtins): Use it.
(pass_fold_builtins): Add TODO_rename_vars to todo_flags_finish.

* gcc.c-torture/execute/builtins/strcpy-2.c: New test.
* gcc.c-torture/execute/builtins/strcpy-2-lib.c: New.

From-SVN: r87983

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/builtins/strcpy-2-lib.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/builtins/strcpy-2.c [new file with mode: 0644]
gcc/tree-dfa.c
gcc/tree-flow.h
gcc/tree-sra.c
gcc/tree-ssa-ccp.c

index cabb154ca00612bb51c187b42e9a12a099048cef..37c7d2c9ccf668c6e5785862d503ebdc8cda71da 100644 (file)
@@ -1,3 +1,16 @@
+2004-09-23  Diego Novillo  <dnovillo@redhat.com>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       * tree-flow.h (find_new_referenced_vars): Add prototype.
+       * tree-sra.c (find_new_referenced_vars_1, find_new_referenced_vars):
+       Move to...
+       * tree-dfa.c (find_new_referenced_vars_1, find_new_referenced_vars):
+       ... here.
+       (mark_new_vars_to_rename): Walk through all operands.
+       * tree-ssa-ccp.c (convert_to_gimple_builtin): New function.
+       (execute_fold_all_builtins): Use it.
+       (pass_fold_builtins): Add TODO_rename_vars to todo_flags_finish.
+
 2004-09-23  P.J. Darcy  <darcypj@us.ibm.com>
 
        * gthr-tpf.h: New file.
index 79df7ecf68fc5a94a497d1620f120cacefabfd82..dd233c1aff685d27e317837b1e35b5259d58075f 100644 (file)
@@ -1,3 +1,8 @@
+2004-09-23  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.c-torture/execute/builtins/strcpy-2.c: New test.
+       * gcc.c-torture/execute/builtins/strcpy-2-lib.c: New.
+
 2004-09-23  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR c++/17618
diff --git a/gcc/testsuite/gcc.c-torture/execute/builtins/strcpy-2-lib.c b/gcc/testsuite/gcc.c-torture/execute/builtins/strcpy-2-lib.c
new file mode 100644 (file)
index 0000000..b10dfcb
--- /dev/null
@@ -0,0 +1 @@
+#include "lib/strcpy.c"
diff --git a/gcc/testsuite/gcc.c-torture/execute/builtins/strcpy-2.c b/gcc/testsuite/gcc.c-torture/execute/builtins/strcpy-2.c
new file mode 100644 (file)
index 0000000..c3cb6d0
--- /dev/null
@@ -0,0 +1,47 @@
+/* Copyright (C) 2004  Free Software Foundation.
+
+   Ensure builtin strcpy is optimized into memcpy
+   even when there is more than one possible string literal
+   passed to it, but all string literals passed to it
+   have equal length.
+
+   Written by Jakub Jelinek, 9/15/2004.  */
+
+extern void abort (void);
+extern char *strcpy (char *, const char *);
+typedef __SIZE_TYPE__ size_t;
+extern void *memcpy (void *, const void *, size_t);
+extern int memcmp (const void *, const void *, size_t);
+
+char buf[32], *p;
+int i;
+
+char *
+__attribute__((noinline))
+test (void)
+{
+  int j;
+  const char *q = "abcdefg";
+  for (j = 0; j < 3; ++j)
+    {
+      if (j == i)
+        q = "bcdefgh";
+      else if (j == i + 1)
+        q = "cdefghi";
+      else if (j == i + 2)
+        q = "defghij";
+    }
+  p = strcpy (buf, q);
+  return strcpy (buf + 16, q);
+}
+
+void
+main_test (void)
+{
+#ifndef __OPTIMIZE_SIZE__
+  /* For -Os, strcpy above is not replaced with
+     memcpy (buf, q, 8);, as that is larger.  */
+  if (test () != buf + 16 || p != buf)
+    abort ();
+#endif
+}
index 9db0cbb243aab525cb12e5f735df44ffb5fbc694..679ffef06aa9ed53160567687eb6e4fd7a560775 100644 (file)
@@ -981,9 +981,7 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename)
   v_may_defs_after = NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt));
   v_must_defs_after = NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt));
 
-  FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, 
-                            SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF)
-
+  FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_ALL_OPERANDS)
     {
       if (DECL_P (val))
        {
@@ -1004,3 +1002,27 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename)
 
   BITMAP_XFREE (vars_in_vops_to_rename);
 }
+
+/* Find all variables within the gimplified statement that were not previously
+   visible to the function and add them to the referenced variables list.  */
+
+static tree
+find_new_referenced_vars_1 (tree *tp, int *walk_subtrees,
+                           void *data ATTRIBUTE_UNUSED)
+{
+  tree t = *tp;
+
+  if (TREE_CODE (t) == VAR_DECL && !var_ann (t))
+    add_referenced_tmp_var (t);
+
+  if (IS_TYPE_OR_DECL_P (t))
+    *walk_subtrees = 0;
+
+  return NULL;
+}
+
+void
+find_new_referenced_vars (tree *stmt_p)
+{
+  walk_tree (stmt_p, find_new_referenced_vars_1, NULL, NULL);
+}
index 0cf86ca60eb8ff3f60721ba4624b0739c79aeb5c..292879ac4306d6586902ac9107eafdfb259ef2f7 100644 (file)
@@ -541,6 +541,8 @@ extern void free_df_for_stmt (tree);
 extern tree get_virtual_var (tree);
 extern void add_referenced_tmp_var (tree var);
 extern void mark_new_vars_to_rename (tree, bitmap);
+extern void find_new_referenced_vars (tree *);
+
 extern void redirect_immediate_uses (tree, tree);
 extern tree make_rename_temp (tree, const char *);
 
index 01a609acda2a8e6dbcfca43cd54207011c5309b2..9c1a4976afe1c10009b6a2b9fe34ede7b571d60e 100644 (file)
@@ -1541,30 +1541,6 @@ generate_element_zero (struct sra_elt *elt, tree *list_p)
     }
 }
 
-/* Find all variables within the gimplified statement that were not previously
-   visible to the function and add them to the referenced variables list.  */
-
-static tree
-find_new_referenced_vars_1 (tree *tp, int *walk_subtrees,
-                           void *data ATTRIBUTE_UNUSED)
-{
-  tree t = *tp;
-
-  if (TREE_CODE (t) == VAR_DECL && !var_ann (t))
-    add_referenced_tmp_var (t);
-
-  if (IS_TYPE_OR_DECL_P (t))
-    *walk_subtrees = 0;
-
-  return NULL;
-}
-
-static inline void
-find_new_referenced_vars (tree *stmt_p)
-{
-  walk_tree (stmt_p, find_new_referenced_vars_1, NULL, NULL);
-}
-
 /* Generate an assignment VAR = INIT, where INIT may need gimplification.
    Add the result to *LIST_P.  */
 
index f268686668c4cda768cbcdef334d4efaf691e7fb..bb37fcf09670fceacbab13cb732a31d794009107 100644 (file)
@@ -2099,6 +2099,37 @@ fold_stmt (tree *stmt_p)
 }
 
 \f
+/* Convert EXPR into a GIMPLE value suitable for substitution on the
+   RHS of an assignment.  Insert the necessary statements before
+   iterator *SI_P.  */
+
+static tree
+convert_to_gimple_builtin (block_stmt_iterator *si_p, tree expr)
+{
+  tree_stmt_iterator ti;
+  tree stmt = bsi_stmt (*si_p);
+  tree tmp, stmts = NULL;
+
+  push_gimplify_context ();
+  tmp = get_initialized_tmp_var (expr, &stmts, NULL);
+  pop_gimplify_context (NULL);
+
+  /* The replacement can expose previously unreferenced variables.  */
+  for (ti = tsi_start (stmts); !tsi_end_p (ti); tsi_next (&ti))
+    {
+      find_new_referenced_vars (tsi_stmt_ptr (ti));
+      mark_new_vars_to_rename (tsi_stmt (ti), vars_to_rename);
+    }
+
+  if (EXPR_HAS_LOCATION (stmt))
+    annotate_all_with_locus (&stmts, EXPR_LOCATION (stmt));
+
+  bsi_insert_before (si_p, stmts, BSI_SAME_STMT);
+
+  return tmp;
+}
+
+
 /* A simple pass that attempts to fold all builtin functions.  This pass
    is run after we've propagated as many constants as we can.  */
 
@@ -2142,8 +2173,13 @@ execute_fold_all_builtins (void)
              print_generic_stmt (dump_file, *stmtp, dump_flags);
            }
 
-         if (set_rhs (stmtp, result))
-           modify_stmt (*stmtp);
+         if (!set_rhs (stmtp, result))
+           {
+             result = convert_to_gimple_builtin (&i, result);
+             if (result && !set_rhs (stmtp, result))
+               abort ();
+           }
+         modify_stmt (*stmtp);
 
          if (dump_file && (dump_flags & TDF_DETAILS))
            {
@@ -2169,6 +2205,8 @@ struct tree_opt_pass pass_fold_builtins =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_verify_ssa,    /* todo_flags_finish */
+  TODO_dump_func
+    | TODO_verify_ssa
+    | TODO_rename_vars,                        /* todo_flags_finish */
   0                                    /* letter */
 };