This is the mail archive of the 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]

Re: Strange RTL


On Wed, 31 Jul 2002, Chris Lattner wrote:

> union X { void *B; };
> union X foo() {
>         union X A;
>         A.B = (void*)123;   /* Interesting part */
>         return A;
> }
> The RTL generated for the assignment is the following (this is from the
> .00.rtl dump, Pmode=PDI):
> (insn 10 5 15 (set (subreg:PDI (reg/v:DI 107) 0)
>         (const_int 123 [0x7b])) -1 (nil)
>     (nil))
> So, my question is: why does the subreg come into play here?

Well, the union/struct is small enough, so only a pseudo is allocated for
it (of DImode size) as backing storage.  Because it's a union, it could
contain other members (which ultimately could result also in different
modes for that pseudo, think about a float also being member).  But the
pseudo itself only has one mode, DImode in this case.  To access the real
member it needs to be converted to the correct mode (PDImode in this case,
if a float would be there, and you would access it, it would be DFmode).
Conversion in RTL is done with subregs.  To use PDImode for this pseudo
from the beginning would be a pure optimization, based on the fact that
this union only contains one member of pointer mode.  I guess this
optimization simply isn't implemented, as a union of only one member
doesn't seem very usefull.

> If I change the union to 'struct' (which should cause identical output
> in this case), then I get this output:
> (insn 10 5 15 (set (reg/v:PDI 107)
>         (const_int 123 [0x7b])) -1 (nil)
>     (nil))

Sure.  Because here the "type" of the backing storage is definitive, as it
can't overlap with any other members.


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