File nov189571-2.diff of Package gcc41

Also for nov #189571
for gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* var-tracking.c (enum micro_operation_type): Add MO_COPY.
	(var_debug_decl): New function.
	(var_reg_set): Follow debug decl link.  Add location even if
	reg is already known to hold some other variable.
	(var_mem_set): Follow debug decl link.
	(var_reg_delete_and_set, var_mem_delete_and_set): Follow debug
	decl link.  Delete other known locations of the variable part
	if requested.
	(var_reg_delete, var_mem_delete): Delete other known locations
	of the variable part if requested.
	(same_variable_part_p): New function.
	(add_stores): Select MO_COPY when appropriate.
	(vt_initialize): Handle it.
	(compute_bb_dataflow, emit_notes_in_bb): Likewise.  Delete
	known locations for MO_SET and MO_CLOBBER.
	(find_variable_location_part): New function.
	(set_variable_part, delete_variable_part): Use it.
	(clobber_variable_part): New function.
	* dwarf2out.c (dwarf2out_var_location): Do not follow debug
	decl link.

Index: gcc/var-tracking.c
===================================================================
*** gcc/var-tracking.c.orig	2008-06-12 13:25:26.000000000 +0200
--- gcc/var-tracking.c	2008-06-12 13:31:37.000000000 +0200
*************** enum micro_operation_type
*** 114,119 ****
--- 114,121 ----
    MO_USE_NO_VAR,/* Use location which is not associated with a variable
  		   or the variable is not trackable.  */
    MO_SET,	/* Set location.  */
+   MO_COPY,	/* Copy the same portion of a variable from one
+ 		   loation to another.  */
    MO_CLOBBER,	/* Clobber location.  */
    MO_CALL,	/* Call insn.  */
    MO_ADJUST	/* Adjust stack pointer.  */
*************** static void vars_clear (htab_t);
*** 298,310 ****
  static variable unshare_variable (dataflow_set *set, variable var);
  static int vars_copy_1 (void **, void *);
  static void vars_copy (htab_t, htab_t);
  static void var_reg_set (dataflow_set *, rtx);
! static void var_reg_delete_and_set (dataflow_set *, rtx);
! static void var_reg_delete (dataflow_set *, rtx);
  static void var_regno_delete (dataflow_set *, int);
  static void var_mem_set (dataflow_set *, rtx);
! static void var_mem_delete_and_set (dataflow_set *, rtx);
! static void var_mem_delete (dataflow_set *, rtx);
  
  static void dataflow_set_init (dataflow_set *, int);
  static void dataflow_set_clear (dataflow_set *);
--- 300,313 ----
  static variable unshare_variable (dataflow_set *set, variable var);
  static int vars_copy_1 (void **, void *);
  static void vars_copy (htab_t, htab_t);
+ static tree var_debug_decl (tree);
  static void var_reg_set (dataflow_set *, rtx);
! static void var_reg_delete_and_set (dataflow_set *, rtx, bool);
! static void var_reg_delete (dataflow_set *, rtx, bool);
  static void var_regno_delete (dataflow_set *, int);
  static void var_mem_set (dataflow_set *, rtx);
! static void var_mem_delete_and_set (dataflow_set *, rtx, bool);
! static void var_mem_delete (dataflow_set *, rtx, bool);
  
  static void dataflow_set_init (dataflow_set *, int);
  static void dataflow_set_clear (dataflow_set *);
*************** static void dataflow_set_destroy (datafl
*** 321,326 ****
--- 324,330 ----
  
  static bool contains_symbol_ref (rtx);
  static bool track_expr_p (tree);
+ static bool same_variable_part_p (rtx, tree, HOST_WIDE_INT);
  static int count_uses (rtx *, void *);
  static void count_uses_1 (rtx *, void *);
  static void count_stores (rtx, rtx, void *);
*************** static void dump_dataflow_sets (void);
*** 338,343 ****
--- 342,348 ----
  
  static void variable_was_changed (variable, htab_t);
  static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
+ static void clobber_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
  static void delete_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
  static int emit_note_insn_var_location (void **, void *);
  static void emit_notes_for_changes (rtx, enum emit_note_where);
*************** vars_copy (htab_t dst, htab_t src)
*** 801,806 ****
--- 806,824 ----
    htab_traverse (src, vars_copy_1, dst);
  }
  
