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]

Re: reg_scan info validity during jump


Hi,

this patch solves my "SIGSEGV in jump.c" problem on powerpc-unknown-linux-gnu,
thanks.

Franz.

Am Fri, 10 Jul 1998 schrieb David S. Miller:
>I was tooling around with some sparc backend optimizations, decided to
>fiddle with BRANCH_COST, and found the following set of problems as a
>result.
>
>duplicate_loop_exit_test depends upon having valid reg_scan info
>around for several reasons, most importantly:
>
>1) regno_first_uid must be valid
>2) regno_last_uid must be valid
>3) max_reg_num() must return the same value it did when
>   reg_scan() was most recently run
>
>The third reason provoked the bug I saw, because
>duplicate_loop_exit_test walked off the end of the reg_n_info array
>and caused the compiler to crash.
>
>The issue is that some of the jump optimizations (and funny, the ones
>which typically happen for larger values of BRANCH_COST ;-) create new
>REGs
>
>My fear is that if this isn't crashing existing configurations in the
>current developer sources, it is causing optimization opportunities to
>be lost.  Much of the time, one is lucky because the allocation of
>reg_n_info grabs some "slop" extra entries.  I think this is bad
>programming practice and it should be allocating more strictly, and
>instead we should fix the core problems.
>
>A quick solution is to rerun reg scan when new REGs are created.
>Here is a patch which fixes this bug, yet not the generic issue.
>
>Fri Jul 10 05:36:16 1998  David S. Miller  <davem@pierdol.cobaltmicro.com>
>
>	* jump.c (jump_optimize): If after_regscan and our transformations
>	generate new REGs, rerun reg_scan.
>
>--- jump.c.~1~	Thu Jul  9 17:28:57 1998
>+++ jump.c	Fri Jul 10 05:35:15 1998
>@@ -151,6 +151,7 @@
> {
>   register rtx insn, next, note;
>   int changed;
>+  int old_max_reg;
>   int first = 1;
>   int max_uid = 0;
>   rtx last_insn;
>@@ -591,6 +592,7 @@
> 
>   /* Now iterate optimizing jumps until nothing changes over one pass.  */
>   changed = 1;
>+  old_max_reg = max_reg_num ();
>   while (changed)
>     {
>       changed = 0;
>@@ -602,6 +604,16 @@
> 	  rtx nlabel;
> 	  int this_is_simplejump, this_is_condjump, reversep = 0;
> 	  int this_is_condjump_in_parallel;
>+
>+	  /* If one of our transformations has created more REGs we
>+	     must rerun reg_scan or else we risk missed optimizations,
>+	     erroneous optimizations, or even worse a crash.  */
>+	  if (after_regscan &&
>+	      old_max_reg < max_reg_num ())
>+	    {
>+	      reg_scan (f, max_reg_num (), 0);
>+	      old_max_reg = max_reg_num ();
>+	    }
> #if 0
> 	  /* If NOT the first iteration, if this is the last jump pass
> 	     (just before final), do the special peephole optimizations.


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