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: Real purpose for failure in "Too restrictive sanity check"


> On Thu, Apr 20, 2000 at 10:33:54AM -0600, Jeffrey A Law wrote:
> > However, they are caused you recent loop.c change:
> > 
> >         * loop.c (emit_iv_add_mult):  Simplify it's input and emit
> >         REG_EQUAL note explaining the calculated value.
> > 
> > This is causing the stage1 compiler to mis-compile genattrtab.
> 
> It breaks Alpha too.  I've reverted the change.

Oops, I fell so embrassed by causing yet another breakage.  This patch looked
very innocent to me.
> 
> The problem is that it emits notes like this:
> 
> 	(insn 234 229 239 (set (reg:DI 133)
>         	(reg:DI 122)) -1 (nil)
>     	(expr_list:REG_EQUAL (reg:DI 122)
>         	(nil)))
> 
> which is wrong.  The notes must be limited to function-wide invariants.
I don't think this holds for REG_EQUAL notes. (and it don't even hold for some
REG_EQUIV notes we emit).  This looks like problem with single REG in the
REG_EQUAL note. I remember Jeff claiming this to be prohibited (even when the
reason is not clear to me). I didn't seen yet such an note emited by this code
(and I am very surprised, that loop.c uses emit_iv_add_mult to do no-op moves),
but it is probably used for giv initialization with add_val=0, since we don't strength
reduce much on i386, this didn't show to me.
Proper fix seems to be to avoid single register in the notes.

In case REG_EQUIV notes needs to be invariants, I guess my patch to gcse.c needs
fixing.  Please can someone confirm this?

Anyway can you please test a patch I will send shortly that will not emit REG_EQUAL
notes for single register?  Perhaps this will fix the problem.

I didn't bootstrapped this patch yet, but since it is just trivial change, I expect
that i386 bootstrap will not show much.

Honza

Sun Apr  9 19:15:24 CEST 2000  Jan Hubicka  <jh@suse.cz>
	* loop.c (emit_iv_add_mult):  Simplify it's input and emit REG_EQUAL note
	explaining the calculated value.

Index: egcs/gcc/loop.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/loop.c,v
retrieving revision 1.239
diff -c -3 -p -r1.239 loop.c
*** loop.c	2000/04/21 02:56:58	1.239
--- loop.c	2000/04/21 12:03:11
*************** emit_iv_add_mult (b, m, a, reg, insert_b
*** 7640,7650 ****
--- 7640,7663 ----
  {
    rtx seq;
    rtx result;
+   rtx last;
+   rtx set;
+   rtx exp;
+   enum machine_mode mode = GET_MODE (reg);
  
    /* Prevent unexpected sharing of these rtx.  */
    a = copy_rtx (a);
    b = copy_rtx (b);
  
+   /* We may be faced to (plus (symbol_ref) (const_int)).  We want to simplify this
+      to CONST rtx.  */
+   exp = simplify_rtx (a);
+   if (exp)
+     a = exp;
+   exp = simplify_rtx (b);
+   if (exp)
+     b = exp;
+ 
    /* Increase the lifetime of any invariants moved further in code.  */
    update_reg_last_use (a, insert_before);
    update_reg_last_use (b, insert_before);
*************** emit_iv_add_mult (b, m, a, reg, insert_b
*** 7657,7663 ****
    seq = gen_sequence ();
    end_sequence ();
  
!   emit_insn_before (seq, insert_before);
  
    /* It is entirely possible that the expansion created lots of new 
       registers.  Iterate over the sequence we just created and 
--- 7670,7676 ----
    seq = gen_sequence ();
    end_sequence ();
  
!   last = emit_insn_before (seq, insert_before);
  
    /* It is entirely possible that the expansion created lots of new 
       registers.  Iterate over the sequence we just created and 
*************** emit_iv_add_mult (b, m, a, reg, insert_b
*** 7668,7681 ****
        int i;
        for (i = 0; i < XVECLEN (seq, 0); ++i)
  	{
! 	  rtx set = single_set (XVECEXP (seq, 0, i));
  	  if (set && GET_CODE (SET_DEST (set)) == REG)
  	    record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
  	}
      }
!   else if (GET_CODE (seq) == SET
! 	   && GET_CODE (SET_DEST (seq)) == REG)
!     record_base_value (REGNO (SET_DEST (seq)), SET_SRC (seq), 0);
  }
  
  /* Test whether A * B can be computed without
--- 7681,7730 ----
        int i;
        for (i = 0; i < XVECLEN (seq, 0); ++i)
  	{
! 	  set = single_set (XVECEXP (seq, 0, i));
  	  if (set && GET_CODE (SET_DEST (set)) == REG)
  	    record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
  	}
+       last = XVECEXP (seq, 0, i - 1);
+     }
+   else
+     {
+       set = single_set (last);
+       if (set && GET_CODE (SET_DEST (set)) == REG)
+         record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
      }
!   if (!last)
!     return;
!   /* Sequence really ought to end by set storing final value to the register.
!     
!      Attach note indicating expression we've just calculated to it.  This is important
!      for second run of loop optimizer to understand strength reduced givs from
!      the first run.  */
!   if (GET_CODE (last) != INSN)
!     abort();
!   set = single_set (last);
!   if (!set)
!     return;
!   if (SET_DEST (set) != reg)
!     abort();
! 
!   /* In case we start to emit some usefull notes to these insns, get abort here,
!      since we need to decide what information is more important.  */
!   if (find_reg_note (last, REG_EQUIV, NULL_RTX)
!       || find_reg_note (last, REG_EQUAL, NULL_RTX))
!     abort();
! 
!   /* Expression we've just caluclated.  */
!   exp = simplify_gen_binary (PLUS, mode,
! 			     simplify_gen_binary (MULT, mode, b, m),
! 			     a);
!   /* Single register REG_EQUAL notes are not allowed, and they are useless anyway.  */
!   if (REG_P (exp))
!     return;
!   REG_NOTES (last)
! 	= gen_rtx_EXPR_LIST (REG_EQUAL,
! 	    		     exp,
! 	    		     REG_NOTES (last));
  }
  
  /* Test whether A * B can be computed without

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