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 ----