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: Compiler crash in cselib_invalidate_regno() patch


On Tue, 25 Apr 2000, Toshiyasu Morita wrote:

> Here is a patch which fixes the problem I posted earlier in gcc-bugs.
> With this patch, my file compiles correctly - please review for correctness.

This is not the right fix.  It just hides the real problem.

> !           /* For an rtx like:
> ! 
> !              (insn 867 865 869 (parallel[ 
> !                          (set (reg:SF 24 fr0)
> !                              (reg:SF 24 fr0))
> !                          (use (reg/v:PSI 48 fpscr))
> !                          (clobber (scratch:SI))
> !                      ] ) 153 {movsf_ie} (insn_list 865 (nil))
> !                  (nil))
> ! 
> !              ... unchain_one_elt_list can set *l = 0 (e.g. v->locs = 0),
> !              so we must check for this case here.  */
> ! 
> !           if (!*l)
> !              continue;

unchain_one_elt_list can never touch the locs field, so this can't be correct.

I'm currently testing the patch below.  The real problem is that we're getting
confused about which values are useless.  More specifically, in
cselib_record_sets some values may temporarily lose all their locations due to
the note_stores call, and later become useful again because of the call to
cselib_record_set.  Unfortunately, once they have been in the "useless" state,
there is nothing that prevents them from getting reclaimed.  The result is a
memory corruption bug.

OK to install if it bootstraps?

Bernd
        
	* simplify-rtx.c (check_value_useless): Delete function.
	(discard_useless_locs): Don't call it; manage N_USELES_VALUES counter
	by hand.
	(cselib_invalidate_regno): Likewise.
	(cselib_invalidate_mem_1): Likewise.
	(references_value_p): Recognize useless values by the fact that they
	have no locations.
	(discard_useless_values): Likewise.
	(add_mem_for_addr): This may turn a useless value into a useful one.
	(cselib_record_set): Likewise.

Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/simplify-rtx.c,v
retrieving revision 1.13
diff -c -p -r1.13 simplify-rtx.c
*** simplify-rtx.c	2000/04/18 20:42:00	1.13
--- simplify-rtx.c	2000/04/29 14:52:55
*************** static void unchain_one_value		PARAMS ((
*** 106,112 ****
  static void unchain_one_elt_list	PARAMS ((struct elt_list **));
  static void unchain_one_elt_loc_list	PARAMS ((struct elt_loc_list **));
  static void clear_table			PARAMS ((void));
- static int check_value_useless		PARAMS ((cselib_val *));
  static int discard_useless_locs		PARAMS ((void **, void *));
  static int discard_useless_values	PARAMS ((void **, void *));
  static void remove_useless_values	PARAMS ((void));
--- 106,111 ----
*************** get_value_hash (entry)
*** 2183,2208 ****
    return v->value;
  }
  
- /* If there are no more locations that hold a value, the value has become
-    useless.  See whether that is the case for V.  Return 1 if this has
-    just become useless.  */
- 
- static int
- check_value_useless (v)
-      cselib_val *v;
- {
-   if (v->locs != 0)
-     return 0;
- 
-   if (v->value == 0)
-     return 0;
- 
-   /* This is a marker to indicate that the value will be reclaimed.  */
-   v->value = 0;
-   n_useless_values++;
-   return 1;
- }
- 
  /* Return true if X contains a VALUE rtx.  If ONLY_USELESS is set, we
     only return true for values which point to a cselib_val whose value
     element has been set to zero, which implies the cselib_val will be
--- 2182,2187 ----
*************** references_value_p (x, only_useless)
*** 2218,2224 ****
    int i, j;
  
    if (GET_CODE (x) == VALUE
!       && (! only_useless || CSELIB_VAL_PTR (x)->value == 0))
      return 1;
  
    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
--- 2197,2203 ----
    int i, j;
  
    if (GET_CODE (x) == VALUE
!       && (! only_useless || CSELIB_VAL_PTR (x)->locs == 0))
      return 1;
  
    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
*************** discard_useless_locs (x, info)
*** 2245,2250 ****
--- 2224,2230 ----
  {
    cselib_val *v = (cselib_val *)*x;
    struct elt_loc_list **p = &v->locs;
+   int had_locs = v->locs != 0;
  
    while (*p)
      {
*************** discard_useless_locs (x, info)
*** 2254,2262 ****
  	p = &(*p)->next;
      }
  
!   if (check_value_useless (v))
!     values_became_useless = 1;
! 
    return 1;
  }
  
--- 2234,2244 ----
  	p = &(*p)->next;
      }
  
!   if (had_locs && v->locs == 0)
!     {
!       n_useless_values++;
!       values_became_useless = 1;
!     }
    return 1;
  }
  
*************** discard_useless_values (x, info)
*** 2269,2275 ****
  {
    cselib_val *v = (cselib_val *)*x;
  
!   if (v->value == 0)
      {
        htab_clear_slot (hash_table, x);
        unchain_one_value (v);
--- 2251,2257 ----
  {
    cselib_val *v = (cselib_val *)*x;
  
!   if (v->locs == 0)
      {
        htab_clear_slot (hash_table, x);
        unchain_one_value (v);
*************** add_mem_for_addr (addr_elt, mem_elt, x)
*** 2627,2632 ****
--- 2609,2617 ----
    RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
    MEM_COPY_ATTRIBUTES (new, x);
  
+   if (mem_elt->locs == 0)
+     n_useless_values--;
+   
    mem_elt->locs = new_elt_loc_list (mem_elt->locs, new);
  }
  
*************** cselib_invalidate_regno (regno, mode)
*** 2877,2884 ****
  		  break;
  		}
  	    }
! 
! 	  check_value_useless (v);
  	}
      }
  }
--- 2862,2869 ----
  		  break;
  		}
  	    }
! 	  if (v->locs == 0)
! 	    n_useless_values++;
  	}
      }
  }
*************** cselib_invalidate_mem_1 (slot, info)
*** 2951,2956 ****
--- 2936,2942 ----
    cselib_val *v = (cselib_val *) *slot;
    rtx mem_rtx = (rtx) info;
    struct elt_loc_list **p = &v->locs;
+   int had_locs = v->locs != 0;
  
    while (*p)
      {
*************** cselib_invalidate_mem_1 (slot, info)
*** 2985,2992 ****
  
        unchain_one_elt_loc_list (p);
      }
  
-   check_value_useless (v);
    return 1;
  }
  
--- 2971,2980 ----
  
        unchain_one_elt_loc_list (p);
      }
+ 
+   if (had_locs && v->locs == 0)
+     n_useless_values++;
  
    return 1;
  }
  
*************** cselib_record_set (dest, src_elt, dest_a
*** 3045,3050 ****
--- 3033,3040 ----
    if (dreg >= 0)
      {
        REG_VALUES (dreg) = new_elt_list (REG_VALUES (dreg), src_elt);
+       if (src_elt->locs == 0)
+ 	n_useless_values--;
        src_elt->locs = new_elt_loc_list (src_elt->locs, dest);
      }
    else if (GET_CODE (dest) == MEM && dest_addr_elt != 0)


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