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 remove unpurged notes containing addressofs


Hi Guys,

  With approval from Richard Henderson I have applied the following
  patch to function.c.  It fixes an abort when compiling the gcc
  testcase compile/990829-1.c, where a REG_EQUIV note containing an
  ADDRESSOF could not be purged because the mode of the MEM in the
  replacement pattern was different from the mode in the note.

Cheers
	Nick


Fri Nov  5 10:07:25 1999  Nick Clifton  <nickc@cygnus.com>

	* function.c (is_addressof): New function.  Returns true if
	the given piece of RTL is an ADDRESSOF.
	(purge_addressof_1): Make boolean.  Return false if the
	ADDRESSOFs could not be purged.
	(purge_addressof): If ADDRESSOFs could not be purged from the
	notes attached to an insn, remove the offending note(s),
	unless they are attached to a libcall.

Index: function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.130
diff -p -r1.130 function.c
*** function.c	1999/11/05 06:49:38	1.130
--- function.c	1999/11/05 10:10:33
*************** static int all_blocks		PROTO((tree, tree
*** 268,275 ****
  static int *record_insns	PROTO((rtx)) ATTRIBUTE_UNUSED;
  static int contains		PROTO((rtx, int *));
  static void put_addressof_into_stack PROTO((rtx, struct hash_table *));
! static void purge_addressof_1	PROTO((rtx *, rtx, int, int, 
  				       struct hash_table *));
  static struct hash_entry *insns_for_mem_newfunc PROTO((struct hash_entry *,
  						       struct hash_table *,
  						       hash_table_key));
--- 268,276 ----
  static int *record_insns	PROTO((rtx)) ATTRIBUTE_UNUSED;
  static int contains		PROTO((rtx, int *));
  static void put_addressof_into_stack PROTO((rtx, struct hash_table *));
! static boolean purge_addressof_1 PROTO((rtx *, rtx, int, int, 
  				       struct hash_table *));
+ static int is_addressof		PROTO ((rtx *, void *));
  static struct hash_entry *insns_for_mem_newfunc PROTO((struct hash_entry *,
  						       struct hash_table *,
  						       hash_table_key));
*************** static rtx purge_addressof_replacements;
*** 2765,2773 ****
  
  /* Helper function for purge_addressof.  See if the rtx expression at *LOC
     in INSN needs to be changed.  If FORCE, always put any ADDRESSOFs into
!    the stack.  */
  
! static void
  purge_addressof_1 (loc, insn, force, store, ht)
       rtx *loc;
       rtx insn;
--- 2766,2775 ----
  
  /* Helper function for purge_addressof.  See if the rtx expression at *LOC
     in INSN needs to be changed.  If FORCE, always put any ADDRESSOFs into
!    the stack.  If the function returns FALSE then the replacement could not
!    be made.  */
  
! static boolean
  purge_addressof_1 (loc, insn, force, store, ht)
       rtx *loc;
       rtx insn;
*************** purge_addressof_1 (loc, insn, force, sto
*** 2778,2790 ****
    RTX_CODE code;
    int i, j;
    const char *fmt;
  
    /* Re-start here to avoid recursion in common cases.  */
   restart:
  
    x = *loc;
    if (x == 0)
!     return;
  
    code = GET_CODE (x);
  
--- 2780,2793 ----
    RTX_CODE code;
    int i, j;
    const char *fmt;
+   boolean result = true;
  
    /* Re-start here to avoid recursion in common cases.  */
   restart:
  
    x = *loc;
    if (x == 0)
!     return true;
  
    code = GET_CODE (x);
  
*************** purge_addressof_1 (loc, insn, force, sto
*** 2793,2801 ****
       memory.  */
    if (code == SET)
      {
!       purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
!       purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
!       return;
      }
  
    else if (code == ADDRESSOF && GET_CODE (XEXP (x, 0)) == MEM)
--- 2796,2804 ----
       memory.  */
    if (code == SET)
      {
!       result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
!       result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
!       return result;
      }
  
    else if (code == ADDRESSOF && GET_CODE (XEXP (x, 0)) == MEM)
*************** purge_addressof_1 (loc, insn, force, sto
*** 2807,2813 ****
  
        if (validate_change (insn, loc, sub, 0)
  	  || validate_replace_rtx (x, sub, insn))
! 	return;
    
        start_sequence ();
        sub = force_operand (sub, NULL_RTX);
--- 2810,2816 ----
  
        if (validate_change (insn, loc, sub, 0)
  	  || validate_replace_rtx (x, sub, insn))
! 	return true;
    
        start_sequence ();
        sub = force_operand (sub, NULL_RTX);
*************** purge_addressof_1 (loc, insn, force, sto
*** 2818,2824 ****
        insns = gen_sequence ();
        end_sequence ();
        emit_insn_before (insns, insn);
!       return;
      }
  
    else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
--- 2821,2827 ----
        insns = gen_sequence ();
        end_sequence ();
        emit_insn_before (insns, insn);
!       return true;
      }
  
    else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
*************** purge_addressof_1 (loc, insn, force, sto
*** 2853,2859 ****
  		if (rtx_equal_p (x, XEXP (tem, 0)))
  		  {
  		    *loc = XEXP (XEXP (tem, 1), 0);
! 		    return;
  		  }
  
  	      /* See comment for purge_addressof_replacements. */
--- 2856,2862 ----
  		if (rtx_equal_p (x, XEXP (tem, 0)))
  		  {
  		    *loc = XEXP (XEXP (tem, 1), 0);
! 		    return true;
  		  }
  
  	      /* See comment for purge_addressof_replacements. */
*************** purge_addressof_1 (loc, insn, force, sto
*** 2896,2903 ****
  		    return;
  		  }
  
! 	      /* There should always be such a replacement.  */
! 	      abort ();
  	    }
  
  	  size_x = GET_MODE_BITSIZE (GET_MODE (x));
--- 2899,2912 ----
  		    return;
  		  }
  
! 	      /* Sometimes we may not be able to find the replacement.  For
! 		 example when the original insn was a MEM in a wider mode,
! 		 and the note is part of a sign extension of a narrowed
! 		 version of that MEM.  Gcc testcase compile/990829-1.c can
! 		 generate an example of this siutation.  Rather than complain
! 		 we return false, which will prompt our caller to remove the
! 		 offending note.  */
! 	      return false;
  	    }
  
  	  size_x = GET_MODE_BITSIZE (GET_MODE (x));
*************** purge_addressof_1 (loc, insn, force, sto
*** 2989,2995 ****
  				      purge_bitfield_addressof_replacements));
  
  	      /* We replaced with a reg -- all done.  */
! 	      return;
  	    }
  	}
  
