suspected bug in reorg.c

Alan Lehotsky lehotsky@tiac.net
Sat Jun 20 08:59:00 GMT 1998


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



More information about the Gcc-bugs mailing list