Message ID | alpine.DEB.2.20.9.1603040927150.1231@idea |
---|---|
State | New |
Headers | show |
On 03/04/2016 03:27 PM, Patrick Palka wrote: >>> I still suggest to try making write_test_expr() avoid emitting >>> redundant parentheses for chains of || or &&, which would fix the >>> original issue all the same. Previously you claimed that such a >>> change would not be simpler than your current patch, but I gave it a >>> quick try and ended up with a much smaller patch: This looks like a reasonable stopgap if a release manager thinks this is important enough to fix for gcc-6. Some comments below for that case. Longer term I'm not sure - in theory maybe the switch would allow us to generate better code, but I tried it and code size actually seems to go up (could be jump tables however). I also noticed that in the version with the switch we still have cases of switch (cached_type) { .... default: switch (cached_type) { } } so that might be a point where the patch could be improved to see if we can get better code generation by collapsing these switches. Might also be worth trying to optimize this pattern in gcc. > static unsigned int > -write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int > flags) > +write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int > flags, > + bool emit_parens = true) Indentation looks wrong, but could be mailer damage. You should also update the function comment. > + attrs_cached > + = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags, > + need_parens); Same here, watch indentation. Bernd
On Fri, Mar 04, 2016 at 04:13:41PM +0100, Bernd Schmidt wrote: > On 03/04/2016 03:27 PM, Patrick Palka wrote: > >>>I still suggest to try making write_test_expr() avoid emitting > >>>redundant parentheses for chains of || or &&, which would fix the > >>>original issue all the same. Previously you claimed that such a > >>>change would not be simpler than your current patch, but I gave it a > >>>quick try and ended up with a much smaller patch: > > This looks like a reasonable stopgap if a release manager thinks this is > important enough to fix for gcc-6. Some comments below for that case. Longer I think it is important for gcc-6, because one compiler for weirdo reasons imposes unreasonably small restrictions on the () nesting and some people use it as stage1 compiler. So, with the formatting nits fixed, if it got appropriately tested, I think we want it for stage4. Jakub
On 04/03/16 16:13, Bernd Schmidt wrote: > On 03/04/2016 03:27 PM, Patrick Palka wrote: >>>> I still suggest to try making write_test_expr() avoid emitting >>>> redundant parentheses for chains of || or &&, which would fix the >>>> original issue all the same. Previously you claimed that such a >>>> change would not be simpler than your current patch, but I gave it a >>>> quick try and ended up with a much smaller patch: > > This looks like a reasonable stopgap if a release manager thinks this > is important enough to fix for gcc-6. Some comments below for that > case. Longer term I'm not sure - in theory maybe the switch would > allow us to generate better code, but I tried it and code size > actually seems to go up (could be jump tables however). I also noticed > that in the version with the switch we still have cases of > > switch (cached_type) > { > .... > default: > switch (cached_type) > { > } > } > > so that might be a point where the patch could be improved to see if > we can get better code generation by collapsing these switches. Might > also be worth trying to optimize this pattern in gcc. > > > > Bernd I can look into that if you deem it worth it, or would you rather just go with Patriks suppressed parenthesis?
On 03/04/2016 05:03 PM, Jesper Broge Jørgensen wrote: > I can look into that if you deem it worth it, or would you rather just > go with Patriks suppressed parenthesis? For the moment (in stage4) we'll at most go with Patrick's patch. Whether we do anything beyond that depends on whether we can demonstrate a benefit - it might be worth investigating. Maybe more interesting than fixing genattrtab would be an optimization to identify switch patterns like the one I posted. Bernd
On 03/04/2016 08:13 AM, Bernd Schmidt wrote: > On 03/04/2016 03:27 PM, Patrick Palka wrote: >>>> I still suggest to try making write_test_expr() avoid emitting >>>> redundant parentheses for chains of || or &&, which would fix the >>>> original issue all the same. Previously you claimed that such a >>>> change would not be simpler than your current patch, but I gave it a >>>> quick try and ended up with a much smaller patch: > > This looks like a reasonable stopgap if a release manager thinks this is > important enough to fix for gcc-6. Some comments below for that case. > Longer term I'm not sure - in theory maybe the switch would allow us to > generate better code, but I tried it and code size actually seems to go > up (could be jump tables however). I also noticed that in the version > with the switch we still have cases of > > switch (cached_type) > { > .... > default: > switch (cached_type) > { > } > } > > so that might be a point where the patch could be improved to see if we > can get better code generation by collapsing these switches. Might also > be worth trying to optimize this pattern in gcc. There's probably a good number of things we could do for this and related scenarios. Essentially DOM and threading are unlikely to do anything with this because the path from the outer case into the inner switch is going to have multiple values associated with cached_type. The backwards threader, if it was presented with SSI rather than SSA could probably untangle it, but I'm not sure we're ready to make the jump to SSI (though it would simplify VRP & DOM). Jeff
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index b64d8b9..e2ccf1f 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -3432,16 +3432,16 @@ find_attrs_to_cache (rtx exp, bool create) #define FLG_OUTSIDE_AND 8 static unsigned int -write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags) +write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags, + bool emit_parens = true) { int comparison_operator = 0; RTX_CODE code; struct attr_desc *attr; - /* In order not to worry about operator precedence, surround our part of - the expression with parentheses. */ + if (emit_parens) + fprintf (outf, "("); - fprintf (outf, "("); code = GET_CODE (exp); switch (code) { @@ -3575,8 +3575,18 @@ write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags) || GET_CODE (XEXP (exp, 1)) == EQ_ATTR || (GET_CODE (XEXP (exp, 1)) == NOT && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR))) - attrs_cached - = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags); + { + bool need_parens = true; + + /* No need to emit parentheses around the right-hand operand if we are + continuing a chain of && or ||. */ + if (GET_CODE (XEXP (exp, 1)) == code) + need_parens = false; + + attrs_cached + = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags, + need_parens); + } else write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags | comparison_operator); @@ -3794,7 +3804,9 @@ write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags) GET_RTX_NAME (code)); } - fprintf (outf, ")"); + if (emit_parens) + fprintf (outf, ")"); + return attrs_cached; }