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 PR 19080



The problem here is that on the second run of alias analysis, we were not clearing call-clobbering information properly. So, memory tags that were deemed unnecessary on the second alias pass were left with their call-clobbered bit set. This caused the operand scanner to add them at call-sites.


Bootstrapped and tested x86, x86-64, ppc and alpha.


Diego.
2004-12-20  Diego Novillo  <dnovillo@redhat.com>

	PR tree-optimization/19080

	Merge from tree-cleanup-branch

	* tree-flow-inline.h (clear_call_clobbered): New function.
	* tree-ssa-alias.c (init_alias_info): Call it.

testsuite/ChangeLog

	PR tree-optimization/19080
	* gcc.c-torture/compile/pr19080.c: New test.

Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow-inline.h,v
retrieving revision 2.27
diff -d -c -p -u -r2.27 tree-flow-inline.h
--- tree-flow-inline.h	25 Nov 2004 20:24:58 -0000	2.27
+++ tree-flow-inline.h	20 Dec 2004 15:59:42 -0000
@@ -625,6 +625,18 @@ mark_call_clobbered (tree var)
   ssa_ro_call_cache_valid = false;
 }
 
+/* Clear the call-clobbered attribute from variable VAR.  */
+static inline void
+clear_call_clobbered (tree var)
+{
+  var_ann_t ann = var_ann (var);
+  if (ann->mem_tag_kind != NOT_A_TAG)
+    DECL_EXTERNAL (var) = 0;
+  bitmap_clear_bit (call_clobbered_vars, ann->uid);
+  ssa_call_clobbered_cache_valid = false;
+  ssa_ro_call_cache_valid = false;
+}
+
 /* Mark variable VAR as being non-addressable.  */
 static inline void
 mark_non_addressable (tree var)
