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]

Local update flow info assumes valid situations are illegal


I've observed a significant number of failures lately, related with
having regmove replace uses of certain registers with uses of others,
such that the originally used register becomes dead.
verify_local_live_at_start() didn't like that.

I've recently been presented with another testcase in which all uses
of a register could be optimized away by combine, so the register
became dead in the whole basic block.

In other cases, a fixed hardware register was not used at all before
some split introduced uses thereof; in this case, the register ended
up live in the beginning of the block, even though it was dead at the end.

In all of these situations, what there was in common was that the
register was dead at the end of the basic block, so, if usage of the
register changed within the block, life information would (or
wouldn't) propagate up from the block end, and the register would end
up dead (or live) in the head, and we'd crash except in certain
common, but not certain, circumstances.

This patch addresses this issue.  With it, we'll only crash when the
register whose life info has changed if it was live at the end of the
basic block.  If it was dead, it's reasonable to have its life info
change at the head, so we'll accept it without crashing.

There's not much to test in this patch, since it pretty much only
avoids crashes, but I've tested it with a couple of targets on which
I've observed failures before, and didn't observe them any more.

Ok to install?

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>
	* flow.c (verify_local_live_at_start): Don't die if a register
	dead at the end of a BB becomes dead at the head.

Index: gcc/flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.364
diff -u -p -r1.364 flow.c
--- gcc/flow.c 2001/01/02 07:00:47 1.364
+++ gcc/flow.c 2001/01/03 22:51:12
@@ -2940,18 +2940,23 @@ verify_local_live_at_start (new_live_at_
 
       EXECUTE_IF_SET_IN_REG_SET (new_live_at_start, 0, i,
 	{
-          /* No registers should die.  */
-	  if (REGNO_REG_SET_P (bb->global_live_at_start, i))
+          /* In general, registers shouldn't die, but if they happen
+	     to be dead at the end of a bb and their uses are
+	     optimized out, their dying is ok.  */
+	  if (REGNO_REG_SET_P (bb->global_live_at_end, i))
 	    {
-	      if (rtl_dump_file)
-		fprintf (rtl_dump_file,
-			 "Register %d died unexpectedly in block %d\n", i,
-			 bb->index);
-	      print_rtl_and_abort ();
-	    }
+	      if (REGNO_REG_SET_P (bb->global_live_at_start, i))
+		{
+		  if (rtl_dump_file)
+		    fprintf (rtl_dump_file,
+			     "Register %d died unexpectedly in block %d\n", i,
+			     bb->index);
+		  print_rtl_and_abort ();
+		}
 
-          /* Verify that the now-live register is wider than word_mode.  */
-	  verify_wide_reg (i, bb->head, bb->end);
+	      /* Verify that the now-live register is wider than word_mode.  */
+	      verify_wide_reg (i, bb->head, bb->end);
+	    }
 	});
     }
 }

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

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