This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix alias problems in PR19633


This patch addresses the aliasing problems that were preventing
the recognition of a tail call in this PR.

The problem was that ptr_is_dereferenced_by was not expecting
INDIRECT_REFs inside function arguments.  So, it was returning
false, and since the CALL_EXPR is an escape site, the alias
analyzer thought that the pointer's value was escaping the
function, making its pointed-to variables call-clobbered.

Once that was fixed, I noticed that we were creating .GLOBAL_VAR
unnecessarily.  The function had no call-clobbered variables.  I
had fixed this several weeks ago on TCB, so I just brought the
patch over from the branch.

Unfortunately this still doesn't fix the PR.  In
suitable_for_tail_call_opt_p we are returning false if any
argument is TREE_ADDRESSABLE.  That's related to two other PRs
and apparently not fixable until 4.1. (I don't have details, rth
seems to know about this limitation).

Bootstrapped and tested x86, x86-64, ia64,  ppc and alpha (alpha
still in progress).


Diego.


	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.


testsuite/ChangeLog

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

Index: tree-outof-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-outof-ssa.c,v
retrieving revision 2.41
diff -d -u -p -r2.41 tree-outof-ssa.c
--- tree-outof-ssa.c	23 Jan 2005 15:05:31 -0000	2.41
+++ tree-outof-ssa.c	27 Jan 2005 02:13:42 -0000
@@ -1460,6 +1460,7 @@ check_replaceable (temp_expr_table_p tab
   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
   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: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-alias.c,v
retrieving revision 2.66
diff -d -u -p -r2.66 tree-ssa-alias.c
--- tree-ssa-alias.c	18 Jan 2005 03:54:35 -0000	2.66
+++ tree-ssa-alias.c	27 Jan 2005 02:13:43 -0000
@@ -621,6 +621,16 @@ ptr_is_dereferenced_by (tree ptr, tree s
 	  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_in
 	  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 ();
     }
 
Index: testsuite/gcc.dg/pr19633.c
===================================================================
RCS file: testsuite/gcc.dg/pr19633.c
diff -N testsuite/gcc.dg/pr19633.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/pr19633.c	27 Jan 2005 02:13:45 -0000
@@ -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;
+}
Index: testsuite/gcc.dg/tree-ssa/pr19633.c
===================================================================
RCS file: testsuite/gcc.dg/tree-ssa/pr19633.c
diff -N testsuite/gcc.dg/tree-ssa/pr19633.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/tree-ssa/pr19633.c	27 Jan 2005 02:13:45 -0000
@@ -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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]