--- 2998,3004 ----
  				      purge_bitfield_addressof_replacements));
  
  	      /* We replaced with a reg -- all done.  */
! 	      return true;
  	    }
  	}
  
*************** purge_addressof_1 (loc, insn, force, sto
*** 3007,3019 ****
  		if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
  		  {
  		    XEXP (XEXP (tem, 1), 0) = sub;
! 		    return;
  		  }
  	      purge_addressof_replacements
  		= gen_rtx (EXPR_LIST, VOIDmode, XEXP (x, 0),
  			   gen_rtx_EXPR_LIST (VOIDmode, sub,
  					      purge_addressof_replacements));
! 	      return;
  	    }
  	  goto restart;
  	}
--- 3016,3028 ----
  		if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
  		  {
  		    XEXP (XEXP (tem, 1), 0) = sub;
! 		    return true;
  		  }
  	      purge_addressof_replacements
  		= gen_rtx (EXPR_LIST, VOIDmode, XEXP (x, 0),
  			   gen_rtx_EXPR_LIST (VOIDmode, sub,
  					      purge_addressof_replacements));
! 	      return true;
  	    }
  	  goto restart;
  	}
*************** purge_addressof_1 (loc, insn, force, sto
*** 3028,3036 ****
      }
    else if (code == SET)
      {
!       purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
!       purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
!       return;
      }
  
    /* Scan all subexpressions. */
--- 3037,3045 ----
      }
    else if (code == SET)
      {
!       result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
!       result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
!       return result;
      }
  
    /* Scan all subexpressions. */
*************** purge_addressof_1 (loc, insn, force, sto
*** 3038,3048 ****
    for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
      {
        if (*fmt == 'e')
! 	purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
        else if (*fmt == 'E')
  	for (j = 0; j < XVECLEN (x, i); j++)
! 	  purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
      }
  }
  
  /* Return a new hash table entry in HT.  */
--- 3047,3059 ----
    for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
      {
        if (*fmt == 'e')
! 	result &= purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
        else if (*fmt == 'E')
  	for (j = 0; j < XVECLEN (x, i); j++)
! 	  result &= purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
      }
+ 
+   return result;
  }
  
  /* Return a new hash table entry in HT.  */
*************** compute_insns_for_mem (insns, last_insn,
*** 3162,3167 ****
--- 3173,3188 ----
  	}
  }
  
+ /* Helper function for purge_addressof called through for_each_rtx.
+    Returns true iff the rtl is an ADDRESSOF.  */
+ static int
+ is_addressof (rtl, data)
+      rtx * rtl;
+      void * data ATTRIBUTE_UNUSED;
+ {
+   return GET_CODE (* rtl) == ADDRESSOF;
+ }
+ 
  /* Eliminate all occurrences of ADDRESSOF from INSNS.  Elide any remaining
     (MEM (ADDRESSOF)) patterns, and force any needed registers into the
     stack.  */
*************** purge_addressof (insns)
*** 3190,3198 ****
      if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
  	|| GET_CODE (insn) == CALL_INSN)
        {
! 	purge_addressof_1 (&PATTERN (insn), insn,
! 			   asm_noperands (PATTERN (insn)) > 0, 0, &ht);
! 	purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, &ht);
        }
  
    /* Clean up.  */
--- 3211,3240 ----
      if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
  	|| GET_CODE (insn) == CALL_INSN)
        {
! 	if (! purge_addressof_1 (&PATTERN (insn), insn,
! 				 asm_noperands (PATTERN (insn)) > 0, 0, &ht))
! 	  /* If we could not replace the ADDRESSOFs in the insn,
! 	     something is wrong.  */
! 	  abort ();
! 	
! 	if (! purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, &ht))
! 	  {
! 	    /* If we could not replace the ADDRESSOFs in the insn's notes,
! 	       we can just remove the offending notes instead.  */
! 	    rtx note;
! 
! 	    for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
! 	      {
! 		/* If we find a REG_RETVAL note then the insn is a libcall.
! 		   Such insns must have REG_EQUAL notes as well, in order
! 		   for later passes of the compiler to work.  So it is not
! 		   safe to delete the notes here, and instead we abort.  */
! 		if (REG_NOTE_KIND (note) == REG_RETVAL)
! 		  abort ();
! 		if (for_each_rtx (& note, is_addressof, NULL))
! 		  remove_note (insn, note);
! 	      }
! 	  }
        }
  
    /* Clean up.  */

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