+ /* Map a decl to its main debug decl.  */
+ 
+ static inline tree
+ var_debug_decl (tree decl)
+ {
+   if (decl && DECL_P (decl)
+       && DECL_DEBUG_EXPR_IS_FROM (decl) && DECL_DEBUG_EXPR (decl)
+       && DECL_P (DECL_DEBUG_EXPR (decl)))
+     decl = DECL_DEBUG_EXPR (decl);
+ 
+   return decl;
+ }
+ 
  /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  */
  
  static void
*************** var_reg_set (dataflow_set *set, rtx loc)
*** 808,830 ****
  {
    tree decl = REG_EXPR (loc);
    HOST_WIDE_INT offset = REG_OFFSET (loc);
  
!   if (set->regs[REGNO (loc)] == NULL)
      attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
    set_variable_part (set, loc, decl, offset);
  }
  
! /* Delete current content of register LOC in dataflow set SET
!    and set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  */
  
  static void
! var_reg_delete_and_set (dataflow_set *set, rtx loc)
  {
    tree decl = REG_EXPR (loc);
    HOST_WIDE_INT offset = REG_OFFSET (loc);
    attrs node, next;
    attrs *nextp;
  
    nextp = &set->regs[REGNO (loc)];
    for (node = *nextp; node; node = next)
      {
--- 826,860 ----
  {
    tree decl = REG_EXPR (loc);
    HOST_WIDE_INT offset = REG_OFFSET (loc);
+   attrs node;
+ 
+   decl = var_debug_decl (decl);
  
!   for (node = set->regs[REGNO (loc)]; node; node = node->next)
!     if (node->decl == decl && node->offset == offset)
!       break;
!   if (!node)
      attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
    set_variable_part (set, loc, decl, offset);
  }
  
! /* Delete current content of register LOC in dataflow set SET and set
!    the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  If
!    MODIFY is true, any other live copies of the same variable part are
!    also deleted from the dataflow set, otherwise the variable part is
!    assumed to be copied from another location holding the same
!    part.  */
  
  static void
! var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify)
  {
    tree decl = REG_EXPR (loc);
    HOST_WIDE_INT offset = REG_OFFSET (loc);
    attrs node, next;
    attrs *nextp;
  
+   decl = var_debug_decl (decl);
+ 
    nextp = &set->regs[REGNO (loc)];
    for (node = *nextp; node; node = next)
      {
*************** var_reg_delete_and_set (dataflow_set *se
*** 841,857 ****
  	  nextp = &node->next;
  	}
      }
    var_reg_set (set, loc);
  }
  
! /* Delete current content of register LOC in dataflow set SET.  */
  
  static void
! var_reg_delete (dataflow_set *set, rtx loc)
  {
    attrs *reg = &set->regs[REGNO (loc)];
    attrs node, next;
  
    for (node = *reg; node; node = next)
      {
        next = node->next;
--- 871,901 ----
  	  nextp = &node->next;
  	}
      }
+   if (modify)
+     clobber_variable_part (set, loc, decl, offset);
    var_reg_set (set, loc);
  }
  
! /* Delete current content of register LOC in dataflow set SET.  If
!    CLOBBER is true, also delete any other live copies of the same
!    variable part.  */
  
  static void
! var_reg_delete (dataflow_set *set, rtx loc, bool clobber)
  {
    attrs *reg = &set->regs[REGNO (loc)];
    attrs node, next;
  
+   if (clobber)
+     {
+       tree decl = REG_EXPR (loc);
+       HOST_WIDE_INT offset = REG_OFFSET (loc);
+ 
+       decl = var_debug_decl (decl);
+ 
+       clobber_variable_part (set, NULL, decl, offset);
+     }
+ 
    for (node = *reg; node; node = next)
      {
        next = node->next;
*************** var_mem_set (dataflow_set *set, rtx loc)
*** 888,915 ****
    tree decl = MEM_EXPR (loc);
    HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
  
    set_variable_part (set, loc, decl, offset);
  }
  
! /* Delete and set the location part of variable MEM_EXPR (LOC)
!    in dataflow set SET to LOC.
     Adjust the address first if it is stack pointer based.  */
  
  static void
! var_mem_delete_and_set (dataflow_set *set, rtx loc)
  {
    var_mem_set (set, loc);
  }
  
! /* Delete the location part LOC from dataflow set SET.
     Adjust the address first if it is stack pointer based.  */
  
  static void
! var_mem_delete (dataflow_set *set, rtx loc)
  {
    tree decl = MEM_EXPR (loc);
    HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
  
    delete_variable_part (set, loc, decl, offset);
  }
  
--- 932,975 ----
    tree decl = MEM_EXPR (loc);
    HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
  
+   decl = var_debug_decl (decl);
+ 
    set_variable_part (set, loc, decl, offset);
  }
  
