[rtlopt] function note_all_uses and its use in var-tracking.c

Josef Zlomek zlomj9am@artax.karlin.mff.cuni.cz
Tue Feb 25 17:04:00 GMT 2003


Hi,

this patch adds a function note_all_uses which calls a user supplied function
on each use of REG or MEM in instruction. It also reports uses in interior
subexpressions.

Bootstrapped x86-64.

Josef

2003-02-25  Josef Zlomek  <zlomekj@suse.cz>

	* rtl.h (note_all_uses): New extern function.
	* rtlanal.c (note_all_uses): New function.
	* var-tracking.c (count_uses, add_uses): Changed type of parameter loc.
	(var_tracking_initialize): Use note_all_uses instead of note_uses.

Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.367.2.13
diff -c -3 -p -r1.367.2.13 rtl.h
*** rtl.h	22 Feb 2003 20:46:06 -0000	1.367.2.13
--- rtl.h	25 Feb 2003 15:18:01 -0000
*************** extern void note_stores			PARAMS ((rtx,
*** 1647,1652 ****
--- 1647,1655 ----
  extern void note_uses			PARAMS ((rtx *,
  						 void (*) (rtx *, void *),
  						 void *));
+ extern void note_all_uses		PARAMS ((rtx,
+ 						 void (*) (rtx, void *),
+ 						 void *));
  extern rtx reg_set_last			PARAMS ((rtx, rtx));
  extern int dead_or_set_p		PARAMS ((rtx, rtx));
  extern int dead_or_set_regno_p		PARAMS ((rtx, unsigned int));
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtlanal.c,v
retrieving revision 1.138.2.7
diff -c -3 -p -r1.138.2.7 rtlanal.c
*** rtlanal.c	12 Feb 2003 17:10:13 -0000	1.138.2.7
--- rtlanal.c	25 Feb 2003 15:18:01 -0000
*************** note_uses (pbody, fun, data)
*** 1828,1833 ****
--- 1828,1929 ----
      }
  }
  
