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]

Patch to fix delete_noop_move REG_LIBCALL handling.


Compiling gcc.c-torture/unsorted/BUG25.c on HP-PA with
-O2 yields the following bit of rtl after addressof runs:

(insn 11 23 12 (set (reg:SI 26 %r26)
        (reg:SI 26 %r26)) 68 {*pa.md:2088} (nil)
    (insn_list:REG_LIBCALL 14 (nil)))

(call_insn 12 11 14 (parallel[
            (set (reg:SI 28 %r28)
                (call (mem:SI (symbol_ref:SI ("@ffs")) 0)
                    (const_int 16 [0x10])))
            (clobber (reg:SI 2 %r2))
            (use (const_int 0 [0x0]))
        ] ) 275 {call_value_internal_symref} (nil)
    (expr_list:REG_EH_REGION (const_int -1 [0xffffffff])
        (nil))
    (expr_list (use (reg:SI 26 %r26))
        (nil)))

(insn 14 12 15 (set (reg:SI 96)
        (reg:SI 28 %r28)) 68 {*pa.md:2088} (nil)
    (insn_list:REG_RETVAL 11 (expr_list:REG_EQUAL (ffs:SI (reg:SI 26 %r26))
            (nil))))

Running life_analysis causes insn 11 to be deleted by delete_noop_moves
which orphans the REG_RETVAL note and causes problems down the line.

This patch passes make bootstrap and make check on Dec Alpha 4.0f,
HP-UX 11.0, and Solaris 7 SPARC.

ChangeLog:

Sat Oct  6 23:19:02 EDT 2001  John Wehle  (john@feith.com)

	* flow.c (delete_noop_moves): Handle REG_LIBCALL and
	REG_RETVAL notes.

Enjoy!

-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/flow.c.ORIGINAL	Thu Oct  4 01:16:10 2001
--- gcc/flow.c	Thu Oct  4 02:09:29 2001
*************** delete_noop_moves (f)
*** 779,786 ****
  	  next = NEXT_INSN (insn);
  	  if (INSN_P (insn) && noop_move_p (insn))
  	    {
! 	      /* Do not call delete_insn here to not confuse backward
! 	         pointers of LIBCALL block.  */
  	      PUT_CODE (insn, NOTE);
  	      NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  	      NOTE_SOURCE_FILE (insn) = 0;
--- 779,816 ----
  	  next = NEXT_INSN (insn);
  	  if (INSN_P (insn) && noop_move_p (insn))
  	    {
! 	      rtx note;
! 
! 	      /* If we're about to remove the first insn of a libcall
! 		 then move the libcall note to the next real insn and
! 		 update the retval note.  */
! 	      if ((note = find_reg_note (insn, REG_LIBCALL, NULL_RTX))
! 		  && XEXP (note, 0) != insn)
! 		{
! 		  rtx new_libcall_insn = next_real_insn (insn);
! 		  rtx retval_note = find_reg_note (XEXP (note, 0),
! 						   REG_RETVAL, NULL_RTX);
! 		  REG_NOTES (new_libcall_insn)
! 		    = gen_rtx_INSN_LIST (REG_LIBCALL, XEXP (note, 0),
! 					 REG_NOTES (new_libcall_insn));
! 		  XEXP (retval_note, 0) = new_libcall_insn;
! 		}
! 
! 	      /* Handle the last insn of a libcall in a similar fashion.  */
! 	      else if ((note = find_reg_note (insn, REG_RETVAL, NULL_RTX))
! 		       && XEXP (note, 0) != insn)
! 		{
! 		  rtx new_retval_insn = prev_real_insn (insn);
! 		  rtx libcall_note = find_reg_note (XEXP (note, 0),
! 						   REG_LIBCALL, NULL_RTX);
! 		  REG_NOTES (new_retval_insn)
! 		    = gen_rtx_INSN_LIST (REG_RETVAL, XEXP (note, 0),
! 					 REG_NOTES (new_retval_insn));
! 		  XEXP (libcall_note, 0) = new_retval_insn;
! 		}
! 
! 	      /* Do not call delete_insn here since that may change
! 	         the basic block boundaries which upsets some callers.  */
  	      PUT_CODE (insn, NOTE);
  	      NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  	      NOTE_SOURCE_FILE (insn) = 0;
-------------------------------------------------------------------------
|   Feith Systems  |   Voice: 1-215-646-8000  |  Email: john@feith.com  |
|    John Wehle    |     Fax: 1-215-540-5495  |                         |
-------------------------------------------------------------------------


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