Index: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-alias.c,v
retrieving revision 2.63
diff -d -c -p -u -r2.63 tree-ssa-alias.c
--- tree-ssa-alias.c	10 Dec 2004 17:28:32 -0000	2.63
+++ tree-ssa-alias.c	20 Dec 2004 15:59:43 -0000
@@ -437,7 +437,6 @@ init_alias_info (void)
   if (aliases_computed_p)
     {
       unsigned i;
-      bitmap_iterator bi;
       basic_block bb;
   
      /* Make sure that every statement has a valid set of operands.
@@ -453,19 +452,6 @@ init_alias_info (void)
 	    get_stmt_operands (bsi_stmt (si));
 	}
 
-      /* Clear the call-clobbered set.  We are going to re-discover
-	  call-clobbered variables.  */
-      EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
-	{
-	  tree var = referenced_var (i);
-
-	  /* Variables that are intrinsically call-clobbered (globals,
-	     local statics, etc) will not be marked by the aliasing
-	     code, so we can't remove them from CALL_CLOBBERED_VARS.  */
-	  if (!is_call_clobbered (var))
-	    bitmap_clear_bit (call_clobbered_vars, var_ann (var)->uid);
-	}
-
       /* Similarly, clear the set of addressable variables.  In this
 	 case, we can just clear the set because addressability is
 	 only computed here.  */
@@ -474,9 +460,19 @@ init_alias_info (void)
       /* Clear flow-insensitive alias information from each symbol.  */
       for (i = 0; i < num_referenced_vars; i++)
 	{
-	  var_ann_t ann = var_ann (referenced_var (i));
+	  tree var = referenced_var (i);
+	  var_ann_t ann = var_ann (var);
+
 	  ann->is_alias_tag = 0;
 	  ann->may_aliases = NULL;
+
+	  /* Since we are about to re-discover call-clobbered
+	     variables, clear the call-clobbered flag.  Variables that
+	     are intrinsically call-clobbered (globals, local statics,
+	     etc) will not be marked by the aliasing code, so we can't
+	     remove them from CALL_CLOBBERED_VARS.  */
+	  if (ann->mem_tag_kind != NOT_A_TAG || !is_global_var (var))
+	    clear_call_clobbered (var);
 	}
 
       /* Clear flow-sensitive points-to information from each SSA name.  */
Index: testsuite/gcc.c-torture/compile/pr19080.c
===================================================================
RCS file: testsuite/gcc.c-torture/compile/pr19080.c
diff -N testsuite/gcc.c-torture/compile/pr19080.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.c-torture/compile/pr19080.c	20 Dec 2004 15:59:45 -0000
@@ -0,0 +1,115 @@
+typedef union { int ioport; volatile char *maddr; } bus_space_handle_t;
+struct scb { unsigned short *hscb; };
+struct ahd_softc
+{
+  int tags[2];
+  bus_space_handle_t bshs[2];
+  int dst_mode;
+  int src_mode;
+  int flags;
+};
+void outb(int, int);
+
+int foo_inb(struct ahd_softc*);
+int foo_int_int (int, int);
+int ahd_inb(struct ahd_softc*);
+int ahd_scb_active_in_fifo (void);
+
+void ahd_flush_qoutfifo (struct ahd_softc *ahd, struct scb *scb)
+{
+  int src, dst, *a = &src, *b = &dst; *a = 1, *b = 1;
+  int bb, p;
+
+  if (ahd->src_mode == 1)
+    { int src, dst, *a = &src, *b = &dst; *a = 1, *b = 1;}
+  foo_int_int (ahd->src_mode, ahd->dst_mode);
+  p = 1;
+  if (ahd->src_mode == 2 && ahd->dst_mode == p)
+    {
+      if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+        outb (1, ahd->bshs[0].ioport );
+      if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+        outb (1, ahd->bshs[0].ioport );
+    }
+  ahd->src_mode = 1;
+  ahd->dst_mode = 2;
+  while ((ahd_inb (ahd) & 0x01) != 0)
+  {
+    p = 1;
+    if (ahd->src_mode == 2 && ahd->dst_mode == p)
+      {
+        if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+          outb (1, ahd->bshs[0].ioport );
+        if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+          outb (1, ahd->bshs[0].ioport );
+      }
+    ahd->src_mode = 1;
+    ahd->dst_mode = 2;
+    if (ahd_scb_active_in_fifo () == 0)
+      continue;
+    p = 1;
+    if (ahd->src_mode == 2 && ahd->dst_mode == p)
+      {
+        if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+          outb (1, ahd->bshs[0].ioport );
+        if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+          outb (1, ahd->bshs[0].ioport );
+      }
+    ahd->src_mode = 1;
+    ahd->dst_mode = 2;
+    if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+      outb (1, ahd->bshs[0].ioport );
+    if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+      outb (1, ahd->bshs[0].ioport );
+    if ((ahd->flags & 1) != 0)
+      foo_inb (ahd);
+    if ((ahd->flags & 1) != 0)
+      foo_inb (ahd);
+    if ((ahd->flags & 1) != 0)
+      foo_inb (ahd);
+    if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+      outb (1, ahd->bshs[0].ioport );
+    if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+      outb (1, ahd->bshs[0].ioport );
+    if ((ahd->flags & 1) != 0)
+      foo_inb (ahd);
+    if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+      outb (1, ahd->bshs[0].ioport );
+    if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+      outb (1, ahd->bshs[0].ioport );
+    bb = (*(scb->hscb));
+    if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+      outb (1, ahd->bshs[0].ioport );
+    if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+      outb (1, ahd->bshs[0].ioport );
+    bb = (*(scb->hscb));
+    if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+      outb (1, ahd->bshs[0].ioport );
+    if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+      outb (1, ahd->bshs[0].ioport );
+  }
+  if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+    outb (1, ahd->bshs[0].ioport );
+  if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+    outb (1, ahd->bshs[0].ioport );
+  p = 1;
+  if (ahd->src_mode == 2 && ahd->dst_mode == p)
+    {
+      if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+        outb (1, ahd->bshs[0].ioport );
+      if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+        outb (1, ahd->bshs[0].ioport );
+    }
+  ahd->src_mode = 1;
+  ahd->dst_mode = 2;
+  if (ahd->src_mode == 2 && ahd->dst_mode == dst)
+    {
+      if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+        outb (1, ahd->bshs[0].ioport );
+      if (ahd->tags[0] == 1) *(ahd->bshs[0].maddr);
+        outb (1, ahd->bshs[0].ioport );
+    }
+  ahd->src_mode = 1;
+  ahd->dst_mode = 2;
+  ahd->flags |= 1;
+}

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