dwarf2out.c (mem_loc_descriptor): Use DW_OP_deref_size if MEM's mode size isn't DWARF2_ADDR_SIZE.
* dwarf2out.c (mem_loc_descriptor) <case MEM>: Use DW_OP_deref_size if MEM's mode size isn't DWARF2_ADDR_SIZE. (mem_loc_descriptor) <do_scompare>: Allow also VOIDmode arguments. Optimize eq/ne comparisons when both arguments are known to be zero-extended. (mem_loc_descriptor) <do_ucompare>: Allow also VOIDmode arguments. Don't mask operands unnecessarily if they are known to be already zero-extended. From-SVN: r156692
This commit is contained in:
parent
19030d779a
commit
d2d36740c2
@ -1,3 +1,14 @@
|
||||
2010-02-11 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* dwarf2out.c (mem_loc_descriptor) <case MEM>: Use DW_OP_deref_size
|
||||
if MEM's mode size isn't DWARF2_ADDR_SIZE.
|
||||
(mem_loc_descriptor) <do_scompare>: Allow also VOIDmode arguments.
|
||||
Optimize eq/ne comparisons when both arguments are known to be
|
||||
zero-extended.
|
||||
(mem_loc_descriptor) <do_ucompare>: Allow also VOIDmode arguments.
|
||||
Don't mask operands unnecessarily if they are known to be already
|
||||
zero-extended.
|
||||
|
||||
2010-02-10 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
* ira-conflicts.c (add_insn_allocno_copies): Use find_reg_note
|
||||
|
194
gcc/dwarf2out.c
194
gcc/dwarf2out.c
@ -12990,7 +12990,19 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
|
||||
if (mem_loc_result == NULL)
|
||||
mem_loc_result = tls_mem_loc_descriptor (rtl);
|
||||
if (mem_loc_result != 0)
|
||||
add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
|
||||
{
|
||||
if (GET_MODE_SIZE (GET_MODE (rtl)) > DWARF2_ADDR_SIZE)
|
||||
{
|
||||
expansion_failed (NULL_TREE, rtl, "DWARF address size mismatch");
|
||||
return 0;
|
||||
}
|
||||
else if (GET_MODE_SIZE (GET_MODE (rtl)) == DWARF2_ADDR_SIZE)
|
||||
add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
|
||||
else
|
||||
add_loc_descr (&mem_loc_result,
|
||||
new_loc_descr (DW_OP_deref_size,
|
||||
GET_MODE_SIZE (GET_MODE (rtl)), 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx new_rtl = avoid_constant_pool_reference (rtl);
|
||||
@ -13219,32 +13231,72 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
|
||||
goto do_scompare;
|
||||
|
||||
do_scompare:
|
||||
if (GET_MODE_CLASS (GET_MODE (XEXP (rtl, 0))) != MODE_INT
|
||||
|| GET_MODE_SIZE (GET_MODE (XEXP (rtl, 0))) > DWARF2_ADDR_SIZE
|
||||
|| GET_MODE (XEXP (rtl, 0)) != GET_MODE (XEXP (rtl, 1)))
|
||||
if (GET_MODE_SIZE (GET_MODE (XEXP (rtl, 0))) > DWARF2_ADDR_SIZE
|
||||
|| GET_MODE_SIZE (GET_MODE (XEXP (rtl, 1))) > DWARF2_ADDR_SIZE)
|
||||
break;
|
||||
|
||||
op0 = mem_loc_descriptor (XEXP (rtl, 0), mode,
|
||||
VAR_INIT_STATUS_INITIALIZED);
|
||||
op1 = mem_loc_descriptor (XEXP (rtl, 1), mode,
|
||||
VAR_INIT_STATUS_INITIALIZED);
|
||||
|
||||
if (op0 == 0 || op1 == 0)
|
||||
break;
|
||||
|
||||
if (GET_MODE_SIZE (GET_MODE (XEXP (rtl, 0))) < DWARF2_ADDR_SIZE)
|
||||
else
|
||||
{
|
||||
int shift = DWARF2_ADDR_SIZE
|
||||
- GET_MODE_SIZE (GET_MODE (XEXP (rtl, 0)));
|
||||
shift *= BITS_PER_UNIT;
|
||||
add_loc_descr (&op0, int_loc_descriptor (shift));
|
||||
add_loc_descr (&op0, new_loc_descr (DW_OP_shl, 0, 0));
|
||||
if (CONST_INT_P (XEXP (rtl, 1)))
|
||||
op1 = int_loc_descriptor (INTVAL (XEXP (rtl, 1)) << shift);
|
||||
else
|
||||
enum machine_mode op_mode = GET_MODE (XEXP (rtl, 0));
|
||||
|
||||
if (op_mode == VOIDmode)
|
||||
op_mode = GET_MODE (XEXP (rtl, 1));
|
||||
if (op_mode != VOIDmode && GET_MODE_CLASS (op_mode) != MODE_INT)
|
||||
break;
|
||||
|
||||
op0 = mem_loc_descriptor (XEXP (rtl, 0), mode,
|
||||
VAR_INIT_STATUS_INITIALIZED);
|
||||
op1 = mem_loc_descriptor (XEXP (rtl, 1), mode,
|
||||
VAR_INIT_STATUS_INITIALIZED);
|
||||
|
||||
if (op0 == 0 || op1 == 0)
|
||||
break;
|
||||
|
||||
if (op_mode != VOIDmode
|
||||
&& GET_MODE_SIZE (op_mode) < DWARF2_ADDR_SIZE)
|
||||
{
|
||||
add_loc_descr (&op1, int_loc_descriptor (shift));
|
||||
add_loc_descr (&op1, new_loc_descr (DW_OP_shl, 0, 0));
|
||||
int shift = DWARF2_ADDR_SIZE - GET_MODE_SIZE (op_mode);
|
||||
shift *= BITS_PER_UNIT;
|
||||
/* For eq/ne, if the operands are known to be zero-extended,
|
||||
there is no need to do the fancy shifting up. */
|
||||
if (op == DW_OP_eq || op == DW_OP_ne)
|
||||
{
|
||||
dw_loc_descr_ref last0, last1;
|
||||
for (last0 = op0;
|
||||
last0->dw_loc_next != NULL;
|
||||
last0 = last0->dw_loc_next)
|
||||
;
|
||||
for (last1 = op1;
|
||||
last1->dw_loc_next != NULL;
|
||||
last1 = last1->dw_loc_next)
|
||||
;
|
||||
/* deref_size zero extends, and for constants we can check
|
||||
whether they are zero extended or not. */
|
||||
if (((last0->dw_loc_opc == DW_OP_deref_size
|
||||
&& last0->dw_loc_oprnd1.v.val_int
|
||||
<= GET_MODE_SIZE (op_mode))
|
||||
|| (CONST_INT_P (XEXP (rtl, 0))
|
||||
&& (unsigned HOST_WIDE_INT) INTVAL (XEXP (rtl, 0))
|
||||
== (INTVAL (XEXP (rtl, 0))
|
||||
& GET_MODE_MASK (op_mode))))
|
||||
&& ((last1->dw_loc_opc == DW_OP_deref_size
|
||||
&& last1->dw_loc_oprnd1.v.val_int
|
||||
<= GET_MODE_SIZE (op_mode))
|
||||
|| (CONST_INT_P (XEXP (rtl, 1))
|
||||
&& (unsigned HOST_WIDE_INT)
|
||||
INTVAL (XEXP (rtl, 1))
|
||||
== (INTVAL (XEXP (rtl, 1))
|
||||
& GET_MODE_MASK (op_mode)))))
|
||||
goto do_compare;
|
||||
}
|
||||
add_loc_descr (&op0, int_loc_descriptor (shift));
|
||||
add_loc_descr (&op0, new_loc_descr (DW_OP_shl, 0, 0));
|
||||
if (CONST_INT_P (XEXP (rtl, 1)))
|
||||
op1 = int_loc_descriptor (INTVAL (XEXP (rtl, 1)) << shift);
|
||||
else
|
||||
{
|
||||
add_loc_descr (&op1, int_loc_descriptor (shift));
|
||||
add_loc_descr (&op1, new_loc_descr (DW_OP_shl, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13277,42 +13329,72 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
|
||||
goto do_ucompare;
|
||||
|
||||
do_ucompare:
|
||||
if (GET_MODE_CLASS (GET_MODE (XEXP (rtl, 0))) != MODE_INT
|
||||
|| GET_MODE_SIZE (GET_MODE (XEXP (rtl, 0))) > DWARF2_ADDR_SIZE
|
||||
|| GET_MODE (XEXP (rtl, 0)) != GET_MODE (XEXP (rtl, 1)))
|
||||
if (GET_MODE_SIZE (GET_MODE (XEXP (rtl, 0))) > DWARF2_ADDR_SIZE
|
||||
|| GET_MODE_SIZE (GET_MODE (XEXP (rtl, 1))) > DWARF2_ADDR_SIZE)
|
||||
break;
|
||||
|
||||
op0 = mem_loc_descriptor (XEXP (rtl, 0), mode,
|
||||
VAR_INIT_STATUS_INITIALIZED);
|
||||
op1 = mem_loc_descriptor (XEXP (rtl, 1), mode,
|
||||
VAR_INIT_STATUS_INITIALIZED);
|
||||
|
||||
if (op0 == 0 || op1 == 0)
|
||||
break;
|
||||
|
||||
if (GET_MODE_SIZE (GET_MODE (XEXP (rtl, 0))) < DWARF2_ADDR_SIZE)
|
||||
{
|
||||
HOST_WIDE_INT mask = GET_MODE_MASK (GET_MODE (XEXP (rtl, 0)));
|
||||
add_loc_descr (&op0, int_loc_descriptor (mask));
|
||||
add_loc_descr (&op0, new_loc_descr (DW_OP_and, 0, 0));
|
||||
if (CONST_INT_P (XEXP (rtl, 1)))
|
||||
op1 = int_loc_descriptor (INTVAL (XEXP (rtl, 1)) & mask);
|
||||
else
|
||||
{
|
||||
add_loc_descr (&op1, int_loc_descriptor (mask));
|
||||
add_loc_descr (&op1, new_loc_descr (DW_OP_and, 0, 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HOST_WIDE_INT bias = 1;
|
||||
bias <<= (DWARF2_ADDR_SIZE * BITS_PER_UNIT - 1);
|
||||
add_loc_descr (&op0, new_loc_descr (DW_OP_plus_uconst, bias, 0));
|
||||
if (CONST_INT_P (XEXP (rtl, 1)))
|
||||
op1 = int_loc_descriptor ((unsigned HOST_WIDE_INT) bias
|
||||
+ INTVAL (XEXP (rtl, 1)));
|
||||
enum machine_mode op_mode = GET_MODE (XEXP (rtl, 0));
|
||||
|
||||
if (op_mode == VOIDmode)
|
||||
op_mode = GET_MODE (XEXP (rtl, 1));
|
||||
if (op_mode != VOIDmode && GET_MODE_CLASS (op_mode) != MODE_INT)
|
||||
break;
|
||||
|
||||
op0 = mem_loc_descriptor (XEXP (rtl, 0), mode,
|
||||
VAR_INIT_STATUS_INITIALIZED);
|
||||
op1 = mem_loc_descriptor (XEXP (rtl, 1), mode,
|
||||
VAR_INIT_STATUS_INITIALIZED);
|
||||
|
||||
if (op0 == 0 || op1 == 0)
|
||||
break;
|
||||
|
||||
if (op_mode != VOIDmode
|
||||
&& GET_MODE_SIZE (op_mode) < DWARF2_ADDR_SIZE)
|
||||
{
|
||||
HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
|
||||
dw_loc_descr_ref last0, last1;
|
||||
for (last0 = op0;
|
||||
last0->dw_loc_next != NULL;
|
||||
last0 = last0->dw_loc_next)
|
||||
;
|
||||
for (last1 = op1;
|
||||
last1->dw_loc_next != NULL;
|
||||
last1 = last1->dw_loc_next)
|
||||
;
|
||||
if (CONST_INT_P (XEXP (rtl, 0)))
|
||||
op0 = int_loc_descriptor (INTVAL (XEXP (rtl, 0)) & mask);
|
||||
/* deref_size zero extends, so no need to mask it again. */
|
||||
else if (last0->dw_loc_opc != DW_OP_deref_size
|
||||
|| last0->dw_loc_oprnd1.v.val_int
|
||||
> GET_MODE_SIZE (op_mode))
|
||||
{
|
||||
add_loc_descr (&op0, int_loc_descriptor (mask));
|
||||
add_loc_descr (&op0, new_loc_descr (DW_OP_and, 0, 0));
|
||||
}
|
||||
if (CONST_INT_P (XEXP (rtl, 1)))
|
||||
op1 = int_loc_descriptor (INTVAL (XEXP (rtl, 1)) & mask);
|
||||
/* deref_size zero extends, so no need to mask it again. */
|
||||
else if (last1->dw_loc_opc != DW_OP_deref_size
|
||||
|| last1->dw_loc_oprnd1.v.val_int
|
||||
> GET_MODE_SIZE (op_mode))
|
||||
{
|
||||
add_loc_descr (&op1, int_loc_descriptor (mask));
|
||||
add_loc_descr (&op1, new_loc_descr (DW_OP_and, 0, 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
add_loc_descr (&op1, new_loc_descr (DW_OP_plus_uconst, bias, 0));
|
||||
{
|
||||
HOST_WIDE_INT bias = 1;
|
||||
bias <<= (DWARF2_ADDR_SIZE * BITS_PER_UNIT - 1);
|
||||
add_loc_descr (&op0, new_loc_descr (DW_OP_plus_uconst, bias, 0));
|
||||
if (CONST_INT_P (XEXP (rtl, 1)))
|
||||
op1 = int_loc_descriptor ((unsigned HOST_WIDE_INT) bias
|
||||
+ INTVAL (XEXP (rtl, 1)));
|
||||
else
|
||||
add_loc_descr (&op1, new_loc_descr (DW_OP_plus_uconst,
|
||||
bias, 0));
|
||||
}
|
||||
}
|
||||
goto do_compare;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user