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

Tony Hosking hosking at cs.purdue.edu
Wed Sep 1 15:52:55 CEST 2010


Type ids can always be looked up via the Modula-3 run-time.

On 1 Sep 2010, at 07:50, Jay K wrote:

> 
> 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