re PR debug/21946 (Invalid DWARF2 debug info emitted)
PR debug/21946 * dwarf2out.c (add_loc_descr_op_piece): New function. (multiple_reg_loc_descriptor, concat_loc_descriptor, loc_descriptor): Use it. * var-tracking.c: Include regs.h and expr.h. (emit_note_insn_var_location): Skip over pieces where offset is smaller than previous offset plus previous piece mode size. Optimize adjacent hard registers or memory locations. * Makefile.in (var-tracking.o): Depend on $(REGS_H) and $(EXPR_H). From-SVN: r100706
This commit is contained in:
parent
2214de3042
commit
c938250d71
@ -1,3 +1,15 @@
|
||||
2005-06-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR debug/21946
|
||||
* dwarf2out.c (add_loc_descr_op_piece): New function.
|
||||
(multiple_reg_loc_descriptor, concat_loc_descriptor,
|
||||
loc_descriptor): Use it.
|
||||
* var-tracking.c: Include regs.h and expr.h.
|
||||
(emit_note_insn_var_location): Skip over pieces where offset
|
||||
is smaller than previous offset plus previous piece mode size.
|
||||
Optimize adjacent hard registers or memory locations.
|
||||
* Makefile.in (var-tracking.o): Depend on $(REGS_H) and $(EXPR_H).
|
||||
|
||||
2005-06-07 Richard Guenther <rguenth@gcc.gnu.org>
|
||||
|
||||
* c-typeck.c (c_finish_if_stmt): Use void_type_node as type
|
||||
|
@ -2136,7 +2136,8 @@ df.o : df.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
$(BASIC_BLOCK_H) $(DF_H) bitmap.h sbitmap.h $(TM_P_H)
|
||||
var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h $(FLAGS_H) \
|
||||
$(BASIC_BLOCK_H) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H)
|
||||
$(BASIC_BLOCK_H) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \
|
||||
$(REGS_H) $(EXPR_H)
|
||||
conflict.o : conflict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(OBSTACK_H) \
|
||||
$(HASHTAB_H) $(RTL_H) hard-reg-set.h $(BASIC_BLOCK_H)
|
||||
profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
|
@ -2659,6 +2659,7 @@ static const char *dwarf_stack_op_name (unsigned);
|
||||
static dw_loc_descr_ref new_loc_descr (enum dwarf_location_atom,
|
||||
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT);
|
||||
static void add_loc_descr (dw_loc_descr_ref *, dw_loc_descr_ref);
|
||||
static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
|
||||
static unsigned long size_of_loc_descr (dw_loc_descr_ref);
|
||||
static unsigned long size_of_locs (dw_loc_descr_ref);
|
||||
static void output_loc_operands (dw_loc_descr_ref);
|
||||
@ -3011,6 +3012,27 @@ add_loc_descr (dw_loc_descr_ref *list_head, dw_loc_descr_ref descr)
|
||||
*d = descr;
|
||||
}
|
||||
|
||||
|
||||
/* Optionally add a DW_OP_piece term to a location description expression.
|
||||
DW_OP_piece is only added if the location description expression already
|
||||
doesn't end with DW_OP_piece. */
|
||||
|
||||
static void
|
||||
add_loc_descr_op_piece (dw_loc_descr_ref *list_head, int size)
|
||||
{
|
||||
dw_loc_descr_ref loc;
|
||||
|
||||
if (*list_head != NULL)
|
||||
{
|
||||
/* Find the end of the chain. */
|
||||
for (loc = *list_head; loc->dw_loc_next != NULL; loc = loc->dw_loc_next)
|
||||
;
|
||||
|
||||
if (loc->dw_loc_opc != DW_OP_piece)
|
||||
loc->dw_loc_next = new_loc_descr (DW_OP_piece, size, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the size of a location descriptor. */
|
||||
|
||||
static unsigned long
|
||||
@ -8467,7 +8489,7 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs)
|
||||
|
||||
t = one_reg_loc_descriptor (reg);
|
||||
add_loc_descr (&loc_result, t);
|
||||
add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
|
||||
add_loc_descr_op_piece (&loc_result, size);
|
||||
++reg;
|
||||
}
|
||||
return loc_result;
|
||||
@ -8487,7 +8509,7 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs)
|
||||
t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)));
|
||||
add_loc_descr (&loc_result, t);
|
||||
size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
|
||||
add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
|
||||
add_loc_descr_op_piece (&loc_result, size);
|
||||
}
|
||||
return loc_result;
|
||||
}
|
||||
@ -8790,14 +8812,10 @@ concat_loc_descriptor (rtx x0, rtx x1)
|
||||
return 0;
|
||||
|
||||
cc_loc_result = x0_ref;
|
||||
add_loc_descr (&cc_loc_result,
|
||||
new_loc_descr (DW_OP_piece,
|
||||
GET_MODE_SIZE (GET_MODE (x0)), 0));
|
||||
add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x0)));
|
||||
|
||||
add_loc_descr (&cc_loc_result, x1_ref);
|
||||
add_loc_descr (&cc_loc_result,
|
||||
new_loc_descr (DW_OP_piece,
|
||||
GET_MODE_SIZE (GET_MODE (x1)), 0));
|
||||
add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x1)));
|
||||
|
||||
return cc_loc_result;
|
||||
}
|
||||
@ -8862,8 +8880,7 @@ loc_descriptor (rtx rtl, bool can_use_fbreg)
|
||||
loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0),
|
||||
can_use_fbreg);
|
||||
mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
|
||||
add_loc_descr (&loc_result,
|
||||
new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0));
|
||||
add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
|
||||
for (i = 1; i < num_elem; i++)
|
||||
{
|
||||
dw_loc_descr_ref temp;
|
||||
@ -8872,9 +8889,7 @@ loc_descriptor (rtx rtl, bool can_use_fbreg)
|
||||
can_use_fbreg);
|
||||
add_loc_descr (&loc_result, temp);
|
||||
mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
|
||||
add_loc_descr (&loc_result,
|
||||
new_loc_descr (DW_OP_piece,
|
||||
GET_MODE_SIZE (mode), 0));
|
||||
add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -102,6 +102,8 @@
|
||||
#include "alloc-pool.h"
|
||||
#include "fibheap.h"
|
||||
#include "hashtab.h"
|
||||
#include "regs.h"
|
||||
#include "expr.h"
|
||||
|
||||
/* Type of micro operation. */
|
||||
enum micro_operation_type
|
||||
@ -2167,25 +2169,101 @@ emit_note_insn_var_location (void **varp, void *data)
|
||||
rtx insn = ((emit_note_data *)data)->insn;
|
||||
enum emit_note_where where = ((emit_note_data *)data)->where;
|
||||
rtx note;
|
||||
int i;
|
||||
int i, j, n_var_parts;
|
||||
bool complete;
|
||||
HOST_WIDE_INT last_limit;
|
||||
tree type_size_unit;
|
||||
HOST_WIDE_INT offsets[MAX_VAR_PARTS];
|
||||
rtx loc[MAX_VAR_PARTS];
|
||||
|
||||
gcc_assert (var->decl);
|
||||
|
||||
complete = true;
|
||||
last_limit = 0;
|
||||
n_var_parts = 0;
|
||||
for (i = 0; i < var->n_var_parts; i++)
|
||||
{
|
||||
enum machine_mode mode, wider_mode;
|
||||
|
||||
if (last_limit < var->var_part[i].offset)
|
||||
{
|
||||
complete = false;
|
||||
break;
|
||||
}
|
||||
last_limit
|
||||
= (var->var_part[i].offset
|
||||
+ GET_MODE_SIZE (GET_MODE (var->var_part[i].loc_chain->loc)));
|
||||
else if (last_limit > var->var_part[i].offset)
|
||||
continue;
|
||||
offsets[n_var_parts] = var->var_part[i].offset;
|
||||
loc[n_var_parts] = var->var_part[i].loc_chain->loc;
|
||||
mode = GET_MODE (loc[n_var_parts]);
|
||||
last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
|
||||
|
||||
/* Attempt to merge adjacent registers or memory. */
|
||||
wider_mode = GET_MODE_WIDER_MODE (mode);
|
||||
for (j = i + 1; j < var->n_var_parts; j++)
|
||||
if (last_limit <= var->var_part[j].offset)
|
||||
break;
|
||||
if (j < var->n_var_parts
|
||||
&& wider_mode != VOIDmode
|
||||
&& GET_CODE (loc[n_var_parts])
|
||||
== GET_CODE (var->var_part[j].loc_chain->loc)
|
||||
&& mode == GET_MODE (var->var_part[j].loc_chain->loc)
|
||||
&& last_limit == var->var_part[j].offset)
|
||||
{
|
||||
rtx new_loc = NULL;
|
||||
rtx loc2 = var->var_part[j].loc_chain->loc;
|
||||
|
||||
if (REG_P (loc[n_var_parts])
|
||||
&& hard_regno_nregs[REGNO (loc[n_var_parts])][mode] * 2
|
||||
== hard_regno_nregs[REGNO (loc[n_var_parts])][wider_mode]
|
||||
&& REGNO (loc[n_var_parts])
|
||||
+ hard_regno_nregs[REGNO (loc[n_var_parts])][mode]
|
||||
== REGNO (loc2))
|
||||
{
|
||||
if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
|
||||
new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
|
||||
mode, 0);
|
||||
else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
|
||||
new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
|
||||
if (new_loc)
|
||||
{
|
||||
if (!REG_P (new_loc)
|
||||
|| REGNO (new_loc) != REGNO (loc[n_var_parts]))
|
||||
new_loc = NULL;
|
||||
else
|
||||
REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
|
||||
}
|
||||
}
|
||||
else if (MEM_P (loc[n_var_parts])
|
||||
&& GET_CODE (XEXP (loc2, 0)) == PLUS
|
||||
&& GET_CODE (XEXP (XEXP (loc2, 0), 0)) == REG
|
||||
&& GET_CODE (XEXP (XEXP (loc2, 0), 1)) == CONST_INT)
|
||||
{
|
||||
if ((GET_CODE (XEXP (loc[n_var_parts], 0)) == REG
|
||||
&& rtx_equal_p (XEXP (loc[n_var_parts], 0),
|
||||
XEXP (XEXP (loc2, 0), 0))
|
||||
&& INTVAL (XEXP (XEXP (loc2, 0), 1))
|
||||
== GET_MODE_SIZE (mode))
|
||||
|| (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
|
||||
&& GET_CODE (XEXP (XEXP (loc[n_var_parts], 0), 1))
|
||||
== CONST_INT
|
||||
&& rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
|
||||
XEXP (XEXP (loc2, 0), 0))
|
||||
&& INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
|
||||
+ GET_MODE_SIZE (mode)
|
||||
== INTVAL (XEXP (XEXP (loc2, 0), 1))))
|
||||
new_loc = adjust_address_nv (loc[n_var_parts],
|
||||
wider_mode, 0);
|
||||
}
|
||||
|
||||
if (new_loc)
|
||||
{
|
||||
loc[n_var_parts] = new_loc;
|
||||
mode = wider_mode;
|
||||
last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
++n_var_parts;
|
||||
}
|
||||
type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (var->decl));
|
||||
if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
|
||||
@ -2201,26 +2279,24 @@ emit_note_insn_var_location (void **varp, void *data)
|
||||
NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
|
||||
NULL_RTX);
|
||||
}
|
||||
else if (var->n_var_parts == 1)
|
||||
else if (n_var_parts == 1)
|
||||
{
|
||||
rtx expr_list
|
||||
= gen_rtx_EXPR_LIST (VOIDmode,
|
||||
var->var_part[0].loc_chain->loc,
|
||||
GEN_INT (var->var_part[0].offset));
|
||||
= gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
|
||||
|
||||
NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
|
||||
expr_list);
|
||||
}
|
||||
else if (var->n_var_parts)
|
||||
else if (n_var_parts)
|
||||
{
|
||||
rtx argp[MAX_VAR_PARTS];
|
||||
rtx parallel;
|
||||
|
||||
for (i = 0; i < var->n_var_parts; i++)
|
||||
argp[i] = gen_rtx_EXPR_LIST (VOIDmode, var->var_part[i].loc_chain->loc,
|
||||
GEN_INT (var->var_part[i].offset));
|
||||
for (i = 0; i < n_var_parts; i++)
|
||||
loc[i]
|
||||
= gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
|
||||
|
||||
parallel = gen_rtx_PARALLEL (VOIDmode,
|
||||
gen_rtvec_v (var->n_var_parts, argp));
|
||||
gen_rtvec_v (n_var_parts, loc));
|
||||
NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
|
||||
parallel);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user