* [PATCH] Optimize DW_OP_{breg{[0-9],[12][0-9],3[01],x},fbreg} followed by DW_OP_plus_uconst
@ 2009-04-08 15:26 Jakub Jelinek
2009-04-24 22:09 ` Ian Lance Taylor
0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2009-04-08 15:26 UTC (permalink / raw)
To: Jason Merrill; +Cc: gcc-patches
Hi!
When working on the patch I've just posted, I've noticed a lot of
sequences like:
.byte 0x73 # DW_OP_breg3
.sleb128 0
.byte 0x23 # DW_OP_plus_uconst
.uleb128 0x98
.byte 0x6 # DW_OP_deref
or
.byte 0x91 # DW_OP_fbreg
.sleb128 -1872
.byte 0x23 # DW_OP_plus_uconst
.uleb128 0x70
in .debug_info. We can merge the constant addition with the breg*/fbreg
offset in most cases. This patch creates a new function for that and
uses it in all places that were deciding if DW_OP_plus_uconst or DW_OP_plus
should be used.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2009-04-08 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (loc_descr_plus_const): New function.
(build_cfa_aligned_loc, tls_mem_loc_descriptor,
mem_loc_descriptor, loc_descriptor_from_tree_1,
descr_info_loc, gen_variable_die): Use it.
--- gcc/dwarf2out.c.jj 2009-04-08 11:10:16.000000000 +0200
+++ gcc/dwarf2out.c 2009-04-08 12:52:16.000000000 +0200
@@ -3890,6 +3890,47 @@ add_loc_descr (dw_loc_descr_ref *list_he
*d = descr;
}
+/* Add a constant OFFSET to a location expression. */
+
+static void
+loc_descr_plus_const (dw_loc_descr_ref *list_head, HOST_WIDE_INT offset)
+{
+ dw_loc_descr_ref loc;
+ HOST_WIDE_INT *p;
+
+ gcc_assert (*list_head != NULL);
+
+ if (!offset)
+ return;
+
+ /* Find the end of the chain. */
+ for (loc = *list_head; loc->dw_loc_next != NULL; loc = loc->dw_loc_next)
+ ;
+
+ p = NULL;
+ if (loc->dw_loc_opc == DW_OP_fbreg
+ || (loc->dw_loc_opc >= DW_OP_breg0 && loc->dw_loc_opc <= DW_OP_breg31))
+ p = &loc->dw_loc_oprnd1.v.val_int;
+ else if (loc->dw_loc_opc == DW_OP_bregx)
+ p = &loc->dw_loc_oprnd2.v.val_int;
+
+ /* If the last operation is fbreg, breg{0..31,x}, optimize by adjusting its
+ offset. Don't optimize if an signed integer overflow would happen. */
+ if (p != NULL
+ && ((offset > 0 && *p <= INTTYPE_MAXIMUM (HOST_WIDE_INT) - offset)
+ || (offset < 0 && *p >= INTTYPE_MINIMUM (HOST_WIDE_INT) - offset)))
+ *p += offset;
+
+ else if (offset > 0)
+ loc->dw_loc_next = new_loc_descr (DW_OP_plus_uconst, offset, 0);
+
+ else
+ {
+ loc->dw_loc_next = int_loc_descriptor (offset);
+ add_loc_descr (&loc->dw_loc_next, new_loc_descr (DW_OP_plus, 0, 0));
+ }
+}
+
/* Return the size of a location descriptor. */
static unsigned long
@@ -4409,9 +4450,7 @@ build_cfa_aligned_loc (HOST_WIDE_INT off
head = new_reg_loc_descr (dwarf_fp, 0);
add_loc_descr (&head, int_loc_descriptor (alignment));
add_loc_descr (&head, new_loc_descr (DW_OP_and, 0, 0));
-
- add_loc_descr (&head, int_loc_descriptor (offset));
- add_loc_descr (&head, new_loc_descr (DW_OP_plus, 0, 0));
+ loc_descr_plus_const (&head, offset);
}
else
head = new_reg_loc_descr (dwarf_fp, offset);
@@ -9913,7 +9952,7 @@ static dw_loc_descr_ref
tls_mem_loc_descriptor (rtx mem)
{
tree base;
- dw_loc_descr_ref loc_result, loc_result2;
+ dw_loc_descr_ref loc_result;
if (MEM_EXPR (mem) == NULL_TREE || MEM_OFFSET (mem) == NULL_RTX)
return NULL;
@@ -9929,21 +9968,7 @@ tls_mem_loc_descriptor (rtx mem)
return NULL;
if (INTVAL (MEM_OFFSET (mem)))
- {
- if (INTVAL (MEM_OFFSET (mem)) >= 0)
- add_loc_descr (&loc_result,
- new_loc_descr (DW_OP_plus_uconst,
- INTVAL (MEM_OFFSET (mem)), 0));
- else
- {
- loc_result2 = mem_loc_descriptor (MEM_OFFSET (mem), GET_MODE (mem),
- VAR_INIT_STATUS_INITIALIZED);
- if (loc_result2 == 0)
- return NULL;
- add_loc_descr (&loc_result, loc_result2);
- add_loc_descr (&loc_result, new_loc_descr (DW_OP_plus, 0, 0));
- }
- }
+ loc_descr_plus_const (&loc_result, INTVAL (MEM_OFFSET (mem)));
return loc_result;
}
@@ -10108,11 +10133,8 @@ mem_loc_descriptor (rtx rtl, enum machin
if (mem_loc_result == 0)
break;
- if (GET_CODE (XEXP (rtl, 1)) == CONST_INT
- && INTVAL (XEXP (rtl, 1)) >= 0)
- add_loc_descr (&mem_loc_result,
- new_loc_descr (DW_OP_plus_uconst,
- INTVAL (XEXP (rtl, 1)), 0));
+ if (GET_CODE (XEXP (rtl, 1)) == CONST_INT)
+ loc_descr_plus_const (&mem_loc_result, INTVAL (XEXP (rtl, 1)));
else
{
dw_loc_descr_ref mem_loc_result2
@@ -10526,13 +10548,7 @@ loc_descriptor_from_tree_1 (tree loc, in
}
bytepos = bitpos / BITS_PER_UNIT;
- if (bytepos > 0)
- add_loc_descr (&ret, new_loc_descr (DW_OP_plus_uconst, bytepos, 0));
- else if (bytepos < 0)
- {
- add_loc_descr (&ret, int_loc_descriptor (bytepos));
- add_loc_descr (&ret, new_loc_descr (DW_OP_plus, 0, 0));
- }
+ loc_descr_plus_const (&ret, bytepos);
have_address = 1;
break;
@@ -10616,11 +10632,7 @@ loc_descriptor_from_tree_1 (tree loc, in
if (ret == 0)
return 0;
- add_loc_descr (&ret,
- new_loc_descr (DW_OP_plus_uconst,
- tree_low_cst (TREE_OPERAND (loc, 1),
- 0),
- 0));
+ loc_descr_plus_const (&ret, tree_low_cst (TREE_OPERAND (loc, 1), 0));
break;
}
@@ -13001,10 +13013,7 @@ descr_info_loc (tree val, tree base_decl
loc = descr_info_loc (TREE_OPERAND (val, 0), base_decl);
if (!loc)
break;
- add_loc_descr (&loc,
- new_loc_descr (DW_OP_plus_uconst,
- tree_low_cst (TREE_OPERAND (val, 1),
- 1), 0));
+ loc_descr_plus_const (&loc, tree_low_cst (TREE_OPERAND (val, 1), 0));
}
else
{
@@ -13920,9 +13929,7 @@ gen_variable_die (tree decl, tree origin
loc->dw_loc_oprnd1.v.val_addr
= plus_constant (loc->dw_loc_oprnd1.v.val_addr, off);
else
- add_loc_descr (&loc,
- new_loc_descr (DW_OP_plus_uconst,
- off, 0));
+ loc_descr_plus_const (&loc, off);
}
add_AT_loc (var_die, DW_AT_location, loc);
remove_AT (var_die, DW_AT_declaration);
@@ -13985,8 +13992,7 @@ gen_variable_die (tree decl, tree origin
loc->dw_loc_oprnd1.v.val_addr
= plus_constant (loc->dw_loc_oprnd1.v.val_addr, off);
else
- add_loc_descr (&loc, new_loc_descr (DW_OP_plus_uconst,
- off, 0));
+ loc_descr_plus_const (&loc, off);
}
add_AT_loc (var_die, DW_AT_location, loc);
}
Jakub
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] Optimize DW_OP_{breg{[0-9],[12][0-9],3[01],x},fbreg} followed by DW_OP_plus_uconst
2009-04-08 15:26 [PATCH] Optimize DW_OP_{breg{[0-9],[12][0-9],3[01],x},fbreg} followed by DW_OP_plus_uconst Jakub Jelinek
@ 2009-04-24 22:09 ` Ian Lance Taylor
0 siblings, 0 replies; 2+ messages in thread
From: Ian Lance Taylor @ 2009-04-24 22:09 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Jason Merrill, gcc-patches
Jakub Jelinek <jakub@redhat.com> writes:
> 2009-04-08 Jakub Jelinek <jakub@redhat.com>
>
> * dwarf2out.c (loc_descr_plus_const): New function.
> (build_cfa_aligned_loc, tls_mem_loc_descriptor,
> mem_loc_descriptor, loc_descriptor_from_tree_1,
> descr_info_loc, gen_variable_die): Use it.
This is OK.
Thanks.
Ian
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-04-24 22:01 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-08 15:26 [PATCH] Optimize DW_OP_{breg{[0-9],[12][0-9],3[01],x},fbreg} followed by DW_OP_plus_uconst Jakub Jelinek
2009-04-24 22:09 ` Ian Lance Taylor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).