OSDN Git Service

PR tree-optimization/19633
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 27 Jan 2005 04:45:20 +0000 (04:45 +0000)
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 27 Jan 2005 04:45:20 +0000 (04:45 +0000)
* tree-ssa-alias.c (ptr_is_dereferenced_by): Also handle
CALL_EXPRs.
(maybe_create_global_var): Do not create .GLOBAL_VAR if there
are no call-clobbered variables.
* tree-outof-ssa.c (check_replaceable): Return false for calls
with side-effects.

testsuite/ChangeLog

PR tree-optimization/19633
* gcc.dg/pr19633.c: New test.
* gcc.dg/tree-ssa/pr19633.c: New test.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr19633.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr19633.c [new file with mode: 0644]
gcc/tree-outof-ssa.c
gcc/tree-ssa-alias.c

index ca995cc..04ef357 100644 (file)
@@ -1,3 +1,13 @@
+2005-01-26  Diego Novillo  <dnovillo@redhat.com>
+
+       PR tree-optimization/19633
+       * tree-ssa-alias.c (ptr_is_dereferenced_by): Also handle
+       CALL_EXPRs.
+       (maybe_create_global_var): Do not create .GLOBAL_VAR if there
+       are no call-clobbered variables.
+       * tree-outof-ssa.c (check_replaceable): Return false for calls
+       with side-effects.
+
 2005-01-26  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * dbxout.c (dbxout_symbol_location): Resolve constant pool references
index 0140e9a..deceb4a 100644 (file)
@@ -1,3 +1,9 @@
+2005-01-26  Diego Novillo  <dnovillo@redhat.com>
+
+       PR tree-optimization/19633
+       * gcc.dg/pr19633.c: New test.
+       * gcc.dg/tree-ssa/pr19633.c: New test.
+
 2005-01-26  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * gcc.dg/20041216-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr19633.c b/gcc/testsuite/gcc.dg/pr19633.c
new file mode 100644 (file)
index 0000000..4e18375
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-do link } */
+/* { dg-options "-O2" } */
+
+struct S
+{
+  int w, x, y, z;
+};
+
+struct T
+{
+  int r;
+  struct S s;
+};
+
+void
+foo (int a, struct T b)
+{
+  struct S x;
+  struct S *c = &x;
+  if (a)
+    c = &b.s;
+  b.s.w = 3;
+  bar (*c, a);
+  if (b.s.w != 3)
+    link_error ();
+}
+
+int main ()
+{
+  struct T b;
+  foo (3, b);
+  return 0;
+}
+
+int X;
+
+int bar (struct S x, int i)
+{
+  X = 3;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr19633.c b/gcc/testsuite/gcc.dg/tree-ssa/pr19633.c
new file mode 100644 (file)
index 0000000..88cbfe2
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-ssa-vops" } */
+struct S
+{
+  int w, x, y, z;
+};
+struct T
+{
+  int r;
+  struct S s;
+};
+void bar (struct S, int);
+void
+foo (int a, struct T b)
+{
+  struct S x;
+  struct S *c = &x;
+  if (a)
+    c = &b.s;
+  bar (*c, a);
+}
+
+/* Make sure that .GLOBAL_VAR is not created when there are no
+   clobbering calls.  */
+/* { dg-final { scan-tree-dump-times "GLOBAL_VAR" 0 "ssa"} } */
index cfa1704..430e8ca 100644 (file)
@@ -1460,6 +1460,7 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
   int num_use_ops, version;
   var_map map = tab->map;
   ssa_op_iter iter;
+  tree call_expr;
 
   if (TREE_CODE (stmt) != MODIFY_EXPR)
     return false;
@@ -1486,6 +1487,15 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
   if (flag_float_store && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (stmt, 1))))
     return false;
 
+  /* Calls to functions with side-effects cannot be replaced.  */
+  if ((call_expr = get_call_expr_in (stmt)) != NULL_TREE)
+    {
+      int call_flags = call_expr_flags (call_expr);
+      if (TREE_SIDE_EFFECTS (call_expr)
+         && !(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
+       return false;
+    }
+
   uses = USE_OPS (ann);
   num_use_ops = NUM_USES (uses);
   vuseops = VUSE_OPS (ann);
index a410217..da11fd0 100644 (file)
@@ -621,6 +621,16 @@ ptr_is_dereferenced_by (tree ptr, tree stmt, bool *is_store)
          return true;
        }
     }
+  else
+    {
+      /* CALL_EXPRs may also contain pointer dereferences for types
+        that are not GIMPLE register types.  If the CALL_EXPR is on
+        the RHS of an assignment, it will be handled by the
+        MODIFY_EXPR handler above.  */
+      tree call = get_call_expr_in (stmt);
+      if (call && walk_tree (&call, find_ptr_dereference, ptr, NULL))
+       return true;
+    }
 
   return false;
 }
@@ -1538,26 +1548,7 @@ maybe_create_global_var (struct alias_info *ai)
          n_clobbered++;
        }
 
-      /* Create .GLOBAL_VAR if we have too many call-clobbered
-        variables.  We also create .GLOBAL_VAR when there no
-        call-clobbered variables to prevent code motion
-        transformations from re-arranging function calls that may
-        have side effects.  For instance,
-
-               foo ()
-               {
-                 int a = f ();
-                 g ();
-                 h (a);
-               }
-
-        There are no call-clobbered variables in foo(), so it would
-        be entirely possible for a pass to want to move the call to
-        f() after the call to g().  If f() has side effects, that
-        would be wrong.  Creating .GLOBAL_VAR in this case will
-        insert VDEFs for it and prevent such transformations.  */
-      if (n_clobbered == 0
-         || ai->num_calls_found * n_clobbered >= (size_t) GLOBAL_VAR_THRESHOLD)
+      if (ai->num_calls_found * n_clobbered >= (size_t) GLOBAL_VAR_THRESHOLD)
        create_global_var ();
     }