This is the mail archive of the egcs@egcs.cygnus.com mailing list for the EGCS project. See the EGCS home page for more information.


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

Re: Meaning of MODIFY_EXPR? (Affects g77, maybe others....)


>  The ability of the compiler to assume non-overlapping copies should
>be implicit in MODIFY_EXPR.  This allows for more optimization in C,
>and that is important.  As you make clear, changing the meaning of
>MODIFY_EXPR would be like changing all memcpys to memmoves;
>potentially costly.

Well, I'm concerned only with *local* partial overlaps, which I forgot
to specify, but trying to accommodate those in C might indeed cost
some applications in terms of performance.  (I would think that the
vast majority of assignments would be provably not partially overlapped,
but might be wrong.)

In C, an assignment like in that sample program I included involves
purely local lhs and rhs, just as in the Fortran cases.  But, C's
"undefining" of partially-overlapped assignments extends all the way
out through assignments via pointers passed in as arguments, etc.,
affecting much more than just local assignments.

In other words, an assignment like

  p->agg = q->agg;

in C, where `agg' is of some large aggregate type, can proceed without
worrying about whether `p' and `q', which could be arguments or globals,
might denote overlapping storage areas vis-a-vis their dereferenced
`agg' members.

Whereas, in Fortran, that sort of thing is already defined to either
always work, if the potential overlap can be identified by looking
just at the module (i.e. it's not created by the association of actual
and dummy arguments), or be completely undefined.

I hadn't really thought about it this way.  What it tells me is that
the performance impact of simply changing MODIFY_EXPR is potentially much
greater for gcc (and maybe g77 as well) than leaving it as is (and
documenting it) and just changing g77 to check for the specific
case under consideration.

>  I suggest we take the alternative of fixing the MODIFY_EXPR
>documentation to reflect its current semantics, and then that you take
>the step of modifying g77 as appropriate.

Looking at just gcc and g77, I'd have to agree.

>  Easy for me to say.

Right.  :)

Let's let people maintaining other front ends look into *their*
alias-assignment issues and then chime in, though.

So, in line with memcpy/memmove, let's talk in terms of a COPY_EXPR
and MOVE_EXPR for now (these are hypothetical), and (mostly) put aside the
issue of which should be an alias for MODIFY_EXPR.

Might the performance implications of having a given front end use
COPY_EXPR and work around the alias problem by using temporaries,
etc., be greater than just using MOVE_EXPR, and leaving the problem
to the back end?

For g77, it probably doesn't matter much, because of the above -- Fortran
already prohibits argument-binding-created aliasing, also, it's usually
easy (in practice, in most cases) for g77 to prove that no partial aliasing
is possible and thus use COPY_EXPR instead of MOVE_EXPR.

Nevertheless, g77 doesn't necessarily know that a COPY_EXPR of a struct
containing two 32-bit floats will work just like a MOVE_EXPR on an x86,
while there'll be a difference when the struct contains two 64-bit floats.

So, not having a MOVE_EXPR means g77 will have to assume it needs to
create and use temporaries to contain the two 32-bit floats (i.e. single-
precision COMPLEX), when it doesn't in fact have to do that.

The impact is likely to be a bit of performance loss in g77 in some
(hopefully) rare cases that already worked, because the back end
probably won't be able to determine that those temporary assignments
can be eliminated.

Whereas, if g77 could just use MOVE_EXPR, the back end might be able
to determine, for the COMPLEX case (vs. DOUBLE COMPLEX), that it is
going to use temporaries anyway, and thus not bother with *more*
temporaries.  (But maybe not.)

So, strictly speaking, it's clearly at least as good, if not better,
performance-wise, for the problem (and the pertinent info) to be pushed
down to the back end, by offering both COPY_EXPR and MOVE_EXPR, etc.
However, I don't think the performance impact to g77 of having to
always use COPY_EXPR will be that great (though I've been wrong about
this sort of thing before, sadly, involving a very similar issue --
overlapping COMPLEX arguments to the run-time library routines).

But, what about languages with more sophisticated forms of records/structs?
E.g. those with varying sizes, differently typed components, and
expressions that are themselves "values" of such types.  Then throw in
all the mess you get from combining that with OO mechanisms, plus
the fact that there's likely to be many cases of MODIFY_EXPR used
for "under-the-hood" work (which mightn't be granted the "undefined"
status by the pertinent language standard that explicit assignments
might)....

That's why I wanted to ask about this here, rather than just go and
fix the problem, and add a note or two in the doc for MODIFY_EXPR
in tree.def.  It might turn out that g++, GNAT (well, perhaps not on
this list...), or other front-end people look into this and discover
they've got lots of problematic MODIFY_EXPR's.  Changing them all
to accommodate it being a COPY_EXPR could be a hassle, if not also
a performance problem, compared to changing them to be a MOVE_EXPR
(or leaving them alone and the back end redefining MODIFY_EXPR as
MOVE_EXPR, and perhaps offering a COPY_EXPR for the gcc front end,
and others, to use to improve performance).

        tq vm, (burley)