This is the mail archive of the gcc-bugs@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: flow still deleting important labels


On Sun, Mar 28, 1999 at 04:13:18PM -0700, Jeffrey A Law wrote:
>   > In the second (-mno-gas), the initial rtl has the label in
>   > the constant pool, but no REG_LABEL note.  So jump1 purges
>   > the label.  Curious.  Looking again I see the reference in
>   > the constant pool set to zero...  I'll check this some more.
>   > 
> Thanks.  Sounds like I should dig some more.  It was awful late when I sent
> that message :-)

Ok, sanity check me here.  I found enough places we were doing
the wrong thing wrt REG_LABEL I can't believe I'm not skewed.

Basic problem -- expand_builtin_setjmp puts a label in memory.
The code it generates to do that doesn't contain a REG_LABEL.
Secondary problems exist in that the REG_LABEL keeps vanishing.

In the patch below, I've marked parts with `>>> [N]' for reference.

In [0], I figure force_reg is as good a way as any to get the
proper notes installed.  [1] is in support of that.  Whether this
is a common enough thing to dirty force_reg is open to debate.
So this gets us the proper set up in .rtl.

In [2], our REG_LABEL vanishes for the first time.  At first I'd
just put in the check for REG_EQUAL, but that failed in jump2
when it isn't a REG_EQUAL anymore, and there are two of them anyway --

(insn/i 70 68 71 (set (reg:SI 19 %r19)
        (mem:SI (lo_sum:SI (reg:SI 19 %r19)
                (symbol_ref/u:SI ("*L$C0006"))) 0)) 63 {reload_outsi+2}
    (insn_list 68 (insn_list 68 (nil)))
    (expr_list:REG_EQUIV (mem:SI (plus:SI (reg:SI 3 %r3)
                (const_int 44)) 0)
        (expr_list:REG_LABEL (code_label/i 76 72 432 65 "")
            (expr_list:REG_EQUIV (label_ref:SI 76)
                (nil)))))

Then I discovered [3], where we weren't actually _doing_ anything
with the REG_LABEL once it is there.

[4] is a bit I thought I needed from the first debugging session;
it doesn't actually trigger on this test case, but I don't know 
that it isn't a good idea either.

So how did this work before, anyway?


r~


	* cse.c (cse_insn): If we add a REG_EQUAL for a label, add a 
	REG_LABEL too.
	* explow.c (force_reg): Likewise.
	* expr.c (expand_builtin_setjmp): Force the label into a register.
	* jump.c (init_label_info): Don't clear REG_LABEL notes.
	(mark_all_labels): Look for REG_LABEL notes and increment 
	reference counts appropriately.

Index: cse.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cse.c,v
retrieving revision 1.69
diff -c -p -d -r1.69 cse.c
*** cse.c	1999/03/22 13:55:22	1.69
--- cse.c	1999/03/29 00:38:55
*************** cse_insn (insn, libcall_insn) >>> [4]
*** 7227,7232 ****
--- 7227,7245 ----
  	    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,
  						  src_const, REG_NOTES (insn));
  
+ 	  /* If we're adding an REG_EQUAL for a LABEL_REF, make sure there's
+ 	     a REG_LABEL to go along with it.  */
+ 	  if (GET_CODE (src_const) == LABEL_REF)
+ 	    {
+ 	      tem = find_reg_note (insn, REG_LABEL, NULL_RTX);
+ 	      if (tem)
+ 		XEXP (tem, 0) = XEXP (src_const, 0);
+ 	      else
+ 		REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL,
+ 						      XEXP (src_const, 0),
+ 						      REG_NOTES (insn));
+ 	    }
+ 
            /* If storing a constant value in a register that
  	     previously held the constant value 0,
  	     record this fact with a REG_WAS_0 note on this insn.
Index: explow.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/explow.c,v
retrieving revision 1.25
diff -c -p -d -r1.25 explow.c
*** explow.c	1999/03/19 08:50:01	1.25
--- explow.c	1999/03/29 00:38:55
*************** force_reg (mode, x) >>> [1]
*** 704,709 ****
--- 704,720 ----
  	XEXP (note, 0) = x;
        else
  	REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, x, REG_NOTES (insn));
+ 
+       /* Remember to DTRT with labels.  */
+       if (GET_CODE (x) == LABEL_REF)
+ 	{
+ 	  note = find_reg_note (insn, REG_LABEL, NULL_RTX);
+ 	  if (note)
+ 	    XEXP (note, 0) = XEXP (x, 0);
+ 	  else
+ 	    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL, XEXP (x, 0),
+ 						  REG_NOTES (insn));
+ 	}
      }
    return temp;
  }
