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]

On killing SAVE_EXPR


On Fri, Feb 09, 2001 at 09:31:33PM -0500, Richard Kenner wrote:
> Let's look at a typical use of SAVE_EXPR.  Suppose we have a language
> where index bounds are checked (e.g., Ada) and you have an expression
> of the form (in C syntax)
> 
> 	... (expression1 && X[expression2]) ...
[...]
> What are you proposing to do, as I understand it, is to create some
> (unnamed) variable, which we'll call UV for clarity and use it instead
> of "expression2".  Where do you propose putting the statement to
> initialize it?

You'd generate the equivalent of

	... (expression1 && (tmp = expression2, X[tmp])) ...

> But if you do that haven't you created something with the same
> semantic problems as SAVE_EXPR, whatever they are, except that
> now it's much more complicated?

No, a COMPOUND_EXPR can be re-evaluated many times without
worrying about the side effects of evaluation on the tree
representation itself.

Incidentally, a statement expression currently expands to an
RTL_EXPR, which is worse than a SAVE_EXPR, in that it can only
be evaluated once with no hope of fiddling state later.  This
is another one I intend to axe.

> And now you lose optimization.  In the case where these are size or offsets,
> usually knowing what the "initializing value", in your model, is will
> allow significant optimizations.

That's cse's job.  I'd hate to think that our compiler is so
lame that I'll get worse code if I write

   int f(int *array, int y)
   {
      int offset = y+5;
      return array[offset];
   }

instead of

   int g(int *array, int y)
   {
      return array[y+5];
   }

>     To work around problems encountered with evaluating SAVE_EXPRs.
>     I won't pretend to know exactly which ones, or why UNSAVE_EXPR
>     was thought to be a "solution".
> 
> Well, unless we can state the problems, why talk about eliminating
> them in a way that will cause yet more serious problems (and not
> really solve them since it's the same semantic issue)?

Oh, I can state the problem in general.  I just knew that UNSAVE_EXPR
was invented for C++, and didn't know in what context they encountered
the problem.  Jason has answered this.

> I'm not aware of any problems in the GCC context or even in the Ada context
> (where SAVE_EXPRs are used *far, far* more than in C and probably even C++).

The problem occurs whenever you want to evaluate an expression
multiple times.

The instance Jason mentioned involves code replication, where two
copies are generated on independant code paths, both of which are
present in the final function expansion.

The instance I'm most familiar is in tail-call elimination.  Here
we generate two code sequences -- one as a normal call and one as
a tail-call or tail-recursion.  At some point later we'll select
one sequence or the other depending on whether the tail-call
sequence is actually legitimate.

A third instance involves inlining at the tree level.  In this case
we've spliced one function into others, potentially many times.
Naturally all copies are present in the output.

In all cases we've got this infernal SAVE_EXPR that changes state
during evaluation.  It emits its initialization code on queue into
the first code sequence.  But when you go to generate the second
code sequence, you get no initialization code because "clearly" 
it has already been emitted.  But that happened on a different code
path, and we wind up using uninitialized pseudos.

So at present we jump through all kinds of hoops to reset the state
of a SAVE_EXPR between evaluations.  Decidedly unclean.


r~


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