loop fix/improvement

Jeffrey A Law law@cygnus.com
Wed Jan 20 02:09:00 GMT 1999


This fixes a minor buglet introduced by Mark's patches, and also removes
the arbitrary limit on the number of memory stores allowed in a loop before
it gives up on tracking aliases.


        * loop.c (NUM_STORES): Delete.
        (loop_store_mems): Turn into an EXPR_LIST of MEMs.
        (prescan_loop): Properly initialize loop_mems_idx.
        (note_addr_stored): Simplify using list structure instead of
        fixed sized array.
        (invariant_p, check_dbra_loop, load_mems): Similarly.

Index: loop.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/loop.c,v
retrieving revision 1.114
diff -c -3 -p -r1.114 loop.c
*** loop.c	1999/01/19 10:31:54	1.114
--- loop.c	1999/01/20 10:05:52
*************** static varray_type may_not_optimize;
*** 159,173 ****
  
  static char *moved_once;
  
! /* Array of MEMs that are stored in this loop. If there are too many to fit
!    here, we just turn on unknown_address_altered.  */
  
! #define NUM_STORES 30
! static rtx loop_store_mems[NUM_STORES];
  
- /* Index of first available slot in above array.  */
- static int loop_store_mems_idx;
- 
  typedef struct loop_mem_info {
    rtx mem;      /* The MEM itself.  */
    rtx reg;      /* Corresponding pseudo, if any.  */
--- 159,168 ----
  
  static char *moved_once;
  
! /* List of MEMs that are stored in this loop.  */
  
! static rtx loop_store_mems;
  
  typedef struct loop_mem_info {
    rtx mem;      /* The MEM itself.  */
    rtx reg;      /* Corresponding pseudo, if any.  */
*************** constant_high_bytes (p, loop_start)
*** 2356,2362 ****
  /* Scan a loop setting the variables `unknown_address_altered',
     `num_mem_sets', `loop_continue', `loops_enclosed', `loop_has_call',
     `loop_has_volatile', and `loop_has_tablejump'.
!    Also, fill in the arrays `loop_mems' and `loop_store_mems'.  */
  
  static void
  prescan_loop (start, end)
--- 2351,2357 ----
  /* Scan a loop setting the variables `unknown_address_altered',
     `num_mem_sets', `loop_continue', `loops_enclosed', `loop_has_call',
     `loop_has_volatile', and `loop_has_tablejump'.
!    Also, fill in the array `loop_mems' and the list `loop_store_mems'.  */
  
  static void
  prescan_loop (start, end)
*************** prescan_loop (start, end)
*** 2377,2383 ****
    loop_has_call = 0;
    loop_has_volatile = 0;
    loop_has_tablejump = 0;
!   loop_store_mems_idx = 0;
    loop_mems_idx = 0;
  
    num_mem_sets = 0;
--- 2372,2378 ----
    loop_has_call = 0;
    loop_has_volatile = 0;
    loop_has_tablejump = 0;
!   loop_store_mems = NULL_RTX;
    loop_mems_idx = 0;
  
    num_mem_sets = 0;
*************** note_addr_stored (x, y)
*** 2981,2988 ****
       rtx x;
       rtx y ATTRIBUTE_UNUSED;
  {
-   register int i;
- 
    if (x == 0 || GET_CODE (x) != MEM)
      return;
  
--- 2976,2981 ----
*************** note_addr_stored (x, y)
*** 2996,3018 ****
  
    if (unknown_address_altered)
      return;
- 
-   for (i = 0; i < loop_store_mems_idx; i++)
-     if (rtx_equal_p (XEXP (loop_store_mems[i], 0), XEXP (x, 0)))
-       {
- 	/* We are storing at the same address as previously noted.  Save the
- 	   wider reference.  */
- 	if (GET_MODE_SIZE (GET_MODE (x))
- 	    > GET_MODE_SIZE (GET_MODE (loop_store_mems[i])))
- 	  loop_store_mems[i] = x;
- 	break;
-       }
  
!   if (i == NUM_STORES)
!     unknown_address_altered = 1;
! 
!   else if (i == loop_store_mems_idx)
!     loop_store_mems[loop_store_mems_idx++] = x;
  }
  
  /* Return nonzero if the rtx X is invariant over the current loop.
--- 2989,2996 ----
  
    if (unknown_address_altered)
      return;
  
!   loop_store_mems = gen_rtx_EXPR_LIST (VOIDmode, x, loop_store_mems);
  }
  
  /* Return nonzero if the rtx X is invariant over the current loop.
*************** invariant_p (x)
*** 3031,3036 ****
--- 3009,3015 ----
    register enum rtx_code code;
    register char *fmt;
    int conditional = 0;
+   rtx mem_list_entry;
  
    if (x == 0)
      return 1;
*************** invariant_p (x)
*** 3093,3107 ****
        if (RTX_UNCHANGING_P (x))
  	break;
  
!       /* If we filled the table (or had a subroutine call), any location
! 	 in memory could have been clobbered.  */
        if (unknown_address_altered)
  	return 0;
  
        /* See if there is any dependence between a store and this load.  */
!       for (i = loop_store_mems_idx - 1; i >= 0; i--)
! 	if (true_dependence (loop_store_mems[i], VOIDmode, x, rtx_varies_p))
! 	  return 0;
  
        /* It's not invalidated by a store in memory
  	 but we must still verify the address is invariant.  */
--- 3072,3091 ----
        if (RTX_UNCHANGING_P (x))
  	break;
  
!       /* If we had a subroutine call, any location in memory could have been
! 	 clobbered.  */
        if (unknown_address_altered)
  	return 0;
  
        /* See if there is any dependence between a store and this load.  */
!       mem_list_entry = loop_store_mems;
!       while (mem_list_entry)
! 	{
! 	  if (true_dependence (XEXP (mem_list_entry, 0), VOIDmode,
! 			       x, rtx_varies_p))
! 	    return 0;
! 	  mem_list_entry = XEXP (mem_list_entry, 1);
! 	}
  
        /* It's not invalidated by a store in memory
  	 but we must still verify the address is invariant.  */
*************** check_dbra_loop (loop_end, insn_count, l
*** 6804,6810 ****
  	  if (num_mem_sets == 1)
  	    reversible_mem_store
  	      = (! unknown_address_altered
! 		 && ! invariant_p (XEXP (loop_store_mems[0], 0)));
  	}
        else
  	return 0;
--- 6788,6794 ----
  	  if (num_mem_sets == 1)
  	    reversible_mem_store
  	      = (! unknown_address_altered
! 		 && ! invariant_p (XEXP (loop_store_mems, 0)));
  	}
        else
  	return 0;
*************** load_mems (scan_start, end, loop_top, st
*** 8427,8436 ****
        /* Actually move the MEMs.  */
        for (i = 0; i < loop_mems_idx; ++i) 
  	{
- 	  int j;
  	  int written = 0;
  	  rtx reg;
  	  rtx mem = loop_mems[i].mem;
  
  	  if (MEM_VOLATILE_P (mem) 
  	      || invariant_p (XEXP (mem, 0)) != 1)
--- 8411,8420 ----
        /* Actually move the MEMs.  */
        for (i = 0; i < loop_mems_idx; ++i) 
  	{
  	  int written = 0;
  	  rtx reg;
  	  rtx mem = loop_mems[i].mem;
+ 	  rtx mem_list_entry;
  
  	  if (MEM_VOLATILE_P (mem) 
  	      || invariant_p (XEXP (mem, 0)) != 1)
*************** load_mems (scan_start, end, loop_top, st
*** 8439,8455 ****
  
  	  /* Go through the MEMs written to in the loop to see if this
  	     one is aliased by one of them.  */
! 	  for (j = 0; j < loop_store_mems_idx; ++j) 
  	    {
! 	      if (rtx_equal_p (mem, loop_store_mems[j]))
  		written = 1;
! 	      else if (true_dependence (loop_store_mems[j], VOIDmode,
  					mem, rtx_varies_p))
  		{
  		  /* MEM is indeed aliased by this store.  */
  		  loop_mems[i].optimize = 0;
  		  break;
  		}
  	    }
  	  
  	  /* If this MEM is written to, we must be sure that there
--- 8423,8441 ----
  
  	  /* Go through the MEMs written to in the loop to see if this
  	     one is aliased by one of them.  */
! 	  mem_list_entry = loop_store_mems;
! 	  while (mem_list_entry)
  	    {
! 	      if (rtx_equal_p (mem, XEXP (mem_list_entry, 0)))
  		written = 1;
! 	      else if (true_dependence (XEXP (mem_list_entry, 0), VOIDmode,
  					mem, rtx_varies_p))
  		{
  		  /* MEM is indeed aliased by this store.  */
  		  loop_mems[i].optimize = 0;
  		  break;
  		}
+ 	      mem_list_entry = XEXP (mem_list_entry, 1);
  	    }
  	  
  	  /* If this MEM is written to, we must be sure that there



More information about the Gcc-patches mailing list