This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: alpha haifa regression
- To: law at cygnus dot com
- Subject: Re: alpha haifa regression
- From: Joern Rennecke <amylaar at cygnus dot co dot uk>
- Date: Tue, 7 Oct 1997 21:12:38 +0100 (BST)
- Cc: wilson at cygnus dot com, rth at cygnus dot com, egcs at cygnus dot com
> In message <199709292200.PAA08832@cygnus.com>you write:
[Richard Henderson:]
> > But since the tests in true_dependance are symmetric, that will
> > then cause problems for va_arg(list, int), no?
> >
[Jim Wilson:]
> > I would suspect no, because va_arg(list, int) expands into complicated code
> > that does an actual aggregate (array and/or structure) memory access, and
> > hence va_arg references are always aggregate references, even if a scalar
> > type is specified.
> I suspect yes -- I've already seen it on the PA.
I just checked it for alpha. pa and sh. For a TYPE argument, va_arg
basically casts (or assigns) a void* to a TYPE*, and then dereferences
the TYPE*. The result is a memory access that has MEM_IN_STRUCT_P set
iff TYPE is a struct.
I propose to cast to a (struct { TYPE t;} *) instead, and dereference that
and select the t member (can of course both be done with the -> operator).
If TYPE is smaller than STRUCTURE_SIZE_BOUNDARY, and the target is
big endian, we have to adjust the alignment padding.
care. We have then to
the t member of this structure.
> > It is easy enough to check by looking at the RTL generated by a va_arg
> > call using a scalar. I suspect that it will have MEM_IN_STRUCT_P set.
> Depends on the target, but most end up doing something like this if
> you remove all the casts, address computations & rounding:
>
>
> blah = *(type*)address
It is actually has an impact what form address takes. If it happens to be
a a (type *) might happen for type == char if some port uses char *
for address) and the actual operation is a cast with a following dereference,
without an intervening assignment to a variable, the actual form of address
matters - i.e. if there is some non-zero integer added to a pointer, the
MEM_IN_STRUCT_P of the resulting mem gets set.
However, what I have seen so far either uses an ntervening assignment,
or an intervening cast to (void*), thus resulting in a MEM without
MEM_IN_STRUCT_P.