<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Tahoma
}
--></style>
</head>
<body class='hmmessage'>
 > I don't particularly understand the SPARC64_SOLARIS issue<BR>
 <BR>
 <BR>
When a record is passed by value SPARC64_SOLARIS backend goes to figure<BR>
out the ABI for it and it hits an assertion failure.<BR>
 <BR>
 <BR>
Historically no type was associated with parameters and locals in the backend.<BR>
At least not for records.<BR>
Maybe they had a size and an alignment.<BR>
But certainly no fields.<BR>
 <BR>
 <BR>
You know -- imagine a record with non-zero size but zero fields. Wierd eh?<BR>
The SPARC64_SOLARIS code in gcc doesn't like that and fails an assertion.<BR>
  (gcc can cope with some such cases the comments say, but still..)<BR>
 <BR>
 <BR>
If you start but don't finish fixing this problem, by giving types to parameters,<BR>
you can then quickly run into problems in AMD64_DARWIN, and probably all AMD64 targets.<BR>
I don't fully understand/remember the problem, but it is easy to uncover.<BR>
 <BR>
 <BR>
Part of the problem was plain missing type information -- I fixed that in m3front.<BR>
If you both imported and defined a type, you wouldn't get the information.<BR>
    m3front was deliberately skipping imported types, even if they coincided with locally defined types.<BR>
If you fix that by defining "everything", you get duplicate opaque error in m3linker. I allow that now,<BR>
if the supertype matches.<BR>
 <BR>
 <BR>
That's still not the extent of the problem on AMD64_DARWIN though.<BR>
 <BR>
 <BR>
Test case p247 covers much of this.<BR>
It just passes a record with a pointer and integer by value.<BR>
Two integers (in record) have same problem.<BR>
 <BR>
 <BR>
To try to summarize:<BR>
   There has been a historical lack of use of type information in the backend. <BR>
   Mostly the backend does get good type information from frontend, but<BR>
    it didn't associate it with locals/parameters. And it is better now. <BR>
   (globals are worse still I believe)<BR>
 <BR>
   <BR>
   I'm not 100% sure, but it appears to me that both the frontend and backend layout records.<BR>
    That is, determine the offset of each field, such as by adding up the sizes of preceding fields.<BR>
     (It is more involved than that, due to alignment.)<BR>
   I am concerned that these two layouts might not agree, and the result would be terrible.<BR>
 <BR>
 <BR>
-  Jay<BR><BR> <BR>

