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]
Other format: [Raw text]

[patch] Fix bug in variable-tracking


Hello,

when compiling the attached testcase on x86-64 with "-g -O" the
location list is not produced correctly for variable "seq".
The problem is caused by the optimization for the location list length
(inside a basic block we avoid changing the current location of variable
if not necessary) and we did not compare whether the currect locations differ
while emitting notes for differences between end of one basic block and
beginning of another.
The attached patch is a fixed version of
http://gcc.gnu.org/ml/gcc-patches/2004-04/msg00272.html
which caused bootstrap hangup on ia64 and was reverted last week by me.

Bootstrapped/regtested ia64 and x86-64.
OK?

Josef

long volatile vol;
long
func1 (long a, long b, long c, long d, long e, long f, long g, int seq)
{
  vol = a + b + c + d + e + f + g;
  if (seq == 3)
    return vol;
  return 10 * func1 (g, f, e, d, c, b, a, seq + 1);
}

int
main ()
{
  vol = func1 (10, 20, 30, 40, 50, 60, 70, 0);
  return (int) vol;
}

2004-04-25  Josef Zlomek  <zlomekj@suse.cz>

	* var-tracking.c (compare_current_location): New.
	(variable_part_different_p): Compare current location of variable part
	when compare_current_location is true.
	(variable_tracking_main): Clear compare_current_location before
	finding locations, set it before emitting notes.

Index: var-tracking.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/var-tracking.c,v
retrieving revision 2.15
diff -c -p -c -3 -p -r2.15 var-tracking.c
*** var-tracking.c	22 Apr 2004 12:16:33 -0000	2.15
--- var-tracking.c	24 Apr 2004 07:06:02 -0000
*************** dataflow_set_union (dataflow_set *dst, d
*** 1234,1247 ****
  }
  
  /* Flag whether two dataflow sets being compared contain different data.  */
! static bool
! dataflow_set_different_value;
  
  static bool
  variable_part_different_p (variable_part *vp1, variable_part *vp2)
  {
    location_chain lc1, lc2;
  
    for (lc1 = vp1->loc_chain; lc1; lc1 = lc1->next)
      {
        for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
--- 1234,1258 ----
  }
  
  /* Flag whether two dataflow sets being compared contain different data.  */
! static bool dataflow_set_different_value;
! 
! /* True if current locations of variable parts should be compared.  */
! static bool compare_current_location;
  
  static bool
  variable_part_different_p (variable_part *vp1, variable_part *vp2)
  {
    location_chain lc1, lc2;
  
+   if (compare_current_location)
+     {
+       if (!((GET_CODE (vp1->cur_loc) == REG
+ 	     && GET_CODE (vp2->cur_loc) == REG
+ 	     && REGNO (vp1->cur_loc) == REGNO (vp2->cur_loc))
+ 	    || rtx_equal_p (vp1->cur_loc, vp2->cur_loc)))
+ 	return true;
+     }
+ 
    for (lc1 = vp1->loc_chain; lc1; lc1 = lc1->next)
      {
        for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
*************** variable_tracking_main (void)
*** 2744,2750 ****
--- 2755,2763 ----
  	}
      }
  
+   compare_current_location = false;
    vt_find_locations ();
+   compare_current_location = true;
    vt_emit_notes ();
  
    if (dump_file)


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