On Tue, Sep 9, 2014 at 1:50 PM, Alan Modra <amo...@gmail.com> wrote: > 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);
why wasn't 'result' built using simplify_gen_* in the first place? I also note that debug_insns can have all sorts of weird (even invalid) and un-recognized RTL which the simplify_rtx machinery may not like (and thus ICE). CSELIB seems to do the less optimal copy_rtx, valueize operands, re-simplify operation instead of valueizing the operands and then simplify_gen_ the actual RTX here (skipping that when valueizing the operands did nothing). Richard. > + if (tem) > + result = tem; > + } > + var->var_part[0].cur_loc = result; > + } > > return result; > } > > -- > Alan Modra > Australia Development Lab, IBM