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]

[tree-ssa] Fix handling of function calls with side effects


When a program has no call-clobbered variables, the compiler would not
create .GLOBAL_VAR (the artificial variable used to model side
effects).  This was causing the expression recombination pass to move
function calls past others:

a = foo()
bar();
baz(a);	<-- foo() was being moved here.

If bar() depends on some global variable set by foo(), we have a
problem.

Jeff found this as a runtime failure in one of the FC2 packages
(temacs?).  This patch fixes the problem.

It also fixes the handling of asm memory barriers to add a VDEF to
.GLOBAL_VAR even if there are no call-clobbered variables in the
function.

Bootstrapped x86, x86-64.


Diego.


	* tree-ssa-alias.c (maybe_create_global_var): Create
	.GLOBAL_VAR if there are no call-clobbered variables.
	* tree-ssa-operands.c (get_stmt_operands): Add call-clobbering
	VDEFs for asm ("":::"memory") if there are call-clobbered
	variables or if .GLOBAL_VAR has been created.


testsuite/ChangeLog.tree-ssa:

	* gcc.dg/tree-ssa/20040326-1.c: New test.

Index: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-alias.c,v
retrieving revision 1.1.2.16
diff -d -c -p -d -u -p -r1.1.2.16 tree-ssa-alias.c
--- tree-ssa-alias.c	25 Mar 2004 18:41:36 -0000	1.1.2.16
+++ tree-ssa-alias.c	26 Mar 2004 17:58:36 -0000
@@ -1304,7 +1304,25 @@ maybe_create_global_var (struct alias_in
   n_clobbered = 0;
   EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, n_clobbered++);
 
-  if (ai->num_calls_found * n_clobbered >= (size_t) GLOBAL_VAR_THRESHOLD)
+  /* Create .GLOBAL_VAR if we have too many call-clobbered variables.
+     We also create .GLOBAL_VAR when there no are 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)
     create_global_var ();
 
   /* If the function has calls to clobbering functions and .GLOBAL_VAR has
Index: tree-ssa-operands.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-operands.c,v
retrieving revision 1.1.2.17
diff -d -c -p -d -u -p -r1.1.2.17 tree-ssa-operands.c
--- tree-ssa-operands.c	16 Mar 2004 22:31:56 -0000	1.1.2.17
+++ tree-ssa-operands.c	26 Mar 2004 17:58:36 -0000
@@ -769,10 +769,12 @@ get_stmt_operands (tree stmt)
 	    get_expr_operands (stmt, &TREE_VALUE (link), 0, &prev_vops);
 	  }
 
-	for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
-	  if (!strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory")
-	      && bitmap_first_set_bit (call_clobbered_vars) >= 0)
-	    add_call_clobber_ops (stmt, &prev_vops);
+	/* Clobber memory for asm ("" : : : "memory");  */
+	if (global_var
+	    || bitmap_first_set_bit (call_clobbered_vars) >= 0)
+	  for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
+	    if (!strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory"))
+	      add_call_clobber_ops (stmt, &prev_vops);
       }
       break;
 
Index: testsuite/gcc.dg/tree-ssa/20040326-1.c
===================================================================
RCS file: testsuite/gcc.dg/tree-ssa/20040326-1.c
diff -N testsuite/gcc.dg/tree-ssa/20040326-1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/tree-ssa/20040326-1.c	26 Mar 2004 21:10:51 -0000
@@ -0,0 +1,29 @@
+/* { dg-options "-O2 -fno-inline-functions" } */
+/* { dg-do run } */
+/* When there are no call-clobbered variables, we should still create
+   a .GLOBAL_VAR to model the side effects of functions.  Without it,
+   we were moving the call to Faref() inside the second call to
+   Faset().  */
+main ()
+{
+  int table, c, elt;
+  int tem = Faref (table, elt);
+  Faset (table, elt, c);
+  Faset (table, c, tem);/* tem cannot be replaced with Faref (table, elt) */
+  exit (0);
+}
+
+int j = 0;
+
+int __attribute__ ((noinline)) Faref (table, elt)
+{
+  j = 1;
+  return 0;
+}
+
+int __attribute__ ((noinline)) Faset (table, elt, c)
+{
+  if (j != 1)
+    abort ();
+  return 0;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]