[M3devel] a trouble with passing records by value..

Tony Hosking hosking at cs.purdue.edu
Wed Sep 1 16:54:43 CEST 2010


I would very much hesitate to remove these internal assertions in GCC since they tend to be needed to catch invariants that the rest of the compiler relies upon.  Especially, internal changes to the backend of gcc is something to be strongly avoided.  My inclination would be to type the record in a way that forces gcc to assume the worst and not pass the record in a register.  I don't know what the sparc64 ABI says about passing structs, but surely we can type it in such as way as to get the behaviour the CM3 front-end expects.

On 1 Sep 2010, at 10:41, Rodney M. Bates wrote:

> 
> 
> Jay K wrote:
>> > I don't particularly understand the SPARC64_SOLARIS issue
>>  When a record is passed by value SPARC64_SOLARIS backend goes to figure
>> out the ABI for it and it hits an assertion failure.
>>  Historically no type was associated with parameters and locals in the backend.
>> At least not for records.
>> Maybe they had a size and an alignment.
>> But certainly no fields.
>>  You know -- imagine a record with non-zero size but zero fields. Wierd eh?
>> The SPARC64_SOLARIS code in gcc doesn't like that and fails an assertion.
>>  (gcc can cope with some such cases the comments say, but still..)
>> 
> 
> Is it possible the assertion is just overzealous and can be removed?
> Or, if the assertion is really needed, can gcc be changed so it no
> longer needs it?  Would this approach be a simpler way?  I sounds like
> it might at least be a more local change, instead of the pervasive
> problems that have emerged from putting type info in at the front of
> gcc.
> 
> Or, are you trying to avoid internal changes to gcc at all cost?
> 
> 
>> If you start but don't finish fixing this problem, by giving types to parameters,
>> you can then quickly run into problems in AMD64_DARWIN, and probably all AMD64 targets.
>> I don't fully understand/remember the problem, but it is easy to uncover.
>>  Part of the problem was plain missing type information -- I fixed that in m3front.
>> If you both imported and defined a type, you wouldn't get the information.
>>    m3front was deliberately skipping imported types, even if they coincided with locally defined types.
>> If you fix that by defining "everything", you get duplicate opaque error in m3linker. I allow that now,
>> if the supertype matches.
>>  That's still not the extent of the problem on AMD64_DARWIN though.
>>  Test case p247 covers much of this.
>> It just passes a record with a pointer and integer by value.
>> Two integers (in record) have same problem.
>>  To try to summarize:
>>   There has been a historical lack of use of type information in the backend.
>>   Mostly the backend does get good type information from frontend, but
>>    it didn't associate it with locals/parameters. And it is better now.
>>   (globals are worse still I believe)
>>      I'm not 100% sure, but it appears to me that both the frontend and backend layout records.
>>    That is, determine the offset of each field, such as by adding up the sizes of preceding fields.
>>     (It is more involved than that, due to alignment.)
>>   I am concerned that these two layouts might not agree, and the result would be terrible.
>>  -  Jay
>> ------------------------------------------------------------------------
>> From: hosking at cs.purdue.edu
>> Date: Tue, 31 Aug 2010 22:22:16 -0400
>> To: jay.krell at cornell.edu
>> CC: m3devel at elegosoft.com
>> Subject: Re: [M3devel] a trouble with passing records by value..
>> I believe there is one way out here.
>> Modula-3's dynamic types (UID-based) give a story for debugging in which we interpret the layout dynamically based on the Modula-3 type.
>> We can even rely on Modula-3 run-time support to interpret the UIDs.
>> I don't particularly understand the SPARC64_SOLARIS issue.  Can you elaborate?
>> On 31 Aug 2010, at 22:00, Jay K wrote:
>>    >  I strongly advise against that hack.
>>         It's not my favorite, but I'm possibly in
>>    a jam here between providing type information
>>    for debugging with stock gdb, and I suspect an
>>    overall poor story regarding type information
>>    and backend/frontend interface.
>>              One option is to give up on type information.
>>    i.e. go back to the historical way i.e. before August 2010.
>>    That worked ok as far as most people observed (except for stock gdb..)
>>    However that isn't quite adequate. It doesn't work for SPARC64_SOLARIS.
>>         I suspect we never historically passed records in registers, and
>>    that we must continue not to.
>>      Because of how fields are referenced. Unless maybe gcc "homes" the
>>    records as needed, if
>>      it notices their address taken.
>>         It might suffice, besides giving up on type information, to
>>    mark all records as "addressable". Or, again, to slightly
>>    hack the backend. Maybe only for SPARC64.
>>              The bigger controversial question is if we should change
>>    m3cg (the interface) to know about "field references".
>>         And then, again, should layout be done by the frontend, backend,
>>    or both? There are arguments for all three options.
>>    I think the current *design* is frontend only.
>>    But I think the current *implementation* is both (except for NT386).
>>    And probably the right way is backend only.
>>         This would also generally fix the pesky "load/store use bitfields"
>>    thing.
>>              Debuggability with stock gdb does seem like a nice idea.
>>    But I see now it might conflict tremendously with our odd structuring.
>>              I'll keep poking at it. e.g.: good type information, including for
>>    temporaries,
>>    and mark all record types/values as addressable.
>>              We should still consider the notion of "field references" in the
>>    m3cg interface.
>>     Right? I'm not crazy in the "mismatch" I seem to "detect"?
>>    Probably besides given the field "name", we should pass what the
>>    frontend
>>    thinks is the offset, type, alignment. This will serve two purposes.
>>    For NT386, it will let it continue to be fairly typeless, at least
>>    for now.
>>    For m3cc, it can maybe assert that the layouts agree -- at least for
>>    the fields that are accessed.
>>              I still have to understand how bitfields fit here also.
>>    Though I checked -- it is quite nice afterall that offsets and sizes
>>    are given in bits instead of bytes!
>>          - Jay
>>         >  From: hosking at cs.purdue.edu <mailto:hosking at cs.purdue.edu>
>>    >  Date: Tue, 31 Aug 2010 20:58:07 -0400
>>    >  To: jay.krell at cornell.edu <mailto:jay.krell at cornell.edu>
>>    >  CC: m3devel at elegosoft.com <mailto:m3devel at elegosoft.com>
>>    >  Subject: Re: [M3devel] a trouble with passing records by value..
>>    >     >     >     >  On 31 Aug 2010, at 19:09, Jay K wrote:
>>    >     >  >     >  > I'm possibly going to try changing the target-specific code in
>>    gcc to never pass structs in registers.
>>    >  > Yucky.
>>    >     >  I strongly advise against that hack.
>>    >     >  > I'm also going to try giving temporaries types.
>>    >  > Another m3cg change like pop_struct.
>>    >  > Given the latest internal error I saw.
>>    >  > Maybe review m3cg for more missing type information.
>>    >     >  This would be better...
>>    >     >  >     >  > - Jay
>>    >  >     >  > ----------------------------------------
>>    >  >> From: jay.krell at cornell.edu <mailto:jay.krell at cornell.edu>
>>    >  >> To: hosking at cs.purdue.edu <mailto:hosking at cs.purdue.edu>
>>    >  >> CC: m3devel at elegosoft.com <mailto:m3devel at elegosoft.com>
>>    >  >> Subject: RE: [M3devel] a trouble with passing records by value..
>>    >  >> Date: Tue, 31 Aug 2010 23:05:08 +0000
>>    >  >>     >  >>     >  >> t1 must still be passed in registers. The ABI can't be changed
>>    by that.
>>    >  >>     >  >> - Jay
>>    >  >>     >  >> ----------------------------------------
>>    >  >>> From: hosking at cs.purdue.edu <mailto:hosking at cs.purdue.edu>
>>    >  >>> Date: Tue, 31 Aug 2010 09:15:32 -0400
>>    >  >>> To: jay.krell at cornell.edu <mailto:jay.krell at cornell.edu>
>>    >  >>> CC: m3devel at elegosoft.com <mailto:m3devel at elegosoft.com>
>>    >  >>> Subject: Re: [M3devel] a trouble with passing records by value..
>>    >  >>>     >  >>> What happens if you take the address of t inside ActionLookup?
>>    >  >>> What happens if you take the address of t1 inside main?
>>    >  >>>     >  >>> On 31 Aug 2010, at 07:25, Jay K wrote:
>>    >  >>>     >  >>>>     >  >>>> Given something like this:
>>    >  >>>>     >  >>>> jbook2:p247 jay$ more 1.c
>>    >  >>>> #include
>>    >  >>>>     >  >>>> typedef struct { long code; long value; } T1;
>>    >  >>>>     >  >>>> void ActionLookup(T1 t, long code, long value);
>>    >  >>>>     >  >>>> void ActionLookup(T1 t, long code, long value)
>>    >  >>>> {
>>    >  >>>> assert(t.code == code);
>>    >  >>>> assert(t.value == value);
>>    >  >>>> }
>>    >  >>>>     >  >>>> int main()
>>    >  >>>> {
>>    >  >>>> T1 t1 = {2,2};
>>    >  >>>> ActionLookup(t1, 2, 2);
>>    >  >>>> return 0;
>>    >  >>>> }
>>    >  >>>> j
>>    >  >>>>     >  >>>>     >  >>>> on some platforms, such as AMD64_DARWIN, T1 is passed in
>>    registers. Good.
>>    >  >>>>     >  >>>>     >  >>>> However, one of the unfortunate aspects of our Modula-3
>>    system is that when you reference e.g. t1.value,
>>    >  >>>> the backend isn't told you are accessing the "value" "field"
>>    of "t1", and it figures out where that is,
>>    >  >>>> but rather 64bits at offset 64bits into t1. Therefore t1 must
>>    have an address. Therefore it can't be in registers.
>>    >  >>>> Darn.
>>    >  >>>>     >  >>>>     >  >>>> If m3cg were higher level this could be better.
>>    >  >>>>     >  >>>>     >  >>>> There should be a viable compromise where the parameter is
>>    passed in registers, and only "homed"
>>    >  >>>> to some stack location if its address is used -- e.g. to pass
>>    unused parameters in registers.
>>    >  >>>> But given the inefficiency of field accesses, I'm not sure it
>>    is worth trying?
>>    >  >>>>     >  >>>>     >  >>>> Maybe we should have M3CG include field references?
>>    >  >>>>     >  >>>>     >  >>>> There is this basic problem that the interface between
>>    m3front and m3cc isn't really at the
>>    >  >>>> right level for m3cc. But it is probably for m3front. m3front
>>    wants a lower level code generator.
>>    >  >>>>     >  >>>>     >  >>>> - Jay




More information about the M3devel mailing list