This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PR debug/60655, debug loc expressions
- From: Alan Modra <amodra at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: "Maciej W. Rozycki" <macro at codesourcery dot com>
- Date: Tue, 9 Sep 2014 21:20:27 +0930
- Subject: PR debug/60655, debug loc expressions
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot DEB dot 1 dot 10 dot 1409020249380 dot 2958 at tp dot orcam dot me dot uk> <CAGWvnyk61JeAUVBogq5uf5gDQzqkj+-VTuNag1FMb=h6ttNztg at mail dot gmail dot com> <20140903053117 dot GF17693 at bubble dot grove dot modra dot org> <20140904122150 dot GL17693 at bubble dot grove dot modra dot org> <alpine dot DEB dot 1 dot 10 dot 1409042020320 dot 27075 at tp dot orcam dot me dot uk> <20140905013004 dot GN17693 at bubble dot grove dot modra dot org>
On Fri, Sep 05, 2014 at 11:00:04AM +0930, Alan Modra wrote:
> Of course it would be better to repair the damage done to debug info
> rather than rejecting it outright..
This cures PR60655 on PowerPC by passing the horrible debug_loc
expressions we have through simplify_rtx. Not only do we get
reg10 + &.LANCHOR0 + const(0x14f - &.LANCHOR0) and
reg10 + &modulus + const(~&d_data),
the two expressions that cause the PR due to (CONST (MINUS ..)) and
(CONST (NOT ..)), but also things like
~reg5 - reg31 + reg5 + reg10 + &modulus
where "~reg5 + reg5" is an inefficient way to write "-1".
It turns out that merely passing these expression through simplify_rtx
isn't enough. Some tweaking is necessary to make (CONST (NOT ..)) and
(CONST (MINUS ..)) recognised by simplify_plus_minus, and even after
doing that, the two reg5 terms are not cancelled.
The reg5 case starts off with the simplify_plus_minus sorted ops array
effectively containing the expression
-reg31 + reg10 + reg5 + -reg5 + &modulus + -1
The first combination tried is &modulus + -1, which is rejected to
prevent recursion. The next combination tried is -reg5 + -1, which is
simlified to ~reg5. Well, that is a valid simplification, but the
trouble is that this prevents "reg5 + -reg5" being simplified to 0.
What's more, "&modulus + -1" is no more expensive than "&modulus",
since they are both emitted as an address field with a symbol+addend
relocation. For that reason, I believe we should not consider
combining a const_int with any other term after finding that it can be
combined with a symbol_ref or other similar term.
Bootstrapped and regression tested powerpc64-linux and x86_64-linux.
I measured before/after bootstrap times on x86_64-linux because I was
concerned about the extra simplify_rtx calls, and was pleasantly
surprised to see a 0.23% improvement in bootstrap time. (Which of
course is likely just noise.) OK to apply?
PR debug/60655
* simplify-rtx.c (simplify_plus_minus): Delete unused "input_ops".
Handle CONST wrapped NOT, NEG and MINUS. Break out of innermost
loop when finding a trivial CONST expression.
* var-tracking.c (vt_expand_var_loc_chain): Call simplify_rtx.
Index: gcc/simplify-rtx.c
===================================================================
--- gcc/simplify-rtx.c (revision 214487)
+++ gcc/simplify-rtx.c (working copy)
@@ -3960,7 +3960,7 @@ simplify_plus_minus (enum rtx_code code, enum mach
{
struct simplify_plus_minus_op_data ops[8];
rtx result, tem;
- int n_ops = 2, input_ops = 2;
+ int n_ops = 2;
int changed, n_constants = 0, canonicalized = 0;
int i, j;
@@ -3997,7 +3997,6 @@ simplify_plus_minus (enum rtx_code code, enum mach
n_ops++;
ops[i].op = XEXP (this_op, 0);
- input_ops++;
changed = 1;
canonicalized |= this_neg;
break;
@@ -4010,14 +4009,35 @@ simplify_plus_minus (enum rtx_code code, enum mach
break;
case CONST:
- if (n_ops < 7
- && GET_CODE (XEXP (this_op, 0)) == PLUS
- && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
- && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
+ if (GET_CODE (XEXP (this_op, 0)) == NEG
+ && CONSTANT_P (XEXP (XEXP (this_op, 0), 0)))
{
ops[i].op = XEXP (XEXP (this_op, 0), 0);
+ ops[i].neg = !this_neg;
+ changed = 1;
+ canonicalized = 1;
+ }
+ else if (n_ops < 7
+ && GET_CODE (XEXP (this_op, 0)) == NOT
+ && CONSTANT_P (XEXP (XEXP (this_op, 0), 0)))
+ {
+ ops[n_ops].op = CONSTM1_RTX (mode);
+ ops[n_ops++].neg = this_neg;
+ ops[i].op = XEXP (XEXP (this_op, 0), 0);
+ ops[i].neg = !this_neg;
+ changed = 1;
+ canonicalized = 1;
+ }
+ else if (n_ops < 7
+ && (GET_CODE (XEXP (this_op, 0)) == PLUS
+ || GET_CODE (XEXP (this_op, 0)) == MINUS)
+ && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
+ && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
+ {
+ ops[i].op = XEXP (XEXP (this_op, 0), 0);
ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
- ops[n_ops].neg = this_neg;
+ ops[n_ops].neg
+ = (GET_CODE (XEXP (this_op, 0)) == MINUS) ^ this_neg;
n_ops++;
changed = 1;
canonicalized = 1;
@@ -4141,16 +4161,21 @@ simplify_plus_minus (enum rtx_code code, enum mach
else
tem = simplify_binary_operation (ncode, mode, lhs, rhs);
- /* Reject "simplifications" that just wrap the two
- arguments in a CONST. Failure to do so can result
- in infinite recursion with simplify_binary_operation
- when it calls us to simplify CONST operations. */
- if (tem
- && ! (GET_CODE (tem) == CONST
- && GET_CODE (XEXP (tem, 0)) == ncode
- && XEXP (XEXP (tem, 0), 0) == lhs
- && XEXP (XEXP (tem, 0), 1) == rhs))
+ if (tem)
{
+ /* Reject "simplifications" that just wrap the two
+ arguments in a CONST. Failure to do so can result
+ in infinite recursion with simplify_binary_operation
+ when it calls us to simplify CONST operations.
+ Also, if we find such a simplification, don't try
+ any more combinations with this rhs: We must have
+ something like symbol+offset, ie. one of the
+ trivial CONST expressions we handle later. */
+ if (GET_CODE (tem) == CONST
+ && GET_CODE (XEXP (tem, 0)) == ncode
+ && XEXP (XEXP (tem, 0), 0) == lhs
+ && XEXP (XEXP (tem, 0), 1) == rhs)
+ break;
lneg &= rneg;
if (GET_CODE (tem) == NEG)
tem = XEXP (tem, 0), lneg = !lneg;
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c (revision 214898)
+++ gcc/var-tracking.c (working copy)
@@ -8375,7 +8375,15 @@ vt_expand_var_loc_chain (variable var, bitmap regs
*pendrecp = pending_recursion;
if (!pendrecp || !pending_recursion)
- var->var_part[0].cur_loc = result;
+ {
+ if (result)
+ {
+ rtx tem = simplify_rtx (result);
+ if (tem)
+ result = tem;
+ }
+ var->var_part[0].cur_loc = result;
+ }
return result;
}
--
Alan Modra
Australia Development Lab, IBM