! /* Delete and set the location part of variable MEM_EXPR (LOC) in
!    dataflow set SET to LOC.  If MODIFY is true, any other live copies
!    of the same variable part are also deleted from the dataflow set,
!    otherwise the variable part is assumed to be copied from another
!    location holding the same part.
     Adjust the address first if it is stack pointer based.  */
  
  static void
! var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify)
  {
+   tree decl = MEM_EXPR (loc);
+   HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
+ 
+   decl = var_debug_decl (decl);
+ 
+   if (modify)
+     clobber_variable_part (set, NULL, decl, offset);
    var_mem_set (set, loc);
  }
  
! /* Delete the location part LOC from dataflow set SET.  If CLOBBER is
!    true, also delete any other live copies of the same variable part.
     Adjust the address first if it is stack pointer based.  */
  
  static void
! var_mem_delete (dataflow_set *set, rtx loc, bool clobber)
  {
    tree decl = MEM_EXPR (loc);
    HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
  
+   decl = var_debug_decl (decl);
+   if (clobber)
+     clobber_variable_part (set, NULL, decl, offset);
    delete_variable_part (set, loc, decl, offset);
  }
  
*************** offset_valid_for_tracked_p (HOST_WIDE_IN
*** 1494,1499 ****
--- 1554,1594 ----
    return (-MAX_VAR_PARTS < offset) && (offset < MAX_VAR_PARTS);
  }
  
+ /* Determine whether a given LOC refers to the same variable part as
+    EXPR+OFFSET.  */
+ 
+ static bool
+ same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset)
+ {
+   tree expr2;
+   HOST_WIDE_INT offset2;
+ 
+   if (! DECL_P (expr))
+     return false;
+ 
+   if (REG_P (loc))
+     {
+       expr2 = REG_EXPR (loc);
+       offset2 = REG_OFFSET (loc);
+     }
+   else if (MEM_P (loc))
+     {
+       expr2 = MEM_EXPR (loc);
+       offset2 = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
+     }
+   else
+     return false;
+ 
+   if (! expr2 || ! DECL_P (expr2))
+     return false;
+ 
+   expr = var_debug_decl (expr);
+   expr2 = var_debug_decl (expr2);
+ 
+   return (expr == expr2 && offset == offset2);
+ }
+ 
+ 
  /* Count uses (register and memory references) LOC which will be tracked.
     INSN is instruction which the LOC is part of.  */
  
*************** add_stores (rtx loc, rtx expr, void *ins
*** 1591,1603 ****
        basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
        micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
  
!       if (GET_CODE (expr) != CLOBBER
! 	  && REG_EXPR (loc)
! 	  && track_expr_p (REG_EXPR (loc))
! 	  && offset_valid_for_tracked_p (REG_OFFSET (loc)))
! 	mo->type = MO_SET;
!       else
  	mo->type = MO_CLOBBER;
        mo->u.loc = loc;
        mo->insn = NEXT_INSN ((rtx) insn);
      }
--- 1686,1704 ----
        basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
        micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
  
!       if (GET_CODE (expr) == CLOBBER
! 	  || ! REG_EXPR (loc)
! 	  || ! track_expr_p (REG_EXPR (loc))
! 	  || ! offset_valid_for_tracked_p (REG_OFFSET (loc)))
  	mo->type = MO_CLOBBER;
+       else if (GET_CODE (expr) == SET
+ 	       && SET_DEST (expr) == loc
+ 	       && same_variable_part_p (SET_SRC (expr),
+ 					REG_EXPR (loc),
+ 					REG_OFFSET (loc)))
+ 	mo->type = MO_COPY;
+       else
+ 	mo->type = MO_SET;
        mo->u.loc = loc;
        mo->insn = NEXT_INSN ((rtx) insn);
      }
