[M3devel] a trouble with passing records by value..
Jay K
jay.krell at cornell.edu
Wed Sep 1 13:50:11 CEST 2010
I should point out that the there is still missing type information -- typeids that are
referenced but never defined, and typeids used before they are defined.
- 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: Wed, 1 Sep 2010 11:41:20 +0000
>
>
> Hm. So now I've started asserting that the backend and frontend agree on the sizes of records.
> They don't.
>
> I think we should probably
> - not call layout_type
> - be sure to pass size/align to backend, and have it just set the values, if the rest of the
> backend is ok with that.
>
> e.g. m3cg_declare_field and m3cg_declare_record don't take an alignment.
>
> Though it is easy to compute at this point -- integers/floats/pointers are aligned on their size
> and records are aligned on the highest alignment among their members.
>
> I have to poke around more. I'm going to disable this code again.
>
> - 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: Wed, 1 Sep 2010 09:05:57 +0000
> >
> >
> > oops..sorry..I should have taken the hint from the generated code.. I wasn't defining the type
> > information adequately.. the backend thought all the records were one word/register/integer,
> > and was reasonably well passing that first word/integer in a register.
> >
> >
> > I needed to call layout_type.
> >
> >
> > Testing another fix currently, but it works with both p247 and netobj, previously
> > of which had conflicting requirements -- marking all records as addressable
> > would break netobj, an assertion failure in tree-nested.c, and not fixable
> > I believe with type information on temporaries (though I never tried that..
> > not sure we even ever have any temporary records..)
> >
> > - 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: Wed, 1 Sep 2010 04:26:48 +0000
> > >
> > > > 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
> > >
> >
>
More information about the M3devel
mailing list