Index: expr.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.132
diff -c -p -d -r1.132 expr.c
*** expr.c	1999/03/23 22:33:35	1.132
--- expr.c	1999/03/29 00:38:55
*************** expand_builtin_setjmp (buf_addr, target, >>> [0]
*** 8460,8466 ****
  		  (gen_rtx_MEM (Pmode,
  				plus_constant (buf_addr,
  					       GET_MODE_SIZE (Pmode)))),
! 		  gen_rtx_LABEL_REF (Pmode, lab1));
  
    stack_save = gen_rtx_MEM (sa_mode,
  			    plus_constant (buf_addr,
--- 8460,8466 ----
  		  (gen_rtx_MEM (Pmode,
  				plus_constant (buf_addr,
  					       GET_MODE_SIZE (Pmode)))),
! 		  force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, lab1)));
  
    stack_save = gen_rtx_MEM (sa_mode,
  			    plus_constant (buf_addr,
Index: jump.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/jump.c,v
retrieving revision 1.55
diff -c -p -d -r1.55 jump.c
*** jump.c	1999/03/10 19:45:18	1.55
--- jump.c	1999/03/29 00:38:56
*************** init_label_info (f) >>> [2]
*** 2057,2074 ****
  	LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
        else if (GET_CODE (insn) == JUMP_INSN)
  	JUMP_LABEL (insn) = 0;
        else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
  	{
! 	  rtx note, next;
  
  	  for (note = REG_NOTES (insn); note; note = next)
  	    {
  	      next = XEXP (note, 1);
  	      if (REG_NOTE_KIND (note) == REG_LABEL
! 		  && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
  		remove_note (insn, note);
  	    }
  	}
        if (INSN_UID (insn) > largest_uid)
  	largest_uid = INSN_UID (insn);
      }
--- 2057,2079 ----
  	LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
        else if (GET_CODE (insn) == JUMP_INSN)
  	JUMP_LABEL (insn) = 0;
+ #if 0
+       /* ??? Who are you to decide there really isn't a reference.  */
        else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
  	{
! 	  rtx note, next, tmp;
  
  	  for (note = REG_NOTES (insn); note; note = next)
  	    {
  	      next = XEXP (note, 1);
  	      if (REG_NOTE_KIND (note) == REG_LABEL
! 		  && ! (reg_mentioned_p (XEXP (note, 0), PATTERN (insn))
! 			|| ((tmp = find_reg_note (insn, REG_EQUAL, NULL_RTX))
! 			    && XEXP (XEXP (tmp, 0), 0) == XEXP (note, 0))))
  		remove_note (insn, note);
  	    }
  	}
+ #endif
        if (INSN_UID (insn) > largest_uid)
  	largest_uid = INSN_UID (insn);
      }
*************** mark_all_labels (f, cross_jump) >>> [3]
*** 2134,2139 ****
--- 2139,2151 ----
    for (insn = f; insn; insn = NEXT_INSN (insn))
      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
        {
+ 	if (! INSN_DELETED_P (insn) && GET_CODE (insn) == INSN)
+ 	  {
+ 	    rtx note = find_reg_note (insn, REG_LABEL, NULL_RTX);
+ 	    if (note)
+ 	      ++LABEL_NUSES (XEXP (note, 0));
+ 	  }
+ 
  	mark_jump_label (PATTERN (insn), insn, cross_jump);
  	if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN)
  	  {


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