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]

Re: execute/990628-1.c regression




--On Monday, June 11, 2001 05:27:09 PM -0700 Geoff Keating 
<geoffk@geoffk.org> wrote:

>
> Hi Mark,
>
>> native gcc.sum gcc.c-torture/execute/990628-1.c
>
> this seems to be caused by
>
> 2001-06-09  Mark Mitchell  <mark@codesourcery.com>
>
>        * toplev.c (rest_of_compilation): Remove dead code before
>        purge_addressof.
>
> The problem is that a REG_WAS_0 note pointed to an insn which had been
> deleted and so the pointer is NULL, and cse.c (around line 7488)
> wasn't expecting that.

I looked at this, and Geoff is right.  When flow blows away some
dead instructions, we get dangling REG_WAS_0 notes.  Then, loop
unrolling duplicates the instructions, tries to remap the notes,
and replaces the notes (which used to point to instructions
no longer in the instruction stream) with notes that are just NULL.

It took me a while to even figure out what we're doing with these
notes.  We're using these notes to improve instruction selection
on the AVR and the VAX.  Hardly seems worth it, really...

Anyhow, what to do.  To remove the notes when we remove the
code in life analysis (or anywhere else) is painful -- we need to
scan the entire instruction stream.  So, I'm just going to
blow away the note when it turns out not to be useful in the
unroller.

Also, this patch adds an assertion that we do succeed in remapping
other notes, and also fixes uses of GET_MODE that should should
have been GET_REG_NOTE_KIND.

Bootstrapped and tested on i686-pc-linux-gnu, installed on the
mainline.  The bug does not yet seem manifest on the branch.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2001-06-11  Mark Mitchell  <mark@codesourcery.com>

	* unroll.c (initial_reg_note_copy): Use PUT_REG_NOTE_KIND and
	REG_NOTE_KIND, not PUT_MODE and GET_MODE.
	(final_reg_note_copy): Remove REG_WAS_0 notes that are no longer
	valid.

Index: unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/unroll.c,v
retrieving revision 1.128
diff -c -p -r1.128 unroll.c
*** unroll.c	2001/05/06 19:51:19	1.128
--- unroll.c	2001/06/12 04:40:01
*************** static int *splittable_regs_updates;
*** 201,207 ****
  static void init_reg_map PARAMS ((struct inline_remap *, int));
  static rtx calculate_giv_inc PARAMS ((rtx, rtx, unsigned int));
  static rtx initial_reg_note_copy PARAMS ((rtx, struct inline_remap *));
! static void final_reg_note_copy PARAMS ((rtx, struct inline_remap *));
  static void copy_loop_body PARAMS ((struct loop *, rtx, rtx,
  				    struct inline_remap *, rtx, int,
  				    enum unroll_types, rtx, rtx, rtx, rtx));
--- 201,207 ----
  static void init_reg_map PARAMS ((struct inline_remap *, int));
  static rtx calculate_giv_inc PARAMS ((rtx, rtx, unsigned int));
  static rtx initial_reg_note_copy PARAMS ((rtx, struct inline_remap *));
! static void final_reg_note_copy PARAMS ((rtx *, struct inline_remap *));
  static void copy_loop_body PARAMS ((struct loop *, rtx, rtx,
  				    struct inline_remap *, rtx, int,
  				    enum unroll_types, rtx, rtx, rtx, rtx));
*************** initial_reg_note_copy (notes, map)
*** 1666,1672 ****
      return 0;

    copy = rtx_alloc (GET_CODE (notes));
!   PUT_MODE (copy, GET_MODE (notes));

    if (GET_CODE (notes) == EXPR_LIST)
      XEXP (copy, 0) = copy_rtx_and_substitute (XEXP (notes, 0), map, 0);
--- 1666,1672 ----
      return 0;

    copy = rtx_alloc (GET_CODE (notes));
!   PUT_REG_NOTE_KIND (copy, REG_NOTE_KIND (notes));

    if (GET_CODE (notes) == EXPR_LIST)
      XEXP (copy, 0) = copy_rtx_and_substitute (XEXP (notes, 0), map, 0);
*************** initial_reg_note_copy (notes, map)
*** 1684,1698 ****
  /* Fixup insn references in copied REG_NOTES.  */

  static void
! final_reg_note_copy (notes, map)
!      rtx notes;
       struct inline_remap *map;
  {
!   rtx note;

!   for (note = notes; note; note = XEXP (note, 1))
!     if (GET_CODE (note) == INSN_LIST)
!       XEXP (note, 0) = map->insn_map[INSN_UID (XEXP (note, 0))];
  }

  /* Copy each instruction in the loop, substituting from map as 
appropriate.
--- 1684,1721 ----
  /* Fixup insn references in copied REG_NOTES.  */

  static void
! final_reg_note_copy (notesp, map)
!      rtx *notesp;
       struct inline_remap *map;
  {
!   while (*notesp)
!     {
!       rtx note = *notesp;
!
!       if (GET_CODE (note) == INSN_LIST)
! 	{
! 	  /* Sometimes, we have a REG_WAS_0 note that points to a
! 	     deleted instruction.  In that case, we can just delete the
! 	     note.  */
! 	  if (REG_NOTE_KIND (note) == REG_WAS_0)
! 	    {
! 	      *notesp = XEXP (note, 1);
! 	      continue;
! 	    }
! 	  else
! 	    {
! 	      rtx insn = map->insn_map[INSN_UID (XEXP (note, 0))];

! 	      /* If we failed to remap the note, something is awry.  */
! 	      if (!insn)
! 		abort ();
!
! 	      XEXP (note, 0) = insn;
! 	    }
! 	}
!
!       notesp = &XEXP (note, 1);
!     }
  }

  /* Copy each instruction in the loop, substituting from map as 
appropriate.
*************** copy_loop_body (loop, copy_start, copy_e
*** 2219,2225 ****
        if ((GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
  	   || GET_CODE (insn) == CALL_INSN)
  	  && map->insn_map[INSN_UID (insn)])
! 	final_reg_note_copy (REG_NOTES (map->insn_map[INSN_UID (insn)]), map);
      }
    while (insn != copy_end);

--- 2242,2248 ----
        if ((GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
  	   || GET_CODE (insn) == CALL_INSN)
  	  && map->insn_map[INSN_UID (insn)])
! 	final_reg_note_copy (&REG_NOTES (map->insn_map[INSN_UID (insn)]), map);
      }
    while (insn != copy_end);



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