*************** add_stores (rtx loc, rtx expr, void *ins
*** 1609,1615 ****
        basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
        micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
  
!       mo->type = GET_CODE (expr) == CLOBBER ? MO_CLOBBER : MO_SET;
        mo->u.loc = loc;
        mo->insn = NEXT_INSN ((rtx) insn);
      }
--- 1710,1726 ----
        basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
        micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
  
!       if (GET_CODE (expr) == CLOBBER)
! 	mo->type = MO_CLOBBER;
!       else if (GET_CODE (expr) == SET
! 	       && SET_DEST (expr) == loc
! 	       && same_variable_part_p (SET_SRC (expr),
! 					MEM_EXPR (loc),
! 					MEM_OFFSET (loc)
! 					? INTVAL (MEM_OFFSET (loc)) : 0))
! 	mo->type = MO_COPY;
!       else
! 	mo->type = MO_SET;
        mo->u.loc = loc;
        mo->insn = NEXT_INSN ((rtx) insn);
      }
*************** compute_bb_dataflow (basic_block bb)
*** 1657,1677 ****
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (REG_P (loc))
! 		var_reg_delete_and_set (out, loc);
  	      else if (MEM_P (loc))
! 		var_mem_delete_and_set (out, loc);
  	    }
  	    break;
  
  	  case MO_USE_NO_VAR:
  	  case MO_CLOBBER:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (REG_P (loc))
! 		var_reg_delete (out, loc);
  	      else if (MEM_P (loc))
! 		var_mem_delete (out, loc);
  	    }
  	    break;
  
--- 1768,1809 ----
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (REG_P (loc))
! 		var_reg_delete_and_set (out, loc, true);
  	      else if (MEM_P (loc))
! 		var_mem_delete_and_set (out, loc, true);
! 	    }
! 	    break;
! 
! 	  case MO_COPY:
! 	    {
! 	      rtx loc = VTI (bb)->mos[i].u.loc;
! 
! 	      if (REG_P (loc))
! 		var_reg_delete_and_set (out, loc, false);
! 	      else if (MEM_P (loc))
! 		var_mem_delete_and_set (out, loc, false);
  	    }
  	    break;
  
  	  case MO_USE_NO_VAR:
+ 	    {
+ 	      rtx loc = VTI (bb)->mos[i].u.loc;
+ 
+ 	      if (REG_P (loc))
+ 		var_reg_delete (out, loc, false);
+ 	      else if (MEM_P (loc))
+ 		var_mem_delete (out, loc, false);
+ 	    }
+ 	    break;
+ 
  	  case MO_CLOBBER:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (REG_P (loc))
! 		var_reg_delete (out, loc, true);
  	      else if (MEM_P (loc))
! 		var_mem_delete (out, loc, true);
  	    }
  	    break;
  
*************** variable_was_changed (variable var, htab
*** 1929,1934 ****
--- 2061,2099 ----
      }
  }
  
+ /* Look for the index in VAR->var_part corresponding to OFFSET.
+    Return -1 if not found.  If INSERTION_POINT is non-NULL, the
+    referenced int will be set to the index that the part has or should
+    have, if it should be inserted.  */
+ 
+ static inline int
+ find_variable_location_part (variable var, HOST_WIDE_INT offset,
+ 			     int *insertion_point)
+ {
+   int pos, low, high;
+ 
+   /* Find the location part.  */
+   low = 0;
+   high = var->n_var_parts;
+   while (low != high)
+     {
+       pos = (low + high) / 2;
+       if (var->var_part[pos].offset < offset)
+ 	low = pos + 1;
+       else
+ 	high = pos;
+     }
+   pos = low;
+ 
+   if (insertion_point)
+     *insertion_point = pos;
+ 
+   if (pos < var->n_var_parts && var->var_part[pos].offset == offset)
+     return pos;
+ 
+   return -1;
+ }
+ 
  /* Set the part of variable's location in the dataflow set SET.  The variable
     part is specified by variable's declaration DECL and offset OFFSET and the
     part's location by LOC.  */
