This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: flow still deleting important labels
- To: law at cygnus dot com
- Subject: Re: flow still deleting important labels
- From: Richard Henderson <rth at cygnus dot com>
- Date: Sun, 28 Mar 1999 16:57:57 -0800
- Cc: egcs-bugs at egcs dot cygnus dot com, egcs-patches at egcs dot cygnus dot com
- References: <19990328151310.B18408@cygnus.com> <4786.922662798@upchuck>
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)
{