This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

folding after TER notes


Just some notes I've gathered on folding statements modified by TER...

First, a lot of the changes made do not affect the code we generate in
a meaningful way.  That's because a lot of the changes merely reorder
operands in conditionals, arithmetic expressions and the like.  For
example, after TER we might have something like


if (a->b != c) ...

Folding will rewrite that into

if (c != a->b)

[ In general we will try to have _DECL nodes as the first operand and
  expressions as the second operand to binary operators. ]

I've disabled the code in fold which rearranges operands so that I can
better evaluate the real effects of folding expressions resulting from
TER.

There are definitely cases where folding after TER does result
in simpler trees and sometimes better code generation.

For example, I've seen folding after TER change stuff like this:

   t = *&t->exp.operands[0];

into something like this:

   t = t->exp.operands[0];

This is by far the most common effect I'm seeing for folding after TER.
It's happening enough that I suspect we're missing propagations earlier
in our SSA optimization path.  I don't think it's really advisable to
evaluate folding after TER without first looking at why we're seeing
so many *& expressions showing up after TER.

In a few places we change conditionals like

(x & 128) 

turns into:

(signed char)x < 0

I'm not sure if that's really an improvement or not, but it's something
that I'm seeing relatively often.

In a few places we're able to kill some casts.  For example:

!   pretmp.428 = (int) (reg_class) D.18943;

might turn into:

!   pretmp.428 = D.18943;

Or in some cases we remove redundant operations:

!   *p = (char) (val & 255);

Turns into:
!   *p = (char) val;


In a small number of cases we turn pointer arithmetic into array
indexing:

!   bodyp = &D.20390->exp.operands[0] + 4B;

Is folded into:

!   bodyp = &D.20390->exp.operands[1];


This is something I would have expected to happen before TER.

In a few places we're turning simple conditionals like

x->bitfield != 0

into

(BIT_FIELD_REF (...) & <const>) != 0

Which may or may not be a good thing to do.


Sometimes we get multiple transformations.  For example, turning pointer
arithmetic into array indexing and removal of *& occur relatively
often together in the same expression.

Anyway, I'm going to look into why we're seeing so many *& expressions
during TER.  It just seems to me that such expressions should have been
exposed and optimized before TER and that we might get some secondary
benefits from fixing this oversight.

Jeff




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]