*************** variable_was_changed (variable var, htab
*** 1936,1942 ****
  static void
  set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset)
  {
!   int pos, low, high;
    location_chain node, next;
    location_chain *nextp;
    variable var;
--- 2101,2107 ----
  static void
  set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset)
  {
!   int pos;
    location_chain node, next;
    location_chain *nextp;
    variable var;
*************** set_variable_part (dataflow_set *set, rt
*** 1959,1980 ****
      }
    else
      {
        var = (variable) *slot;
  
!       /* Find the location part.  */
!       low = 0;
!       high = var->n_var_parts;
!       while (low != high)
! 	{
! 	  pos = (low + high) / 2;
! 	  if (var->var_part[pos].offset < offset)
! 	    low = pos + 1;
! 	  else
! 	    high = pos;
! 	}
!       pos = low;
  
!       if (pos < var->n_var_parts && var->var_part[pos].offset == offset)
  	{
  	  node = var->var_part[pos].loc_chain;
  
--- 2124,2136 ----
      }
    else
      {
+       int inspos = 0;
+ 
        var = (variable) *slot;
  
!       pos = find_variable_location_part (var, offset, &inspos);
  
!       if (pos >= 0)
  	{
  	  node = var->var_part[pos].loc_chain;
  
*************** set_variable_part (dataflow_set *set, rt
*** 2006,2015 ****
  	     thus there are at most MAX_VAR_PARTS different offsets.  */
  	  gcc_assert (var->n_var_parts < MAX_VAR_PARTS);
  
! 	  /* We have to move the elements of array starting at index low to the
! 	     next position.  */
! 	  for (high = var->n_var_parts; high > low; high--)
! 	    var->var_part[high] = var->var_part[high - 1];
  
  	  var->n_var_parts++;
  	  var->var_part[pos].offset = offset;
--- 2162,2171 ----
  	     thus there are at most MAX_VAR_PARTS different offsets.  */
  	  gcc_assert (var->n_var_parts < MAX_VAR_PARTS);
  
! 	  /* We have to move the elements of array starting at index
! 	     inspos to the next position.  */
! 	  for (pos = var->n_var_parts; pos > inspos; pos--)
! 	    var->var_part[pos] = var->var_part[pos - 1];
  
  	  var->n_var_parts++;
  	  var->var_part[pos].offset = offset;
*************** set_variable_part (dataflow_set *set, rt
*** 2049,2054 ****
--- 2205,2247 ----
      }
  }
  
+ /* Remove all recorded register locations for the given variable part
+    from dataflow set SET, except for those that are identical to loc.
+    The variable part is specified by variable's declaration DECL and
+    offset OFFSET.  */
+ 
+ static void
+ clobber_variable_part (dataflow_set *set, rtx loc, tree decl,
+ 		      HOST_WIDE_INT offset)
+ {
+   void **slot;
+ 
+   if (! decl || ! DECL_P (decl))
+     return;
+ 
+   slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
+ 				   NO_INSERT);
+   if (slot)
+     {
+       variable var = (variable) *slot;
+       int pos = find_variable_location_part (var, offset, NULL);
+ 
+       if (pos >= 0)
+ 	{
+ 	  location_chain node, next;
+ 
+ 	  /* Remove the register locations from the dataflow set.  */
+ 	  next = var->var_part[pos].loc_chain;
+ 	  for (node = next; node; node = next)
+ 	    {
+ 	      next = node->next;
+ 	      if (REG_P (node->loc) && node->loc != loc)
+ 		var_reg_delete (set, node->loc, false);
+ 	    }
+ 	}
+     }
+ }
+ 
  /* Delete the part of variable's location from dataflow set SET.  The variable
     part is specified by variable's declaration DECL and offset OFFSET and the
     part's location by LOC.  */
*************** static void
*** 2057,2063 ****
  delete_variable_part (dataflow_set *set, rtx loc, tree decl,
  		      HOST_WIDE_INT offset)
  {
-   int pos, low, high;
    void **slot;
      
    slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
--- 2250,2255 ----
*************** delete_variable_part (dataflow_set *set,
*** 2065,2085 ****
    if (slot)
      {
        variable var = (variable) *slot;
  
!       /* Find the location part.  */
!       low = 0;
!       high = var->n_var_parts;
!       while (low != high)
! 	{
! 	  pos = (low + high) / 2;
! 	  if (var->var_part[pos].offset < offset)
! 	    low = pos + 1;
! 	  else
! 	    high = pos;
! 	}
!       pos = low;
! 
!       if (pos < var->n_var_parts && var->var_part[pos].offset == offset)
  	{
  	  location_chain node, next;
  	  location_chain *nextp;
--- 2257,2265 ----
    if (slot)
      {
        variable var = (variable) *slot;
+       int pos = find_variable_location_part (var, offset, NULL);
  
!       if (pos >= 0)
  	{
  	  location_chain node, next;
  	  location_chain *nextp;
*************** delete_variable_part (dataflow_set *set,
*** 2145,2151 ****
  		}
  	    }
  	  if (changed)
! 	      variable_was_changed (var, set->vars);
  	}
      }
  }
--- 2325,2331 ----
  		}
  	    }
  	  if (changed)
! 	    variable_was_changed (var, set->vars);
  	}
      }
  }
