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

Tony Hosking hosking at cs.purdue.edu
Wed Sep 1 15:51:42 CEST 2010


Surely we can give the backend enough opaque information about record types (size, alignment, etc.) without revealing their complete structure...  So, layout is still computed by the front-end and the back-end just sees a bag of bits.  Or is that the exact problem you are facing...

On 1 Sep 2010, at 00:26, 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..)
>  
>  
> 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
> > Date: Tue, 31 Aug 2010 20:58:07 -0400
> > To: jay.krell at cornell.edu
> > CC: 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
> > >> To: hosking at cs.purdue.edu
> > >> CC: 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
> > >>> Date: Tue, 31 Aug 2010 09:15:32 -0400
> > >>> To: jay.krell at cornell.edu
> > >>> CC: 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
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20100901/37f96568/attachment-0002.html>


More information about the M3devel mailing list