<HR id=stopSpelling>
From: hosking@cs.purdue.edu<BR>Date: Tue, 31 Aug 2010 22:22:16 -0400<BR>To: jay.krell@cornell.edu<BR>CC: m3devel@elegosoft.com<BR>Subject: Re: [M3devel] a trouble with passing records by value..<BR><BR>
<META name=Generator content="Microsoft SafeHTML"><BASE>I believe there is one way out here.
<DIV>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.</DIV>
<DIV>We can even rely on Modula-3 run-time support to interpret the UIDs.</DIV>
<DIV><BR></DIV>
<DIV>I don't particularly understand the SPARC64_SOLARIS issue.  Can you elaborate?</DIV>
<DIV><BR><BR>
<DIV>
<DIV>On 31 Aug 2010, at 22:00, Jay K wrote:</DIV><BR class=ecxApple-interchange-newline>
<BLOCKQUOTE><SPAN style="TEXT-TRANSFORM: none; TEXT-INDENT: 0px; BORDER-COLLAPSE: separate; FONT: medium Helvetica; WHITE-SPACE: normal; LETTER-SPACING: normal; WORD-SPACING: 0px" class=ecxApple-style-span>
<DIV style="FONT-FAMILY: Tahoma; FONT-SIZE: 10pt" class=ecxhmmessage>> I strongly advise against that hack.<BR><BR> <BR>It's not my favorite, but I'm possibly in<BR>a jam here between providing type information<BR>for debugging with stock gdb, and I suspect an<BR>overall poor story regarding type information<BR>and backend/frontend interface.<BR> <BR> <BR>One option is to give up on type information.<BR>i.e. go back to the historical way i.e. before August 2010.<BR>That worked ok as far as most people observed (except for stock gdb..)<BR>However that isn't quite adequate. It doesn't work for SPARC64_SOLARIS.<BR> <BR><BR>I suspect we never historically passed records in registers, and that we must continue not to.<BR>  Because of how fields are referenced. Unless maybe gcc "homes" the records as needed, if<BR>  it notices their address taken.<BR><BR> <BR>It might suffice, besides giving up on type information, to<BR>mark all records as "addressable". Or, again, to slightly<BR>hack the backend. Maybe only for SPARC64.<BR> <BR> <BR>The bigger controversial question is if we should change<BR>m3cg (the interface) to know about "field references".<BR> <BR><BR>And then, again, should layout be done by the frontend, backend,<BR>or both? There are arguments for all three options.<BR>I think the current *design* is frontend only.<BR>But I think the current *implementation* is both (except for NT386).<BR>And probably the right way is backend only.<BR> <BR><BR>This would also generally fix the pesky "load/store use bitfields" thing.<BR> <BR> <BR>Debuggability with stock gdb does seem like a nice idea.<BR>But I see now it might conflict tremendously with our odd structuring.<BR> <BR> <BR>I'll keep poking at it. e.g.: good type information, including for temporaries,<BR>and mark all record types/values as addressable.<BR> <BR> <BR>We should still consider the notion of "field references" in the m3cg interface.<BR> Right? I'm not crazy in the "mismatch" I seem to "detect"?<BR>Probably besides given the field "name", we should pass what the frontend<BR>thinks is the offset, type, alignment. This will serve two purposes.<BR>For NT386, it will let it continue to be fairly typeless, at least for now.<BR>For m3cc, it can maybe assert that the layouts agree -- at least for the fields that are accessed.<BR> <BR> <BR>I still have to understand how bitfields fit here also.<BR>Though I checked -- it is quite nice afterall that offsets and sizes are given in bits instead of bytes!<BR> <BR><BR> - Jay<BR><BR><BR> <BR>> From:<SPAN class=ecxApple-converted-space> </SPAN><A href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</A><BR>> Date: Tue, 31 Aug 2010 20:58:07 -0400<BR>> To:<SPAN class=ecxApple-converted-space> </SPAN><A href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</A><BR>> CC:<SPAN class=ecxApple-converted-space> </SPAN><A href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</A><BR>> Subject: Re: [M3devel] a trouble with passing records by value..<BR>><SPAN class=ecxApple-converted-space> </SPAN><BR>><SPAN class=ecxApple-converted-space> </SPAN><BR>><SPAN class=ecxApple-converted-space> </SPAN><BR>> On 31 Aug 2010, at 19:09, Jay K wrote:<BR>><SPAN class=ecxApple-converted-space> </SPAN><BR>> ><SPAN class=ecxApple-converted-space> </SPAN><BR>> > I'm possibly going to try changing the target-specific code in gcc to never pass structs in registers.<BR>> > Yucky.<BR>><SPAN class=ecxApple-converted-space> </SPAN><BR>> I strongly advise against that hack.<BR>><SPAN class=ecxApple-converted-space> </SPAN><BR>> > I'm also going to try giving temporaries types.<BR>> > Another m3cg change like pop_struct.<BR>> > Given the latest internal error I saw.<BR>> > Maybe review m3cg for more missing type information.<BR>><SPAN class=ecxApple-converted-space> </SPAN><BR>> This would be better...<BR>><SPAN class=ecxApple-converted-space> </SPAN><BR>> ><SPAN class=ecxApple-converted-space> </SPAN><BR>> > - Jay<BR>> ><SPAN class=ecxApple-converted-space> </SPAN><BR>> > ----------------------------------------<BR>> >> From:<SPAN class=ecxApple-converted-space> </SPAN><A href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</A><BR>> >> To:<SPAN class=ecxApple-converted-space> </SPAN><A href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</A><BR>> >> CC:<SPAN class=ecxApple-converted-space> </SPAN><A href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</A><BR>> >> Subject: RE: [M3devel] a trouble with passing records by value..<BR>> >> Date: Tue, 31 Aug 2010 23:05:08 +0000<BR>> >><SPAN class=ecxApple-converted-space> </SPAN><BR>> >><SPAN class=ecxApple-converted-space> </SPAN><BR>> >> t1 must still be passed in registers. The ABI can't be changed by that.<BR>> >><SPAN class=ecxApple-converted-space> </SPAN><BR>> >> - Jay<BR>> >><SPAN class=ecxApple-converted-space> </SPAN><BR>> >> ----------------------------------------<BR>> >>> From:<SPAN class=ecxApple-converted-space> </SPAN><A href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</A><BR>> >>> Date: Tue, 31 Aug 2010 09:15:32 -0400<BR>> >>> To:<SPAN class=ecxApple-converted-space> </SPAN><A href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</A><BR>> >>> CC:<SPAN class=ecxApple-converted-space> </SPAN><A href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</A><BR>> >>> Subject: Re: [M3devel] a trouble with passing records by value..<BR>> >>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>> What happens if you take the address of t inside ActionLookup?<BR>> >>> What happens if you take the address of t1 inside main?<BR>> >>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>> On 31 Aug 2010, at 07:25, Jay K wrote:<BR>> >>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> Given something like this:<BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> jbook2:p247 jay$ more 1.c<BR>> >>>> #include<BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> typedef struct { long code; long value; } T1;<BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> void ActionLookup(T1 t, long code, long value);<BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> void ActionLookup(T1 t, long code, long value)<BR>> >>>> {<BR>> >>>> assert(t.code == code);<BR>> >>>> assert(t.value == value);<BR>> >>>> }<BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> int main()<BR>> >>>> {<BR>> >>>> T1 t1 = {2,2};<BR>> >>>> ActionLookup(t1, 2, 2);<BR>> >>>> return 0;<BR>> >>>> }<BR>> >>>> j<BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> on some platforms, such as AMD64_DARWIN, T1 is passed in registers. Good.<BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> However, one of the unfortunate aspects of our Modula-3 system is that when you reference e.g. t1.value,<BR>> >>>> the backend isn't told you are accessing the "value" "field" of "t1", and it figures out where that is,<BR>> >>>> but rather 64bits at offset 64bits into t1. Therefore t1 must have an address. Therefore it can't be in registers.<BR>> >>>> Darn.<BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> If m3cg were higher level this could be better.<BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> There should be a viable compromise where the parameter is passed in registers, and only "homed"<BR>> >>>> to some stack location if its address is used -- e.g. to pass unused parameters in registers.<BR>> >>>> But given the inefficiency of field accesses, I'm not sure it is worth trying?<BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> Maybe we should have M3CG include field references?<BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> There is this basic problem that the interface between m3front and m3cc isn't really at the<BR>> >>>> right level for m3cc. But it is probably for m3front. m3front wants a lower level code generator.<BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>><SPAN class=ecxApple-converted-space> </SPAN><BR>> >>>> - Jay<BR></DIV></SPAN></BLOCKQUOTE></DIV><BR></DIV>                                      </body>
</html>