+ /* Like notes_uses, but call FUN for each expression that is being
+    referenced in PBODY, a pointer to the PATTERN of an insn, and for all
+    interior subexpressions.  FUN receives a pointer to the expression and the
+    DATA passed to this function.  */
+ 
+ void
+ note_all_uses (body, fun, data)
+      rtx body;
+      void (*fun) PARAMS ((rtx, void *));
+      void *data;
+ {
+   int i;
+ 
+   if (body == NULL_RTX)
+     return;
+ 
+   switch (GET_CODE (body))
+     {
+       case REG:
+ 	(*fun) (body, data);
+ 	return;
+ 
+       case MEM:
+ 	(*fun) (body, data);
+ 	note_all_uses (XEXP (body, 0), fun, data);
+ 	return;
+ 
+       case SET:
+ 	note_all_uses (SET_SRC (body), fun, data);
+ 
+ 	/* Fallthru.  */
+       case CLOBBER:
+ 	{
+ 	  rtx dest = SET_DEST (body);
+ 
+ 	  /* Note the uses in DEST, for example the uses in
+ 	     (mem/s:DI (plus:DI (reg/v/f:DI 3 rbx [orig:81 prev ] [81])
+ 			(const_int 24 [0x18])) [0 <variable>.rtx+0 S8 A64])
+ 	   
+ 	     are (reg/v/f:DI 3 rbx [orig:81 prev ] [81])
+ 	     and (const_int 24 [0x18]).  */
+ 
+ 	  while (GET_CODE (dest) == SUBREG
+ 		 || GET_CODE (dest) == ZERO_EXTRACT
+ 		 || GET_CODE (dest) == SIGN_EXTRACT
+ 		 || GET_CODE (dest) == STRICT_LOW_PART)
+ 	    {
+ 	      if (GET_CODE (dest) == ZERO_EXTRACT
+ 		  || GET_CODE (dest) == SIGN_EXTRACT)
+ 		{
+ 		  /* Note the uses in parameters.  */
+ 		  (*fun) (XEXP (dest, 1), data);
+ 		  (*fun) (XEXP (dest, 2), data);
+ 		}
+ 	      dest = XEXP (dest, 0);
+ 	    }
+ 
+ 	  /* If the DEST is a memory, note uses in its subexpressions.  */
+ 	  if (GET_CODE (dest) == MEM)
+ 	    note_all_uses (XEXP (body, 0), fun, data);
+ 	}
+ 	return;
+ 
+       default:
+ 	{
+ 	  int length = GET_RTX_LENGTH (GET_CODE (body));
+ 	  const char *format = GET_RTX_FORMAT (GET_CODE (body));
+ 
+ 	  for (i = 0; i < length; i++)
+ 	    {
+ 	      switch (format[i])
+ 		{
+ 		  case 'e':
+ 		    note_all_uses (XEXP (body, i), fun, data);
+ 		    break;
+ 
+ 		  case 'V':
+ 		  case 'E':
+ 		    if (XVEC (body, i) != 0)
+ 		      {
+ 			int j;
+ 			for (j = 0; j < XVECLEN (body, i); j++)
+ 			  note_all_uses (XVECEXP (body, i, j), fun, data);
+ 		      }
+ 		    break;
+ 
+ 		  default:
+ 		    /* Nothing to do.  */
+ 		    break;
+ 		}
+ 	    }
+ 	}
+         return;
+     }
+ }
+ 
  /* Return nonzero if X's old contents don't survive after INSN.
     This will be true if X is (cc0) or if X is a register and
     X dies in INSN or because INSN entirely sets X.
Index: var-tracking.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/var-tracking.c,v
retrieving revision 1.1.4.23
diff -c -3 -p -r1.1.4.23 var-tracking.c
*** var-tracking.c	20 Feb 2003 16:47:12 -0000	1.1.4.23
--- var-tracking.c	25 Feb 2003 15:18:01 -0000
*************** static void attrs_htab_clear		PARAMS ((h
*** 270,278 ****
  static void attrs_htab_cleanup		PARAMS ((void *));
  
  static bool track_expr_p		PARAMS ((tree));
! static void count_uses			PARAMS ((rtx *, void *));
  static void count_stores		PARAMS ((rtx, rtx, void *));
! static void add_uses			PARAMS ((rtx *, void *));
  static void add_stores			PARAMS ((rtx, rtx, void *));
  static bool compute_bb_dataflow		PARAMS ((basic_block));
  static void hybrid_search		PARAMS ((basic_block, sbitmap,
--- 270,278 ----
  static void attrs_htab_cleanup		PARAMS ((void *));
  
  static bool track_expr_p		PARAMS ((tree));
! static void count_uses			PARAMS ((rtx, void *));
  static void count_stores		PARAMS ((rtx, rtx, void *));
! static void add_uses			PARAMS ((rtx, void *));
  static void add_stores			PARAMS ((rtx, rtx, void *));
  static bool compute_bb_dataflow		PARAMS ((basic_block));
  static void hybrid_search		PARAMS ((basic_block, sbitmap,
*************** track_expr_p (expr)
*** 774,795 ****
  
  static void
  count_uses (loc, insn)
!      rtx *loc;
       void *insn;
  {
    basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
  
!   if (GET_CODE (*loc) == REG)
      {
  #ifdef ENABLE_CHECKING
! 	if (REGNO (*loc) >= FIRST_PSEUDO_REGISTER)
  	  abort ();
  #endif
  	VTI (bb)->n_locs++;
      }
!   else if (GET_CODE (*loc) == MEM
! 	   && MEM_EXPR (*loc)
! 	   && track_expr_p (MEM_EXPR (*loc)))
      {
  	  VTI (bb)->n_locs++;
      }
--- 774,795 ----
  
  static void
  count_uses (loc, insn)
!      rtx loc;
       void *insn;
  {
    basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
  
!   if (GET_CODE (loc) == REG)
      {
  #ifdef ENABLE_CHECKING
! 	if (REGNO (loc) >= FIRST_PSEUDO_REGISTER)
  	  abort ();
  #endif
  	VTI (bb)->n_locs++;
      }
!   else if (GET_CODE (loc) == MEM
! 	   && MEM_EXPR (loc)
! 	   && track_expr_p (MEM_EXPR (loc)))
      {
  	  VTI (bb)->n_locs++;
      }
*************** count_stores (loc, expr, insn)
*** 804,810 ****
       rtx expr ATTRIBUTE_UNUSED;
       void *insn;
  {
!   count_uses (&loc, insn);
  }
  
  /* Add uses (register and memory references) LOC which will be tracked
--- 804,810 ----
       rtx expr ATTRIBUTE_UNUSED;
       void *insn;
  {
!   count_uses (loc, insn);
  }
  
  /* Add uses (register and memory references) LOC which will be tracked
*************** count_stores (loc, expr, insn)
*** 812,829 ****
  
  static void
  add_uses (loc, insn)
!      rtx *loc;
       void *insn;
  {
!   if (GET_CODE (*loc) == REG
!       || (GET_CODE (*loc) == MEM
! 	  && MEM_EXPR (*loc)
! 	  && track_expr_p (MEM_EXPR (*loc))))
      {
        basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
        location *l = VTI (bb)->locs + VTI (bb)->n_locs++;
  
!       l->loc = *loc;
        l->insn = (rtx) insn;
        l->type = LT_USE;
      }
--- 812,829 ----
  
  static void
  add_uses (loc, insn)
!      rtx loc;
       void *insn;
  {
!   if (GET_CODE (loc) == REG
!       || (GET_CODE (loc) == MEM
! 	  && MEM_EXPR (loc)
! 	  && track_expr_p (MEM_EXPR (loc))))
      {
        basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
        location *l = VTI (bb)->locs + VTI (bb)->n_locs++;
  
!       l->loc = loc;
        l->insn = (rtx) insn;
        l->type = LT_USE;
      }
*************** var_tracking_initialize ()
*** 1657,1663 ****
  	{
  	  if (INSN_P (insn))
  	    {
! 	      note_uses (&PATTERN (insn), count_uses, insn);
  	      note_stores (PATTERN (insn), count_stores, insn);
  	    }
  	}
--- 1657,1663 ----
  	{
  	  if (INSN_P (insn))
  	    {
! 	      note_all_uses (PATTERN (insn), count_uses, insn);
  	      note_stores (PATTERN (insn), count_stores, insn);
  	    }
  	}
*************** var_tracking_initialize ()
*** 1674,1680 ****
  	      int n1, n2;
  
  	      n1 = VTI (bb)->n_locs;
! 	      note_uses (&PATTERN (insn), add_uses, insn);
  	      note_stores (PATTERN (insn), add_stores, insn);
  	      n2 = VTI (bb)->n_locs - 1;
  
--- 1674,1680 ----
  	      int n1, n2;
  
  	      n1 = VTI (bb)->n_locs;
! 	      note_all_uses (PATTERN (insn), add_uses, insn);
  	      note_stores (PATTERN (insn), add_stores, insn);
  	      n2 = VTI (bb)->n_locs - 1;
  



More information about the Gcc-patches mailing list