This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
suspected bug in reorg.c
- To: egcs-bugs at cygnus dot com
- Subject: suspected bug in reorg.c
- From: Alan Lehotsky <lehotsky at tiac dot net>
- Date: Sat, 20 Jun 1998 12:00:08 -0500
- Cc: kenner at vlsi1 dot ultra dot nyu dot edu, tiemann at cygnus dot com
I'm working on the Analog Devices SHARC DSP port, and I've encountered
a problem with delay-slot filling.
The SHARC has delay slots which are NOT identical. For example, in a
function call, there are two delay slots that can hold compute instructions.
However, the first slot can take either a compute OR a shift-immediate, while
the second slot can only have a compute. In addition, no delayed instruction
can reference R2, which is destroyed
I've written this as:
;; Regular call only has 2 slots
;;
;; CJUMP (PC, addr)(DB);
;; <compute|shiftimm>,dm(i7,m7)=r2;
;; <compute>,dm(i7,m7)=pc;
;;
(define_delay (and (eq_attr "type" "call") (eq_attr "delayable" "cjump"))
[(and (ior(eq_attr "type" "shiftimm") (eq_attr "computable" "true"))
(and (eq_attr "length" "1")
(eq (symbol_ref "eligible_for_call_p (insn)")
(const_int 1))))
(nil) (nil)
(and (eq_attr "computable" "true")
(and (eq_attr "length" "1")
(eq (symbol_ref "eligible_for_call_p (insn)")
(const_int 1))))
(nil) (nil)
])
In reorg, it looks to me like the code carefully evaluates the function
for the slot, but then in the backward's scan, it pushes the SECOND
delay candidate instruction it finds onto the front of the list - so now,
the slots
aren't aligned with the "case" that matches.
trial = try_split (pat, trial, 1);
next_trial = prev_nonnote_insn (trial);
if (eligible_for_delay (insn, slots_filled, trial, flags))
{
/* In this case, we are searching backward, so if we
find insns to put on the delay list, we want
to put them at the head, rather than the
tail, of the list. */
update_reg_dead_notes (trial, insn);
delay_list = gen_rtx_INSN_LIST (VOIDmode,
trial, delay_list);
update_block (trial, trial);
delete_insn (trial);
if (slots_to_fill == ++slots_filled)
break;
So, if I had RTL that looked roughly like
(set (reg:SI R4) (plus:SI (reg:SI R4) (const_int 1)))
(set (reg:SI R8) (ashift:SI (reg:SI R8) (const_int 2)))
...
<< my call with 2 delay slots... >>
I end up seeing delayed instructions that are in the sequence...
(call (something))
(set (reg:SI R4) (plus:SI (reg:SI R4) (const_int 1)))
(set (reg:SI R8) (ashift:SI (reg:SI R8) (const_int 2)))
and that shift can't be in the second slot.
As far as I can tell, none of the ports in the EGCS distribution have delay
slots
like this. It looks like this code was probably never exercised in its full
generality.
Anybody else encounter this and have a patch, or do I have to put my
thinking cap
on :-)
-- Al Lehotsky
------------------------------------------------------------------------
Quality Software Management
http://www.tiac.net/users/lehotsky
lehotsky@tiac.net
(978)287-0435 Voice
(978)287-0436 Fax/Data
Software Process Improvement and Management Consulting
Language Design and Compiler Implementation