Fix to validate_replace_src

Richard Kenner kenner@vlsi1.ultra.nyu.edu
Sat Feb 17 11:55:00 GMT 2001


This fixes the problems reported overnight and also puts in a version
of Jan's patch.

Tested on Alphaev6, but I also checked the blowup case on x86.

Sat Feb 17 14:48:30 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
			  Jan Hubicka  <jh@suse.cz>

	* recog.c (validate_replace_src_1): New.
	(validate_replace_src_data): Likewise.
	(validate_replace_src): Use note_uses.
	* rtl.h (note_uses): Declare.
	* rtlanal.c (note_uses): New.

*** rtl.h	2001/02/13 20:43:13	1.242
--- rtl.h	2001/02/17 19:35:59
*************** extern void note_stores			PARAMS ((rtx,
*** 1404,1407 ****
--- 1404,1410 ----
  						 void (*) (rtx, rtx, void *),
  						 void *));
+ extern void note_uses			PARAMS ((rtx *,
+ 						 void (*) (rtx *, void *),
+ 						 void *));
  extern rtx reg_set_last			PARAMS ((rtx, rtx));
  extern int dead_or_set_p		PARAMS ((rtx, rtx));
*** rtlanal.c	2001/02/13 20:43:13	1.86
--- rtlanal.c	2001/02/17 19:36:04
*************** note_stores (x, fun, data)
*** 1302,1305 ****
--- 1301,1387 ----
      for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
        note_stores (XVECEXP (x, 0, i), fun, data);
+ }
+ 
+ /* Like notes_stores, but call FUN for each expression that is being
+    referenced in PBODY, a pointer to the PATTERN of an insn.  We only call
+    FUN for each expression, not any interior subexpressions.  FUN receives a
+    pointer to the expression and the DATA passed to this function.
+ 
+    Note that this is not quite the same test as that done in reg_referenced_p
+    since that considers something as being referenced if it is being
+    partially set, while we do not.  */
+ 
+ void
+ note_uses (pbody, fun, data)
+      rtx *pbody;
+      void (*fun) PARAMS ((rtx *, void *));
+      void *data;
+ {
+   rtx body = *pbody;
+   int i;
+ 
+   switch (GET_CODE (body))
+     {
+     case COND_EXEC:
+       (*fun) (&COND_EXEC_TEST (body), data);
+       note_uses (&COND_EXEC_CODE (body), fun, data);
+       return;
+ 
+     case PARALLEL:
+       for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
+ 	note_uses (&XVECEXP (body, 0, i), fun, data);
+       return;
+ 
+     case USE:
+       (*fun) (&XEXP (body, 0), data);
+       return;
+ 
+     case ASM_OPERANDS:
+       for (i = ASM_OPERANDS_INPUT_LENGTH (body) - 1; i >= 0; i--)
+ 	(*fun) (&ASM_OPERANDS_INPUT (body, i), data);
+       return;
+ 
+     case TRAP_IF:
+       (*fun) (&TRAP_CONDITION (body), data);
+       return;
+ 
+     case UNSPEC:
+     case UNSPEC_VOLATILE:
+       for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
+ 	(*fun) (&XVECEXP (body, 0, i), data);
+       return;
+ 
+     case CLOBBER:
+       if (GET_CODE (XEXP (body, 0)) == MEM)
+ 	(*fun) (&XEXP (XEXP (body, 0), 0), data);
+       return;
+ 
+     case SET:
+       {
+ 	rtx dest = SET_DEST (body);
+ 
+ 	/* For sets we replace everything in source plus registers in memory
+ 	   expression in store and operands of a ZERO_EXTRACT.  */
+ 	(*fun) (&SET_SRC (body), data);
+ 
+ 	if (GET_CODE (dest) == ZERO_EXTRACT)
+ 	  {
+ 	    (*fun) (&XEXP (dest, 1), data);
+ 	    (*fun) (&XEXP (dest, 2), data);
+ 	  }
+ 
+ 	while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART)
+ 	  dest = XEXP (dest, 0);
+ 
+ 	if (GET_CODE (dest) == MEM)
+ 	  (*fun) (&XEXP (dest, 0), data);
+       }
+       return;
+ 
+     default:
+       /* All the other possibilities never store.  */
+       (*fun) (pbody, data);
+       return;
+     }
  }
  
*** recog.c	2001/02/16 19:14:09	1.88
--- recog.c	2001/02/17 19:36:09
*************** static rtx *find_single_use_1		PARAMS ((
*** 60,63 ****
--- 60,64 ----
  static rtx *find_constant_term_loc	PARAMS ((rtx *));
  static int insn_invalid_p		PARAMS ((rtx));
+ static void validate_replace_src_1 	PARAMS ((rtx *, void *));
  
  /* Nonzero means allow operands to be volatile.
*************** validate_replace_rtx_group (from, to, in
*** 742,745 ****
--- 743,763 ----
  }
  
+ /* Function called by note_uses to replace used subexpressions.  */
+ struct validate_replace_src_data
+   {
+     rtx from, to, insn;
+   };
+ 
+ static void
+ validate_replace_src_1 (x, data)
+      rtx *x;
+      void *data;
+ {
+   struct validate_replace_src_data *d
+     = (struct validate_replace_src_data *) data;
+ 
+   validate_replace_rtx_1 (x, d->from, d->to, d->insn);
+ }
+ 
  /* Try replacing every occurrence of FROM in INSN with TO, avoiding
     SET_DESTs.  After all changes have been made, validate by seeing if
*************** validate_replace_src (from, to, insn)
*** 750,769 ****
       rtx from, to, insn;
  {
!   if ((GET_CODE (insn) != INSN && GET_CODE (insn) != JUMP_INSN)
!       || GET_CODE (PATTERN (insn)) != SET)
!     abort ();
! 
!   validate_replace_rtx_1 (&SET_SRC (PATTERN (insn)), from, to, insn);
!   if (GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
!     validate_replace_rtx_1 (&XEXP (SET_DEST (PATTERN (insn)), 0),
! 			    from, to, insn);
!   else if (GET_CODE (SET_DEST (PATTERN (insn))) == ZERO_EXTRACT)
!     {
!       validate_replace_rtx_1 (&XEXP (SET_DEST (PATTERN (insn)), 1),
! 			      from, to, insn);
!       validate_replace_rtx_1 (&XEXP (SET_DEST (PATTERN (insn)), 2),
! 			      from, to, insn);
!     }
  
    return apply_change_group ();
  }
--- 768,777 ----
       rtx from, to, insn;
  {
!   struct validate_replace_src_data d;
  
+   d.from = from;
+   d.to = to;
+   d.insn = insn;
+   note_uses (&PATTERN (insn), validate_replace_src_1, &d);
    return apply_change_group ();
  }



More information about the Gcc-patches mailing list