*************** emit_notes_in_bb (basic_block bb)
*** 2436,2463 ****
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (REG_P (loc))
! 		var_reg_delete_and_set (&set, loc);
  	      else
! 		var_mem_delete_and_set (&set, loc);
  
  	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
  	    }
  	    break;
  
  	  case MO_USE_NO_VAR:
- 	  case MO_CLOBBER:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (REG_P (loc))
! 		var_reg_delete (&set, loc);
  	      else
! 		var_mem_delete (&set, loc);
  
! 	      if (VTI (bb)->mos[i].type == MO_USE_NO_VAR)
! 		emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
  	      else
! 		emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
  	    }
  	    break;
  
--- 2616,2665 ----
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (REG_P (loc))
! 		var_reg_delete_and_set (&set, loc, true);
  	      else
! 		var_mem_delete_and_set (&set, loc, true);
! 
! 	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
! 	    }
! 	    break;
! 
! 	  case MO_COPY:
! 	    {
! 	      rtx loc = VTI (bb)->mos[i].u.loc;
! 
! 	      if (REG_P (loc))
! 		var_reg_delete_and_set (&set, loc, false);
! 	      else
! 		var_mem_delete_and_set (&set, loc, false);
  
  	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
  	    }
  	    break;
  
  	  case MO_USE_NO_VAR:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (REG_P (loc))
! 		var_reg_delete (&set, loc, false);
  	      else
! 		var_mem_delete (&set, loc, false);
! 
! 	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
! 	    }
! 	    break;
  
! 	  case MO_CLOBBER:
! 	    {
! 	      rtx loc = VTI (bb)->mos[i].u.loc;
! 
! 	      if (REG_P (loc))
! 		var_reg_delete (&set, loc, true);
  	      else
! 		var_mem_delete (&set, loc, true);
! 
! 	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
  	    }
  	    break;
  
*************** vt_initialize (void)
*** 2682,2688 ****
  		{
  		  while (n1 < n2 && VTI (bb)->mos[n1].type == MO_CLOBBER)
  		    n1++;
! 		  while (n1 < n2 && VTI (bb)->mos[n2].type == MO_SET)
  		    n2--;
  		  if (n1 < n2)
  		    {
--- 2884,2891 ----
  		{
  		  while (n1 < n2 && VTI (bb)->mos[n1].type == MO_CLOBBER)
  		    n1++;
! 		  while (n1 < n2 && (VTI (bb)->mos[n2].type == MO_SET
! 				     || VTI (bb)->mos[n2].type == MO_COPY))
  		    n2--;
  		  if (n1 < n2)
  		    {
Index: gcc/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c.orig	2007-11-27 16:21:38.000000000 +0100
--- gcc/dwarf2out.c	2008-06-12 13:25:31.000000000 +0200
*************** dwarf2out_var_location (rtx loc_note)
*** 13593,13601 ****
    last_insn = loc_note;
    last_label = newloc->label;
    decl = NOTE_VAR_LOCATION_DECL (loc_note);
-   if (DECL_DEBUG_EXPR_IS_FROM (decl) && DECL_DEBUG_EXPR (decl) 
-       && DECL_P (DECL_DEBUG_EXPR (decl)))
-     decl = DECL_DEBUG_EXPR (decl); 
    add_var_loc_to_decl (decl, newloc);
  }
  
--- 13593,13598 ----
openSUSE Build Service is sponsored by