From jayk123 at hotmail.com Thu Apr 1 00:26:57 2021 From: jayk123 at hotmail.com (Jay K) Date: Wed, 31 Mar 2021 22:26:57 +0000 Subject: [M3devel] g++ -g undermines m3gdb In-Reply-To: <316d6dc5-1cff-d175-26a1-acee7ca566b6@lcwb.coop> References: , <316d6dc5-1cff-d175-26a1-acee7ca566b6@lcwb.coop> Message-ID: > one pager I looked through it but only a little. I don't use debuggers to their fullest, granted. I think much, not all, of this can be achieved by just calling functions from the expression evaluator. cm3 could even generate code, like to print enums, is one area that is bad currently in C backend, but I can fix (C++ sized enums). It'd even be portable to all/most debuggers -- any that can call functions. I realize this has multiple downsides. It makes the code larger. Instead of seeing a list of params/locals all at once, you'd have to ask debugger to print each one "verbosely". So still not a great ui. But It is also more flexible. The code to print TEXT would live with TEXT, not the debugger. But maintaining a fork of gdb seems like quite a high cost on multiple axes (git repo size, time to build, keeping it building, it doesn't work on many targets, etc.) jay at jaykrell-tp3:/s/cm3$ du -hs m3-sys/m3gdb/gdb m3-sys/m3cc/gcc-4.7 doc/help/gen_html 80M m3-sys/m3gdb/gdb 72M m3-sys/m3cc/gcc-4.7 59M doc/help/gen_html 200mb of stuff that doesn't really belong in this repo imho. vs. around 12mb: jay at jaykrell-tp3:/s/cm3$ du -hs m3-sys/m3front/src m3-sys/m3back/src m3-sys/m3quake/src m3-libs/m3core/src m3-libs/libm3/src m3-sys/cm3/src 3.0M m3-sys/m3front/src 780K m3-sys/m3back/src 292K m3-sys/m3quake/src 5.1M m3-libs/m3core/src 2.7M m3-libs/libm3/src 520K m3-sys/cm3/src Seems like a bad economy. It'd be great to use submodules, I guess. I know nobody likes them. They are wierd. But 200mb. ? - Jay ________________________________ From: Rodney M. Bates Sent: Wednesday, March 31, 2021 5:43 PM To: Jay K ; m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb On 3/30/21 11:53 PM, Jay K wrote: > So the problem is "just" m3_ascertain_compiler_kind and if I can make that work, with -g, then ok? > I'll look into that. > I wonder if the problem is not merely -g but -g plus compiling with g++. > Anyway, I will look. I can run Linux/amd64 and m3cc after all. ? > 'cause I am motivated to keep this is at -g, but keep m3cc+m3gdb working. > (I do hope to replace m3cc with m3c, and debugging there is "good", but could use some improvements also.) No, it is not even close. And I need and use the modula-3-specific functions of m3gdb every day. Have you read doc/help/m3gdb/m3gdb-onepage.html? -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Thu Apr 1 00:38:40 2021 From: jayk123 at hotmail.com (Jay K) Date: Wed, 31 Mar 2021 22:38:40 +0000 Subject: [M3devel] g++ -g undermines m3gdb In-Reply-To: <334c250b-21f7-97cd-456d-33148326c30a@lcwb.coop> References: , <334c250b-21f7-97cd-456d-33148326c30a@lcwb.coop> Message-ID: > I have temporarily patch my copy of m3gdb to force the compiler kind > to m3_ck_cm3 if none of the sought symbols is found. Is that so bad? The pm3/ezm3 distributions have any users, that are using m3gdb? Seems unlikely, but not impossible. We can maybe detect another way? Plus, um, maybe putting main back in m3cc instead of C, would probably fix it? I don't like additional variables like that, but maybe. Plus it can probably be better factored, to reduce the C and add more m3cc use, including symbols for m3gdb to see. Strictly speaking, main has to be in C++ to run constructors, but I doubt any modern implementation works that way. But main could just be one line, call m3main, that is maybe even static .m3. I have to look into the "generated main" to know more/better. Anyway I will try to look. - Jay ________________________________ From: Rodney M. Bates Sent: Wednesday, March 31, 2021 5:19 PM To: Jay K ; m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb On 3/30/21 11:53 PM, Jay K wrote: > So the problem is "just" m3_ascertain_compiler_kind and if I can make that work, with -g, then ok? > I'll look into that. Yes, that is all there is to this problem. I have temporarily patch my copy of m3gdb to force the compiler kind to m3_ck_cm3 if none of the sought symbols is found. > I wonder if the problem is not merely -g but -g plus compiling with g++. > Anyway, I will look. I can run Linux/amd64 and m3cc after all. ? > 'cause I am motivated to keep this is at -g, but keep m3cc+m3gdb working. > (I do hope to replace m3cc with m3c, and debugging there is "good", but could use some improvements also.) > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Wednesday, March 31, 2021 4:33 AM > *To:* m3devel ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] g++ -g undermines m3gdb > Rodney I'm mulling over a complete fix here, but > it is a little confusing, you know, because there is compile and link. > > We used to: > > compile: gcc -gstabs -g > link: gcc -gstabs > > Right? > > I changed it to: > compile: gcc -g -g > link: gcc -g > > The -g in compile was ok? > Remains ok? > The problem is just the linking? > > I guess I could experiment with m3gdb. > > It doesn't matter much, in that -gstabs works somewhat for me, and newer gcc fixes it. > But gcc developers wanting to remove it entirely means we should consider using it less or not at all. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Tuesday, March 30, 2021 7:04 PM > *To:* m3devel ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] g++ -g undermines m3gdb > Really trivial C generates incorrect symbols, with the current Debian or Ubuntu gcc. > Nothing to do with the C backend, just the most trivial of things. > Just like: > int main() > { > char foo[100]; > memset(foo, 0, sizeof(foo)); > } > > step through that, unoptimized, and it doesn't show zeros. > The bug is only with stabs which the gcc developers would like to remove/deprecate. > Dwarf works fine. > > The C compile and debugger "handle it", but the debugger shows the wrong information, making me think my C was incorrect. > > See the gcc bug report. > > I know this kinda gross: > - bad modality > - incomplete target coverage > - code duplication > but: > config: -gstabs sometimes produces incorrect symbols by jaykrell ? Pull Request #274 ? modula3/cm3 (github.com) > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Rodney M. Bates > *Sent:* Tuesday, March 30, 2021 7:00 PM > *To:* Jay K ; m3devel ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] g++ -g undermines m3gdb > > > On 3/30/21 1:24 PM, Jay K wrote: >> When I used gcc -gstabs I got incorrect symbols for C. >> I spent a while debugging the C thinking it was incorrect only to later realize the problem was the symbols. >> At least with the current Debian gcc, not with the current mainline gcc. > > What was the problem with the symbols? If it's legal C code, why would a C > compiler not handle it? > > >> Gcc developers would like to remove stabs support, as well. >> That was the response to the bug report (and that it no longer repros). >> 99457 ? gcc/gdb -gstabs+ is buggy. (gnu.org) >> >> If that ever happens, then what? >> >> So I don't know what to do. It is bad either way. >> Since I don't use m3cc or m3gdb, it could be dependent on backend mode?? >> That's a little gross but might keep everyone productive. >> >> - Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* M3devel on behalf of Rodney M. Bates >> *Sent:* Tuesday, March 30, 2021 6:16 PM >> *To:* m3devel >> *Subject:* [M3devel] g++ -g undermines m3gdb >> >> -> linking prog >> generate _m3main.c >> g++ -g -m64 -fPIC -g -c -xc++ _m3main.c -o _m3main.o >> >> This undermines m3gdb. m3gdb looks for certain stabs definitions that >> occur in every main program to ascertain what compiler (especially, pm3 >> vs. cm3) compiled it. With a mixture of dwarf for _m3main.c and stabs >> for everything else, it can't find what it needs. >> >> gcc -g -m64 -fPIC -fuse-ld=gold -Wl,-z,now -Wl,-z,origin -Bsymbolic -Wl,--fatal-warnings -Wl,-rpath,\$ORIGIN -Wl,-rpath,\$ORIGIN/../lib -Wl,--warn-common -Wl,-rpath,/usr/local/cm3/bin/../lib -o prog _m3main.o Main_m.o -L/usr/local/cm3/pkg/libm3/AMD64_LINUX -lm3 -L/usr/local/cm3/pkg/m3core/AMD64_LINUX -lm3core -lm -pthread >> >> >> -- >> Rodney Bates >> rodney.m.bates at acm.org >> _______________________________________________ >> M3devel mailing list >> M3devel at elegosoft.com >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Cf0897b85dad449df6a9608d8f46920b1%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637528079642866198%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=tVOQ%2BfeVmuSmM32SPui3li1Ny7t6T9TNMVXeAitvWmI%3D&reserved=0 >> >> _______________________________________________ >> M3devel mailing list >> M3devel at elegosoft.com >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Cf0897b85dad449df6a9608d8f46920b1%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637528079642866198%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=tVOQ%2BfeVmuSmM32SPui3li1Ny7t6T9TNMVXeAitvWmI%3D&reserved=0 >> > > -- > Rodney Bates > rodney.m.bates at acm.org > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Cf0897b85dad449df6a9608d8f46920b1%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637528079642876195%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=%2BI36PRbtL1jQ2AyFJzb0aRytPPSHlXGXyQuAEhPxqsc%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Thu Apr 1 06:13:00 2021 From: jayk123 at hotmail.com (Jay K) Date: Thu, 1 Apr 2021 04:13:00 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 Message-ID: This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. PROCEDURE ToBinary ( READONLY source : Buffer; exp1, exp2 : CHAR; VAR tmp : Buffer; VAR used : INTEGER; VAR value : LONGREAL): BOOLEAN = VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); BEGIN (* copy source to tmp, fix the exponent character and null terminate *) FOR i := 0 TO nchars -1 DO ch := source [i]; IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; tmp [i] := ch; END; tmp [nchars] := '\000'; (* finally, do the conversion *) value := strtod (ADR (tmp [0]), eptr); line 824 IF eptr = LOOPHOLE (0, ADDRESS) THEN RETURN FALSE; ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; END; END ToBinary; value unfortunately is void* but that can be ok. With all the casts. Just bad for debugging. /*nil pointer_define*/typedef void* T6B01CD09; UINT8 __cdecl Convert__ToBinary( /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) . . . #line 824 "../src/convert/Convert.m3" (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); #line 824 "../src/convert/Convert.m3" /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ #line 824 "../src/convert/Convert.m3" /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ #line 824 "../src/convert/Convert.m3" /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? #line 824 "../src/convert/Convert.m3" /* store_indirect offset:0 ztype:double mtype:double */ #line 824 "../src/convert/Convert.m3" (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); #line 824 "../src/convert/Convert.m3" #line 825 "../src/convert/Convert.m3" Because "address" (which really should be double*) has some implied insufficient alignment? I'll dig a bit more. I think I am close. Thank you, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Thu Apr 1 06:13:52 2021 From: jayk123 at hotmail.com (Jay K) Date: Thu, 1 Apr 2021 04:13:52 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: Message-ID: Hm, so the backend interface doesn't have a notion of pointers to types, does it? Just untyped pointers? So needs a lot of work, I suspect. - Jay ________________________________ From: Jay K Sent: Thursday, April 1, 2021 4:13 AM To: m3devel at elegosoft.com Subject: INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. PROCEDURE ToBinary ( READONLY source : Buffer; exp1, exp2 : CHAR; VAR tmp : Buffer; VAR used : INTEGER; VAR value : LONGREAL): BOOLEAN = VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); BEGIN (* copy source to tmp, fix the exponent character and null terminate *) FOR i := 0 TO nchars -1 DO ch := source [i]; IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; tmp [i] := ch; END; tmp [nchars] := '\000'; (* finally, do the conversion *) value := strtod (ADR (tmp [0]), eptr); line 824 IF eptr = LOOPHOLE (0, ADDRESS) THEN RETURN FALSE; ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; END; END ToBinary; value unfortunately is void* but that can be ok. With all the casts. Just bad for debugging. /*nil pointer_define*/typedef void* T6B01CD09; UINT8 __cdecl Convert__ToBinary( /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) . . . #line 824 "../src/convert/Convert.m3" (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); #line 824 "../src/convert/Convert.m3" /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ #line 824 "../src/convert/Convert.m3" /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ #line 824 "../src/convert/Convert.m3" /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? #line 824 "../src/convert/Convert.m3" /* store_indirect offset:0 ztype:double mtype:double */ #line 824 "../src/convert/Convert.m3" (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); #line 824 "../src/convert/Convert.m3" #line 825 "../src/convert/Convert.m3" Because "address" (which really should be double*) has some implied insufficient alignment? I'll dig a bit more. I think I am close. Thank you, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Thu Apr 1 07:37:36 2021 From: jayk123 at hotmail.com (Jay K) Date: Thu, 1 Apr 2021 05:37:36 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: , Message-ID: What are the three alignments here? ELSIF (t.indirect) THEN CG.Comment(-1, TRUE, "Variable load_indirect:align:" & Fmt.Int(t.align) & " cg_align:" & Fmt.Int(t.cg_align) & " type_info.addr_align:" & Fmt.Int(type_info.addr_align)); CG.Load_addr (t.cg_var, t.offset, t.cg_align); CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ addr_align: Alignment; (* when type=Addr, alignment of VALUE. *) (* NOTE: Originally, field 'align' was highly inconsistent on whether it was the alignment where a value is (or could be) stored, or, when type=Addr, the alignment of where the value pointed. Most calls outside of CG passed in the former, while most uses inside CG expected the latter. This is quite complicated to unravel, so to reduce breakage risk and facilitate fixes thereof, three values are maintained. 'old_align' is as 'align' was. 'base_align' is the former, and 'addr_align' is the latter. It should be possible to eliminate 'old_align' altogether, after ample testing and removal of all uses thereof. *) align became cg_align a few places. Why? What is the difference? Too many things are called align w/o obvious to me why so many. :( commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca Author: Rodney Bates Date: Wed Aug 8 15:10:38 2018 -0500 packedVars branch, initial commit. ... diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 index 77064cde0..301e88ccd 100644 --- a/m3-sys/m3front/src/values/Variable.m3 +++ b/m3-sys/m3front/src/values/Variable.m3 @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = CG.Load_addr_of (t.bss_var, 0, t.cg_align); ELSIF (t.cg_var = NIL) THEN (* => global *) Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); - CG.Boost_alignment (t.align); + CG.Boost_addr_alignment (t.cg_align); ELSIF (t.indirect) THEN - CG.Load_addr (t.cg_var, t.offset); - CG.Boost_alignment (t.align); + CG.Load_addr (t.cg_var, t.offset, t.cg_align); ELSE CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); END; ELSE (* simple scalar *) . . . - CG.Boost_alignment (t.align); - CG.Load_indirect (t.stk_type, 0, t.size); + CG.Boost_addr_alignment (t.cg_align); + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); ELSIF (t.indirect) THEN - CG.Load_addr (t.cg_var, t.offset); - CG.Boost_alignment (t.align); - CG.Load_indirect (t.stk_type, 0, t.size); + CG.Load_addr (t.cg_var, t.offset, t.cg_align); + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); . . . END Load; @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); END; ELSIF (t.indirect) THEN . . . - CG.Boost_alignment (t.align); + CG.Boost_addr_alignment (t.cg_align); END LoadLValue; PROCEDURE SetLValue (t: T) = @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = align := CG.Max_alignment; END; <*ASSERT t.indirect *> - CG.Boost_alignment (align); + CG.Boost_addr_alignment (t.cg_align); CG.Store_addr (v, t.offset); END SetLValue; I think that is the problem. Alignment seems like a big mess in the compiler. Btw I'm wrong I think about the typing. I think the parameter could be an indirect double, if m3front would say so. But that is a separate point. - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Thursday, April 1, 2021 4:13 AM To: m3devel at elegosoft.com Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 Hm, so the backend interface doesn't have a notion of pointers to types, does it? Just untyped pointers? So needs a lot of work, I suspect. - Jay ________________________________ From: Jay K Sent: Thursday, April 1, 2021 4:13 AM To: m3devel at elegosoft.com Subject: INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. PROCEDURE ToBinary ( READONLY source : Buffer; exp1, exp2 : CHAR; VAR tmp : Buffer; VAR used : INTEGER; VAR value : LONGREAL): BOOLEAN = VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); BEGIN (* copy source to tmp, fix the exponent character and null terminate *) FOR i := 0 TO nchars -1 DO ch := source [i]; IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; tmp [i] := ch; END; tmp [nchars] := '\000'; (* finally, do the conversion *) value := strtod (ADR (tmp [0]), eptr); line 824 IF eptr = LOOPHOLE (0, ADDRESS) THEN RETURN FALSE; ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; END; END ToBinary; value unfortunately is void* but that can be ok. With all the casts. Just bad for debugging. /*nil pointer_define*/typedef void* T6B01CD09; UINT8 __cdecl Convert__ToBinary( /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) . . . #line 824 "../src/convert/Convert.m3" (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); #line 824 "../src/convert/Convert.m3" /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ #line 824 "../src/convert/Convert.m3" /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ #line 824 "../src/convert/Convert.m3" /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? #line 824 "../src/convert/Convert.m3" /* store_indirect offset:0 ztype:double mtype:double */ #line 824 "../src/convert/Convert.m3" (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); #line 824 "../src/convert/Convert.m3" #line 825 "../src/convert/Convert.m3" Because "address" (which really should be double*) has some implied insufficient alignment? I'll dig a bit more. I think I am close. Thank you, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Thu Apr 1 07:48:10 2021 From: jayk123 at hotmail.com (Jay K) Date: Thu, 1 Apr 2021 05:48:10 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: , , Message-ID: m3front: Change several t.cg_align back to t.align. by jaykrell ? Pull Request #292 ? modula3/cm3 (github.com) ? - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Thursday, April 1, 2021 5:37 AM To: m3devel at elegosoft.com Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 What are the three alignments here? ELSIF (t.indirect) THEN CG.Comment(-1, TRUE, "Variable load_indirect:align:" & Fmt.Int(t.align) & " cg_align:" & Fmt.Int(t.cg_align) & " type_info.addr_align:" & Fmt.Int(type_info.addr_align)); CG.Load_addr (t.cg_var, t.offset, t.cg_align); CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ addr_align: Alignment; (* when type=Addr, alignment of VALUE. *) (* NOTE: Originally, field 'align' was highly inconsistent on whether it was the alignment where a value is (or could be) stored, or, when type=Addr, the alignment of where the value pointed. Most calls outside of CG passed in the former, while most uses inside CG expected the latter. This is quite complicated to unravel, so to reduce breakage risk and facilitate fixes thereof, three values are maintained. 'old_align' is as 'align' was. 'base_align' is the former, and 'addr_align' is the latter. It should be possible to eliminate 'old_align' altogether, after ample testing and removal of all uses thereof. *) align became cg_align a few places. Why? What is the difference? Too many things are called align w/o obvious to me why so many. :( commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca Author: Rodney Bates Date: Wed Aug 8 15:10:38 2018 -0500 packedVars branch, initial commit. ... diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 index 77064cde0..301e88ccd 100644 --- a/m3-sys/m3front/src/values/Variable.m3 +++ b/m3-sys/m3front/src/values/Variable.m3 @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = CG.Load_addr_of (t.bss_var, 0, t.cg_align); ELSIF (t.cg_var = NIL) THEN (* => global *) Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); - CG.Boost_alignment (t.align); + CG.Boost_addr_alignment (t.cg_align); ELSIF (t.indirect) THEN - CG.Load_addr (t.cg_var, t.offset); - CG.Boost_alignment (t.align); + CG.Load_addr (t.cg_var, t.offset, t.cg_align); ELSE CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); END; ELSE (* simple scalar *) . . . - CG.Boost_alignment (t.align); - CG.Load_indirect (t.stk_type, 0, t.size); + CG.Boost_addr_alignment (t.cg_align); + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); ELSIF (t.indirect) THEN - CG.Load_addr (t.cg_var, t.offset); - CG.Boost_alignment (t.align); - CG.Load_indirect (t.stk_type, 0, t.size); + CG.Load_addr (t.cg_var, t.offset, t.cg_align); + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); . . . END Load; @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); END; ELSIF (t.indirect) THEN . . . - CG.Boost_alignment (t.align); + CG.Boost_addr_alignment (t.cg_align); END LoadLValue; PROCEDURE SetLValue (t: T) = @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = align := CG.Max_alignment; END; <*ASSERT t.indirect *> - CG.Boost_alignment (align); + CG.Boost_addr_alignment (t.cg_align); CG.Store_addr (v, t.offset); END SetLValue; I think that is the problem. Alignment seems like a big mess in the compiler. Btw I'm wrong I think about the typing. I think the parameter could be an indirect double, if m3front would say so. But that is a separate point. - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Thursday, April 1, 2021 4:13 AM To: m3devel at elegosoft.com Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 Hm, so the backend interface doesn't have a notion of pointers to types, does it? Just untyped pointers? So needs a lot of work, I suspect. - Jay ________________________________ From: Jay K Sent: Thursday, April 1, 2021 4:13 AM To: m3devel at elegosoft.com Subject: INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. PROCEDURE ToBinary ( READONLY source : Buffer; exp1, exp2 : CHAR; VAR tmp : Buffer; VAR used : INTEGER; VAR value : LONGREAL): BOOLEAN = VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); BEGIN (* copy source to tmp, fix the exponent character and null terminate *) FOR i := 0 TO nchars -1 DO ch := source [i]; IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; tmp [i] := ch; END; tmp [nchars] := '\000'; (* finally, do the conversion *) value := strtod (ADR (tmp [0]), eptr); line 824 IF eptr = LOOPHOLE (0, ADDRESS) THEN RETURN FALSE; ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; END; END ToBinary; value unfortunately is void* but that can be ok. With all the casts. Just bad for debugging. /*nil pointer_define*/typedef void* T6B01CD09; UINT8 __cdecl Convert__ToBinary( /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) . . . #line 824 "../src/convert/Convert.m3" (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); #line 824 "../src/convert/Convert.m3" /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ #line 824 "../src/convert/Convert.m3" /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ #line 824 "../src/convert/Convert.m3" /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? #line 824 "../src/convert/Convert.m3" /* store_indirect offset:0 ztype:double mtype:double */ #line 824 "../src/convert/Convert.m3" (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); #line 824 "../src/convert/Convert.m3" #line 825 "../src/convert/Convert.m3" Because "address" (which really should be double*) has some implied insufficient alignment? I'll dig a bit more. I think I am close. Thank you, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Thu Apr 1 08:18:42 2021 From: jayk123 at hotmail.com (Jay K) Date: Thu, 1 Apr 2021 06:18:42 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: , , , Message-ID: That helps some, but then: missing version stamps -> compiling M3CG_MultiPass.m3 "..\src\M3CG_MultiPass.m3", line 1237: CM3 restriction: non-byte-aligned value cannot be passed READONLY by reference (2.3.2) (f) "..\src\M3CG_MultiPass.m3", line 1251: CM3 restriction: non-byte-aligned value cannot be passed READONLY by reference (2.3.2) (f) 2 errors encountered Maybe I should leave some of the lines alone..or try to understand what all the alignments are.. - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Thursday, April 1, 2021 5:48 AM To: m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 m3front: Change several t.cg_align back to t.align. by jaykrell ? Pull Request #292 ? modula3/cm3 (github.com) ? - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Thursday, April 1, 2021 5:37 AM To: m3devel at elegosoft.com Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 What are the three alignments here? ELSIF (t.indirect) THEN CG.Comment(-1, TRUE, "Variable load_indirect:align:" & Fmt.Int(t.align) & " cg_align:" & Fmt.Int(t.cg_align) & " type_info.addr_align:" & Fmt.Int(type_info.addr_align)); CG.Load_addr (t.cg_var, t.offset, t.cg_align); CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ addr_align: Alignment; (* when type=Addr, alignment of VALUE. *) (* NOTE: Originally, field 'align' was highly inconsistent on whether it was the alignment where a value is (or could be) stored, or, when type=Addr, the alignment of where the value pointed. Most calls outside of CG passed in the former, while most uses inside CG expected the latter. This is quite complicated to unravel, so to reduce breakage risk and facilitate fixes thereof, three values are maintained. 'old_align' is as 'align' was. 'base_align' is the former, and 'addr_align' is the latter. It should be possible to eliminate 'old_align' altogether, after ample testing and removal of all uses thereof. *) align became cg_align a few places. Why? What is the difference? Too many things are called align w/o obvious to me why so many. :( commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca Author: Rodney Bates Date: Wed Aug 8 15:10:38 2018 -0500 packedVars branch, initial commit. ... diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 index 77064cde0..301e88ccd 100644 --- a/m3-sys/m3front/src/values/Variable.m3 +++ b/m3-sys/m3front/src/values/Variable.m3 @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = CG.Load_addr_of (t.bss_var, 0, t.cg_align); ELSIF (t.cg_var = NIL) THEN (* => global *) Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); - CG.Boost_alignment (t.align); + CG.Boost_addr_alignment (t.cg_align); ELSIF (t.indirect) THEN - CG.Load_addr (t.cg_var, t.offset); - CG.Boost_alignment (t.align); + CG.Load_addr (t.cg_var, t.offset, t.cg_align); ELSE CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); END; ELSE (* simple scalar *) . . . - CG.Boost_alignment (t.align); - CG.Load_indirect (t.stk_type, 0, t.size); + CG.Boost_addr_alignment (t.cg_align); + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); ELSIF (t.indirect) THEN - CG.Load_addr (t.cg_var, t.offset); - CG.Boost_alignment (t.align); - CG.Load_indirect (t.stk_type, 0, t.size); + CG.Load_addr (t.cg_var, t.offset, t.cg_align); + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); . . . END Load; @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); END; ELSIF (t.indirect) THEN . . . - CG.Boost_alignment (t.align); + CG.Boost_addr_alignment (t.cg_align); END LoadLValue; PROCEDURE SetLValue (t: T) = @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = align := CG.Max_alignment; END; <*ASSERT t.indirect *> - CG.Boost_alignment (align); + CG.Boost_addr_alignment (t.cg_align); CG.Store_addr (v, t.offset); END SetLValue; I think that is the problem. Alignment seems like a big mess in the compiler. Btw I'm wrong I think about the typing. I think the parameter could be an indirect double, if m3front would say so. But that is a separate point. - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Thursday, April 1, 2021 4:13 AM To: m3devel at elegosoft.com Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 Hm, so the backend interface doesn't have a notion of pointers to types, does it? Just untyped pointers? So needs a lot of work, I suspect. - Jay ________________________________ From: Jay K Sent: Thursday, April 1, 2021 4:13 AM To: m3devel at elegosoft.com Subject: INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. PROCEDURE ToBinary ( READONLY source : Buffer; exp1, exp2 : CHAR; VAR tmp : Buffer; VAR used : INTEGER; VAR value : LONGREAL): BOOLEAN = VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); BEGIN (* copy source to tmp, fix the exponent character and null terminate *) FOR i := 0 TO nchars -1 DO ch := source [i]; IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; tmp [i] := ch; END; tmp [nchars] := '\000'; (* finally, do the conversion *) value := strtod (ADR (tmp [0]), eptr); line 824 IF eptr = LOOPHOLE (0, ADDRESS) THEN RETURN FALSE; ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; END; END ToBinary; value unfortunately is void* but that can be ok. With all the casts. Just bad for debugging. /*nil pointer_define*/typedef void* T6B01CD09; UINT8 __cdecl Convert__ToBinary( /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) . . . #line 824 "../src/convert/Convert.m3" (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); #line 824 "../src/convert/Convert.m3" /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ #line 824 "../src/convert/Convert.m3" /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ #line 824 "../src/convert/Convert.m3" /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? #line 824 "../src/convert/Convert.m3" /* store_indirect offset:0 ztype:double mtype:double */ #line 824 "../src/convert/Convert.m3" (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); #line 824 "../src/convert/Convert.m3" #line 825 "../src/convert/Convert.m3" Because "address" (which really should be double*) has some implied insufficient alignment? I'll dig a bit more. I think I am close. Thank you, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Thu Apr 1 20:55:58 2021 From: jayk123 at hotmail.com (Jay K) Date: Thu, 1 Apr 2021 18:55:58 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: , , , , Message-ID: Rodney can you help some here? The basic problem is, how to make m3front tolerate a 32bit target with some 64bit aligned types. Where integer/word are 32bit aligned, but others such as int64/word64/double are 64bit aligned. This worked for many years, but no longer does. m3front I think no longer really tolerates anything being more aligned than a target integer. Since all of your alignment work. - Jay ________________________________ From: Jay K Sent: Thursday, April 1, 2021 6:18 AM To: m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 That helps some, but then: missing version stamps -> compiling M3CG_MultiPass.m3 "..\src\M3CG_MultiPass.m3", line 1237: CM3 restriction: non-byte-aligned value cannot be passed READONLY by reference (2.3.2) (f) "..\src\M3CG_MultiPass.m3", line 1251: CM3 restriction: non-byte-aligned value cannot be passed READONLY by reference (2.3.2) (f) 2 errors encountered Maybe I should leave some of the lines alone..or try to understand what all the alignments are.. - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Thursday, April 1, 2021 5:48 AM To: m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 m3front: Change several t.cg_align back to t.align. by jaykrell ? Pull Request #292 ? modula3/cm3 (github.com) ? - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Thursday, April 1, 2021 5:37 AM To: m3devel at elegosoft.com Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 What are the three alignments here? ELSIF (t.indirect) THEN CG.Comment(-1, TRUE, "Variable load_indirect:align:" & Fmt.Int(t.align) & " cg_align:" & Fmt.Int(t.cg_align) & " type_info.addr_align:" & Fmt.Int(type_info.addr_align)); CG.Load_addr (t.cg_var, t.offset, t.cg_align); CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ addr_align: Alignment; (* when type=Addr, alignment of VALUE. *) (* NOTE: Originally, field 'align' was highly inconsistent on whether it was the alignment where a value is (or could be) stored, or, when type=Addr, the alignment of where the value pointed. Most calls outside of CG passed in the former, while most uses inside CG expected the latter. This is quite complicated to unravel, so to reduce breakage risk and facilitate fixes thereof, three values are maintained. 'old_align' is as 'align' was. 'base_align' is the former, and 'addr_align' is the latter. It should be possible to eliminate 'old_align' altogether, after ample testing and removal of all uses thereof. *) align became cg_align a few places. Why? What is the difference? Too many things are called align w/o obvious to me why so many. :( commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca Author: Rodney Bates Date: Wed Aug 8 15:10:38 2018 -0500 packedVars branch, initial commit. ... diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 index 77064cde0..301e88ccd 100644 --- a/m3-sys/m3front/src/values/Variable.m3 +++ b/m3-sys/m3front/src/values/Variable.m3 @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = CG.Load_addr_of (t.bss_var, 0, t.cg_align); ELSIF (t.cg_var = NIL) THEN (* => global *) Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); - CG.Boost_alignment (t.align); + CG.Boost_addr_alignment (t.cg_align); ELSIF (t.indirect) THEN - CG.Load_addr (t.cg_var, t.offset); - CG.Boost_alignment (t.align); + CG.Load_addr (t.cg_var, t.offset, t.cg_align); ELSE CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); END; ELSE (* simple scalar *) . . . - CG.Boost_alignment (t.align); - CG.Load_indirect (t.stk_type, 0, t.size); + CG.Boost_addr_alignment (t.cg_align); + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); ELSIF (t.indirect) THEN - CG.Load_addr (t.cg_var, t.offset); - CG.Boost_alignment (t.align); - CG.Load_indirect (t.stk_type, 0, t.size); + CG.Load_addr (t.cg_var, t.offset, t.cg_align); + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); . . . END Load; @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); END; ELSIF (t.indirect) THEN . . . - CG.Boost_alignment (t.align); + CG.Boost_addr_alignment (t.cg_align); END LoadLValue; PROCEDURE SetLValue (t: T) = @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = align := CG.Max_alignment; END; <*ASSERT t.indirect *> - CG.Boost_alignment (align); + CG.Boost_addr_alignment (t.cg_align); CG.Store_addr (v, t.offset); END SetLValue; I think that is the problem. Alignment seems like a big mess in the compiler. Btw I'm wrong I think about the typing. I think the parameter could be an indirect double, if m3front would say so. But that is a separate point. - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Thursday, April 1, 2021 4:13 AM To: m3devel at elegosoft.com Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 Hm, so the backend interface doesn't have a notion of pointers to types, does it? Just untyped pointers? So needs a lot of work, I suspect. - Jay ________________________________ From: Jay K Sent: Thursday, April 1, 2021 4:13 AM To: m3devel at elegosoft.com Subject: INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. PROCEDURE ToBinary ( READONLY source : Buffer; exp1, exp2 : CHAR; VAR tmp : Buffer; VAR used : INTEGER; VAR value : LONGREAL): BOOLEAN = VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); BEGIN (* copy source to tmp, fix the exponent character and null terminate *) FOR i := 0 TO nchars -1 DO ch := source [i]; IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; tmp [i] := ch; END; tmp [nchars] := '\000'; (* finally, do the conversion *) value := strtod (ADR (tmp [0]), eptr); line 824 IF eptr = LOOPHOLE (0, ADDRESS) THEN RETURN FALSE; ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; END; END ToBinary; value unfortunately is void* but that can be ok. With all the casts. Just bad for debugging. /*nil pointer_define*/typedef void* T6B01CD09; UINT8 __cdecl Convert__ToBinary( /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) . . . #line 824 "../src/convert/Convert.m3" (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); #line 824 "../src/convert/Convert.m3" /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ #line 824 "../src/convert/Convert.m3" /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ #line 824 "../src/convert/Convert.m3" /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? #line 824 "../src/convert/Convert.m3" /* store_indirect offset:0 ztype:double mtype:double */ #line 824 "../src/convert/Convert.m3" (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); #line 824 "../src/convert/Convert.m3" #line 825 "../src/convert/Convert.m3" Because "address" (which really should be double*) has some implied insufficient alignment? I'll dig a bit more. I think I am close. Thank you, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Thu Apr 1 23:45:33 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Thu, 1 Apr 2021 16:45:33 -0500 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: Message-ID: The compiler can't provide larger alignment than is first provided by some other things. The heap allocator must give every heap object the maximum alignment of anything. 64-bit alignment on 32 could be pretty wasteful, depending on what the application is allocating. The heap allocator also would need the same from wherever it gets its heap space. The initial stack setup would have to do the same. Same for all the sections of object modules and executables, thus the linker and loader. The untraced heap is just implemented by using malloc and friends, so it would have to do it too. Then there's the business of aligning the stack on every call. For target machines that do runtime stack operands, this would have to be done in the back end. The front end could maybe do it at the abstract level of the IR, but whether/how that would match the machine instruction set is target-dependent. The abstract stack model of the IR does not view the operand stack as interspersed with activation records, so would have some record-keeping to do. Unless you can first ensure all target machines, OSs and their tool chains would do these things, it is vain to try to get the compiler to do it. Or do you want this introduce a new target-dependency? Tell us again why you want to do this? Is there a 32-bit hardware machine that puts a 64-bit alignment requirement on any value of any kind? If not, why go to this trouble. On the subject of cg_align, etc., here is a summary. The front end previously had lots of variables named "align" or such that failed to distinguish between the alignment of where a value was stored (call this "value alignment") and, in the case where the value was an address, the alignment of where it pointed, (call this the "address alignment"). There were no hints on any alignment field, which it meant, and I certainly couldn't confidently follow it all, the way it was coded. I attempted to unravel this, with, I believe, at least mostly success. In types/Type.i3.Info, "alignment" was once a mixture, but now is value alignment. New field "addr_align" is address alignment. In CG.m3, these are named "base_align" and "addr_align". I renamed the old "align" to "old_align" and maintained its value unchanged, but replaced all references to one of the others. Then there is also "base_value_align", which, rather confusingly, is the value alignment of where the base points, equals the address alignment of the base's contents. This intermediate alignment is needed to compute other things for some of the address modes of the ValRec. In values/Variable.m3, preexisting field "align" is value alignment and preexisting "cg_align" is address alignment. I believe this may have been the original intent, but there were places it was not complete. But, no matter what M3 source code you feed it, INTERNAL CG ERROR should be prevented by earlier compile errors. Note that the restrictions on packing are now less that before. But some of the preexisting ones were not being detected, making things now appear more restrictive at compile time. P.S. Yes, the low-level type system of the IR, like most, doesn't give a lot of info about the type of the referent of a pointer. However, the referent's address alignments do come through most/all of the operators, (always did, assuming they are correct) alongside the CG type. On 4/1/21 12:37 AM, Jay K wrote: > What are the three alignments here? > > ? ? ? ELSIF (t.indirect) THEN > ? ? ? ? CG.Comment(-1, TRUE, "Variable load_indirect:align:" & > ? ? ? ? ? Fmt.Int(t.align) & > ? ? ? ? ? " cg_align:" & > ? ? ? ? ? Fmt.Int(t.cg_align) & > ? ? ? ? ? " type_info.addr_align:" & > ? ? ? ? ? Fmt.Int(type_info.addr_align)); > ? ? ? ? CG.Load_addr (t.cg_var, t.offset, t.cg_align); > ? ? ? ? CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > > > /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ > > > ? ? addr_align: Alignment; ? ?(* when type=Addr, alignment of VALUE. *) > ? ? (* NOTE: Originally, field 'align' was highly inconsistent on whether it > ? ? ? ? ? ? ?was the alignment where a value is (or could be) stored, or, when > ? ? ? ? ? ? ?type=Addr, the alignment of where the value pointed. ?Most calls > ? ? ? ? ? ? ?outside of CG passed in the former, while most uses inside CG > ? ? ? ? ? ? ?expected the latter. ?This is quite complicated to unravel, so > ? ? ? ? ? ? ?to reduce breakage risk and facilitate fixes thereof, three values > ? ? ? ? ? ? ?are maintained. ?'old_align' is as 'align' was. ?'base_align' is > ? ? ? ? ? ? ?the former, and 'addr_align' is the latter. ?It should be possible > ? ? ? ? ? ? ?to eliminate 'old_align' altogether, after ample testing and > ? ? ? ? ? ? ?removal of all uses thereof. *) > > > align became cg_align a few places. Why? > What is the difference? > Too many things are called align w/o obvious to me why so many. :( > > commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca > Author: Rodney Bates > Date: ? Wed Aug 8 15:10:38 2018 -0500 > > ? ? packedVars branch, initial commit. > ... > > diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 > index 77064cde0..301e88ccd 100644 > --- a/m3-sys/m3front/src/values/Variable.m3 > +++ b/m3-sys/m3front/src/values/Variable.m3 > > @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = > ? ? ? ? ?CG.Load_addr_of (t.bss_var, 0, t.cg_align); > ? ? ? ?ELSIF (t.cg_var = NIL) THEN (* => global *) > ? ? ? ? ?Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); > - ? ? ? ?CG.Boost_alignment (t.align); > + ? ? ? ?CG.Boost_addr_alignment (t.cg_align); > ? ? ? ?ELSIF (t.indirect) THEN > - ? ? ? ?CG.Load_addr (t.cg_var, t.offset); > - ? ? ? ?CG.Boost_alignment (t.align); > + ? ? ? ?CG.Load_addr (t.cg_var, t.offset, t.cg_align); > ? ? ? ?ELSE > ? ? ? ? ?CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); > ? ? ? ?END; > ? ? ?ELSE (* simple scalar *) > . > . > . > - ? ? ? ?CG.Boost_alignment (t.align); > - ? ? ? ?CG.Load_indirect (t.stk_type, 0, t.size); > + ? ? ? ?CG.Boost_addr_alignment (t.cg_align); > + ? ? ? ?CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > ? ? ? ?ELSIF (t.indirect) THEN > - ? ? ? ?CG.Load_addr (t.cg_var, t.offset); > - ? ? ? ?CG.Boost_alignment (t.align); > - ? ? ? ?CG.Load_indirect (t.stk_type, 0, t.size); > + ? ? ? ?CG.Load_addr (t.cg_var, t.offset, t.cg_align); > + ? ? ? ?CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > . > . > . > ? ?END Load; > @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = > ? ? ? ? ?CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); > ? ? ? ?END; > ? ? ?ELSIF (t.indirect) THEN > . > . > . > - ? ?CG.Boost_alignment (t.align); > + ? ?CG.Boost_addr_alignment (t.cg_align); > ? ?END LoadLValue; > ?PROCEDURE SetLValue (t: T) = > @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = > ? ? ? ?align := CG.Max_alignment; > ? ? ?END; > ? ? ?<*ASSERT t.indirect *> > - ? ?CG.Boost_alignment (align); > + ? ?CG.Boost_addr_alignment (t.cg_align); > ? ? ?CG.Store_addr (v, t.offset); > ? ?END SetLValue; > I think that is the problem. > > Alignment seems like a big mess in the compiler. > > Btw I'm wrong I think about the typing. > I think the parameter could be an indirect double, if m3front would say so. > But that is a separate point. > > ?- Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* M3devel on behalf of Jay K > *Sent:* Thursday, April 1, 2021 4:13 AM > *To:* m3devel at elegosoft.com > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > Hm, so the backend interface doesn't have a notion of pointers to types, does it? > Just untyped pointers? > So needs a lot of work, I suspect. > > ?- Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Thursday, April 1, 2021 4:13 AM > *To:* m3devel at elegosoft.com > *Subject:* INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. > > PROCEDURE ToBinary ( > ? ? READONLY source ? ? : Buffer; > ? ? ? ? ? ? ?exp1, exp2 : CHAR; > ? ? ? ? ?VAR tmp ? ? ? ?: Buffer; > ? ? ? ? ?VAR used ? ? ? : INTEGER; > ? ? ? ? ?VAR value ? ? ?: LONGREAL): BOOLEAN = > ? VAR ch: CHAR; ?eptr: ADDRESS; ?nchars: INTEGER := NUMBER (source); > ? BEGIN > ? ? (* copy source to tmp, fix the exponent character and null terminate *) > ? ? FOR i := 0 TO nchars -1 DO > ? ? ? ch := source [i]; > ? ? ? IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; > ? ? ? tmp [i] := ch; > ? ? END; > ? ? tmp [nchars] := '\000'; > > ? ? (* finally, do the conversion *) > ? ? value := strtod (ADR (tmp [0]), eptr); ? ? ? ? ? ? ? ? ?line 824 > ? ? IF eptr = LOOPHOLE (0, ADDRESS) > ? ? ? THEN RETURN FALSE; > ? ? ? ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; > ? ? END; > ? END ToBinary; > > value unfortunately is void* but that can be ok. > With all the casts. Just bad for debugging. > > /*nil pointer_define*/typedef void* T6B01CD09; > > UINT8 > __cdecl > Convert__ToBinary( > ? ?/* Param_Type 1 */ T7632CB42 /* strong_type1 */ ?source_L_245, > ? ?/* Param_Type 1 */ CHAR /* strong_type1 */ ?exp1_L_246, > ? ?/* Param_Type 1 */ CHAR /* strong_type1 */ ?exp2_L_247, > ? ?/* Param_Type 1 */ T7632CB42 /* strong_type1 */ ?tmp_L_248, > ? ?/* Param_Type 1 */ TE6A3D58B /* strong_type1 */ ?used_L_249, > ? ?/* Param_Type 1 */ T6B01CD09 /* strong_type1 */ ?value_L_250) > . > . > . > > #line 824 "../src/convert/Convert.m3" > (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( > ? /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ ?/* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), > ? /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ ?/* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); > #line 824 "../src/convert/Convert.m3" > ?/* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ > #line 824 "../src/convert/Convert.m3" > ?/* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ > #line 824 "../src/convert/Convert.m3" > ?/* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel ?s/a=64/32 */ ?<== Why this? > #line 824 "../src/convert/Convert.m3" > ?/* store_indirect ?offset:0 ztype:double mtype:double */ > #line 824 "../src/convert/Convert.m3" > (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); > #line 824 "../src/convert/Convert.m3" > #line 825 "../src/convert/Convert.m3" > > Because "address" (which really should be double*) has some implied insufficient alignment? > > I'll dig a bit more. I think I am close. > > Thank you, > ?- Jay > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://m3lists.elegosoft.com/mailman/listinfo/m3devel > -- Rodney Bates rodney.m.bates at acm.org From jayk123 at hotmail.com Thu Apr 1 23:47:26 2021 From: jayk123 at hotmail.com (Jay K) Date: Thu, 1 Apr 2021 21:47:26 +0000 Subject: [M3devel] alignment of what pointers point to? Message-ID: I understand the hazards of: char c[8]; *(double*)c; and optimizations like: char c[4]; c[0] = 0; c[1] = 0; c[2] = 0; c[3] = 0; => *(int*)c = 0; but question is, does m3front need to be so concerned with the alignment of what a pointer points to? Or it will really just always be correct? i.e. The first is difficult to construct and the language need not protect you from it? The second is not needed esp. in the frontend. 'cause it seems like a lot of code, confusing, and not correct. Not correct because it does not work with 64-aligned types on 32bit target. Though it used to. But the recent diffs are so large so it is difficult to see what changed and broke. Either I/we need to figure out how to fix it, or remove it. If it isn't really serving a purpose, prefer removal. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Fri Apr 2 00:14:37 2021 From: jayk123 at hotmail.com (Jay K) Date: Thu, 1 Apr 2021 22:14:37 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: , Message-ID: I've said it before. Many 32bit ABIs do align int64 and double to 64bits. Just not Linux/x86. I checked several. Linux/mips32, Linux/ppc32, etc. like everything except x86 and m68k. NT/x86 also 64-aligns the 64bit sized types. cm3 is violating many but not all ABIs. In terms of RECORD/struct interop. The underlying native heaps are aligned. They have to be. I will check on Linux/x86. Win32 heaps are aligned to two pointers. Tons of C code would break otherwise. The globals are also handled trivially. It is true the stack is not always aligned but that is ok. It seems wierd, I agree, but that is how C on Win32/x86 works. There is a vague idea that you tend not to do atomic operations against stack, just heap and globals. When we have C like: struct footype { int a; double d; // or int64 }; Most C compilers, 32bit and 64bit targets, will insert 4 bytes of padding between a and d. All Windows compilers will and many Linux ones will. For many years cm3 did too and it worked. It just recently broke. If that were not the case I could not generate portable C for it. There are gcc and Visual C++ extensions to break the alignment but I'd really rather not use them. On the other hand, if cm3 wants padding then it can say like: struct footype { int a; char padding[4]; double d; // or int64 }; and this does give the same layout on all systems. On the hardware side, perhaps, atomic operations care. We don't know which data will be operated on atomically, but it is not usually stack. So you use the alignment that atomics require. i.e. https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedcompareexchange64 " The variables for this function must be aligned on a 64-bit boundary; otherwise, this function will behave unpredictably on multiprocessor x86 systems and any non-x86 systems. See _aligned_malloc. " The last part "See _aligned_malloc" is bogus. There is no need for that. I'll try to get that fixed. The regular heap is already aligned enough. > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > should be prevented by earlier compile errors. It doesn't. Pointers to double are considered to have 32bit alignment and storing a double through them does this. At least in a few places. I am not sure what is the point of attempting to track the alignment of what a pointer points to. Pointers in C and C++ do not really have this. They either point to a strongly specified type and are assumed to have its alignment, or they are void* or char* and you are on your own, usually either operating a byte at a time, or eventually casting back to the original type, that the pointer was already aligned to, so ok. You are also on your own if you cast a pointer amongst types with different alignment, or at least to a pointer to a type with greater alignment. Granted, I am mixing up IR and source. Perhaps C IR tends to look like this? Is cm3 going out of its way to track something that is already correct? - Jay ________________________________ From: Rodney M. Bates Sent: Thursday, April 1, 2021 9:45 PM To: Jay K ; m3devel at elegosoft.com Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 The compiler can't provide larger alignment than is first provided by some other things. The heap allocator must give every heap object the maximum alignment of anything. 64-bit alignment on 32 could be pretty wasteful, depending on what the application is allocating. The heap allocator also would need the same from wherever it gets its heap space. The initial stack setup would have to do the same. Same for all the sections of object modules and executables, thus the linker and loader. The untraced heap is just implemented by using malloc and friends, so it would have to do it too. Then there's the business of aligning the stack on every call. For target machines that do runtime stack operands, this would have to be done in the back end. The front end could maybe do it at the abstract level of the IR, but whether/how that would match the machine instruction set is target-dependent. The abstract stack model of the IR does not view the operand stack as interspersed with activation records, so would have some record-keeping to do. Unless you can first ensure all target machines, OSs and their tool chains would do these things, it is vain to try to get the compiler to do it. Or do you want this introduce a new target-dependency? Tell us again why you want to do this? Is there a 32-bit hardware machine that puts a 64-bit alignment requirement on any value of any kind? If not, why go to this trouble. On the subject of cg_align, etc., here is a summary. The front end previously had lots of variables named "align" or such that failed to distinguish between the alignment of where a value was stored (call this "value alignment") and, in the case where the value was an address, the alignment of where it pointed, (call this the "address alignment"). There were no hints on any alignment field, which it meant, and I certainly couldn't confidently follow it all, the way it was coded. I attempted to unravel this, with, I believe, at least mostly success. In types/Type.i3.Info, "alignment" was once a mixture, but now is value alignment. New field "addr_align" is address alignment. In CG.m3, these are named "base_align" and "addr_align". I renamed the old "align" to "old_align" and maintained its value unchanged, but replaced all references to one of the others. Then there is also "base_value_align", which, rather confusingly, is the value alignment of where the base points, equals the address alignment of the base's contents. This intermediate alignment is needed to compute other things for some of the address modes of the ValRec. In values/Variable.m3, preexisting field "align" is value alignment and preexisting "cg_align" is address alignment. I believe this may have been the original intent, but there were places it was not complete. But, no matter what M3 source code you feed it, INTERNAL CG ERROR should be prevented by earlier compile errors. Note that the restrictions on packing are now less that before. But some of the preexisting ones were not being detected, making things now appear more restrictive at compile time. P.S. Yes, the low-level type system of the IR, like most, doesn't give a lot of info about the type of the referent of a pointer. However, the referent's address alignments do come through most/all of the operators, (always did, assuming they are correct) alongside the CG type. On 4/1/21 12:37 AM, Jay K wrote: > What are the three alignments here? > > ELSIF (t.indirect) THEN > CG.Comment(-1, TRUE, "Variable load_indirect:align:" & > Fmt.Int(t.align) & > " cg_align:" & > Fmt.Int(t.cg_align) & > " type_info.addr_align:" & > Fmt.Int(type_info.addr_align)); > CG.Load_addr (t.cg_var, t.offset, t.cg_align); > CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > > > /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ > > > addr_align: Alignment; (* when type=Addr, alignment of VALUE. *) > (* NOTE: Originally, field 'align' was highly inconsistent on whether it > was the alignment where a value is (or could be) stored, or, when > type=Addr, the alignment of where the value pointed. Most calls > outside of CG passed in the former, while most uses inside CG > expected the latter. This is quite complicated to unravel, so > to reduce breakage risk and facilitate fixes thereof, three values > are maintained. 'old_align' is as 'align' was. 'base_align' is > the former, and 'addr_align' is the latter. It should be possible > to eliminate 'old_align' altogether, after ample testing and > removal of all uses thereof. *) > > > align became cg_align a few places. Why? > What is the difference? > Too many things are called align w/o obvious to me why so many. :( > > commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca > Author: Rodney Bates > Date: Wed Aug 8 15:10:38 2018 -0500 > > packedVars branch, initial commit. > ... > > diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 > index 77064cde0..301e88ccd 100644 > --- a/m3-sys/m3front/src/values/Variable.m3 > +++ b/m3-sys/m3front/src/values/Variable.m3 > > @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = > CG.Load_addr_of (t.bss_var, 0, t.cg_align); > ELSIF (t.cg_var = NIL) THEN (* => global *) > Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); > - CG.Boost_alignment (t.align); > + CG.Boost_addr_alignment (t.cg_align); > ELSIF (t.indirect) THEN > - CG.Load_addr (t.cg_var, t.offset); > - CG.Boost_alignment (t.align); > + CG.Load_addr (t.cg_var, t.offset, t.cg_align); > ELSE > CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); > END; > ELSE (* simple scalar *) > . > . > . > - CG.Boost_alignment (t.align); > - CG.Load_indirect (t.stk_type, 0, t.size); > + CG.Boost_addr_alignment (t.cg_align); > + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > ELSIF (t.indirect) THEN > - CG.Load_addr (t.cg_var, t.offset); > - CG.Boost_alignment (t.align); > - CG.Load_indirect (t.stk_type, 0, t.size); > + CG.Load_addr (t.cg_var, t.offset, t.cg_align); > + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > . > . > . > END Load; > @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = > CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); > END; > ELSIF (t.indirect) THEN > . > . > . > - CG.Boost_alignment (t.align); > + CG.Boost_addr_alignment (t.cg_align); > END LoadLValue; > PROCEDURE SetLValue (t: T) = > @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = > align := CG.Max_alignment; > END; > <*ASSERT t.indirect *> > - CG.Boost_alignment (align); > + CG.Boost_addr_alignment (t.cg_align); > CG.Store_addr (v, t.offset); > END SetLValue; > I think that is the problem. > > Alignment seems like a big mess in the compiler. > > Btw I'm wrong I think about the typing. > I think the parameter could be an indirect double, if m3front would say so. > But that is a separate point. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* M3devel on behalf of Jay K > *Sent:* Thursday, April 1, 2021 4:13 AM > *To:* m3devel at elegosoft.com > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > Hm, so the backend interface doesn't have a notion of pointers to types, does it? > Just untyped pointers? > So needs a lot of work, I suspect. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Thursday, April 1, 2021 4:13 AM > *To:* m3devel at elegosoft.com > *Subject:* INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. > > PROCEDURE ToBinary ( > READONLY source : Buffer; > exp1, exp2 : CHAR; > VAR tmp : Buffer; > VAR used : INTEGER; > VAR value : LONGREAL): BOOLEAN = > VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); > BEGIN > (* copy source to tmp, fix the exponent character and null terminate *) > FOR i := 0 TO nchars -1 DO > ch := source [i]; > IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; > tmp [i] := ch; > END; > tmp [nchars] := '\000'; > > (* finally, do the conversion *) > value := strtod (ADR (tmp [0]), eptr); line 824 > IF eptr = LOOPHOLE (0, ADDRESS) > THEN RETURN FALSE; > ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; > END; > END ToBinary; > > value unfortunately is void* but that can be ok. > With all the casts. Just bad for debugging. > > /*nil pointer_define*/typedef void* T6B01CD09; > > UINT8 > __cdecl > Convert__ToBinary( > /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, > /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, > /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, > /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, > /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, > /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) > . > . > . > > #line 824 "../src/convert/Convert.m3" > (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( > /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), > /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); > #line 824 "../src/convert/Convert.m3" > /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ > #line 824 "../src/convert/Convert.m3" > /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ > #line 824 "../src/convert/Convert.m3" > /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? > #line 824 "../src/convert/Convert.m3" > /* store_indirect offset:0 ztype:double mtype:double */ > #line 824 "../src/convert/Convert.m3" > (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); > #line 824 "../src/convert/Convert.m3" > #line 825 "../src/convert/Convert.m3" > > Because "address" (which really should be double*) has some implied insufficient alignment? > > I'll dig a bit more. I think I am close. > > Thank you, > - Jay > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Ccf581eafb0a84cb78d4108d8f5578563%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529103547175834%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=%2FelA91M6oRtkKJfpgD%2Fda6XINvE3tAGChqCxXNmD6RY%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Fri Apr 2 00:38:48 2021 From: jayk123 at hotmail.com (Jay K) Date: Thu, 1 Apr 2021 22:38:48 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: , , Message-ID: Some of the ABIs I refer to, not all: x86-32: http://www.sco.com/developers/devspecs/abi386-4.pdf The Intel386 architecture does not require doubleword alignment for doubleprecision values. Nevertheless, for data structure compatibility with other Intel architectures, compilers may provide a method to align double-precision values on doubleword boundaries. mips mipsabi32.pdf (sourceforge.net) double is 8 aligned no mention of int64/longlong. ppc32 http://math-atlas.sourceforge.net/devel/assembly/elfspec_ppc.pdf doubles are 8-aligned " long long (where implemented), and double arguments are considered to have 8-byte size and alignment " sparc32 http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_sparc.pdf double is 8-aligned no mention of 64bit integers sparc32 again http://temlib.org/pub/SparcStation/Standards/V8plus.pdf 2.1.3 C ?long long? Compare with SysV SPARC ABI, Figure 3-1, p.3-2. A C long long is an 8-byte quantity, aligned on an 8-byte boundary. It usually occupies the low-order halves of a register pair: LDD and STD (or two LDs and STs) are usually used to move a long long; not LDX/STX. If you use LDX/STX, you must use a global or out register. More than this I believe are similar. - Jay ________________________________ From: Jay K Sent: Thursday, April 1, 2021 10:14 PM To: m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 I've said it before. Many 32bit ABIs do align int64 and double to 64bits. Just not Linux/x86. I checked several. Linux/mips32, Linux/ppc32, etc. like everything except x86 and m68k. NT/x86 also 64-aligns the 64bit sized types. cm3 is violating many but not all ABIs. In terms of RECORD/struct interop. The underlying native heaps are aligned. They have to be. I will check on Linux/x86. Win32 heaps are aligned to two pointers. Tons of C code would break otherwise. The globals are also handled trivially. It is true the stack is not always aligned but that is ok. It seems wierd, I agree, but that is how C on Win32/x86 works. There is a vague idea that you tend not to do atomic operations against stack, just heap and globals. When we have C like: struct footype { int a; double d; // or int64 }; Most C compilers, 32bit and 64bit targets, will insert 4 bytes of padding between a and d. All Windows compilers will and many Linux ones will. For many years cm3 did too and it worked. It just recently broke. If that were not the case I could not generate portable C for it. There are gcc and Visual C++ extensions to break the alignment but I'd really rather not use them. On the other hand, if cm3 wants padding then it can say like: struct footype { int a; char padding[4]; double d; // or int64 }; and this does give the same layout on all systems. On the hardware side, perhaps, atomic operations care. We don't know which data will be operated on atomically, but it is not usually stack. So you use the alignment that atomics require. i.e. https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedcompareexchange64 " The variables for this function must be aligned on a 64-bit boundary; otherwise, this function will behave unpredictably on multiprocessor x86 systems and any non-x86 systems. See _aligned_malloc. " The last part "See _aligned_malloc" is bogus. There is no need for that. I'll try to get that fixed. The regular heap is already aligned enough. > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > should be prevented by earlier compile errors. It doesn't. Pointers to double are considered to have 32bit alignment and storing a double through them does this. At least in a few places. I am not sure what is the point of attempting to track the alignment of what a pointer points to. Pointers in C and C++ do not really have this. They either point to a strongly specified type and are assumed to have its alignment, or they are void* or char* and you are on your own, usually either operating a byte at a time, or eventually casting back to the original type, that the pointer was already aligned to, so ok. You are also on your own if you cast a pointer amongst types with different alignment, or at least to a pointer to a type with greater alignment. Granted, I am mixing up IR and source. Perhaps C IR tends to look like this? Is cm3 going out of its way to track something that is already correct? - Jay ________________________________ From: Rodney M. Bates Sent: Thursday, April 1, 2021 9:45 PM To: Jay K ; m3devel at elegosoft.com Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 The compiler can't provide larger alignment than is first provided by some other things. The heap allocator must give every heap object the maximum alignment of anything. 64-bit alignment on 32 could be pretty wasteful, depending on what the application is allocating. The heap allocator also would need the same from wherever it gets its heap space. The initial stack setup would have to do the same. Same for all the sections of object modules and executables, thus the linker and loader. The untraced heap is just implemented by using malloc and friends, so it would have to do it too. Then there's the business of aligning the stack on every call. For target machines that do runtime stack operands, this would have to be done in the back end. The front end could maybe do it at the abstract level of the IR, but whether/how that would match the machine instruction set is target-dependent. The abstract stack model of the IR does not view the operand stack as interspersed with activation records, so would have some record-keeping to do. Unless you can first ensure all target machines, OSs and their tool chains would do these things, it is vain to try to get the compiler to do it. Or do you want this introduce a new target-dependency? Tell us again why you want to do this? Is there a 32-bit hardware machine that puts a 64-bit alignment requirement on any value of any kind? If not, why go to this trouble. On the subject of cg_align, etc., here is a summary. The front end previously had lots of variables named "align" or such that failed to distinguish between the alignment of where a value was stored (call this "value alignment") and, in the case where the value was an address, the alignment of where it pointed, (call this the "address alignment"). There were no hints on any alignment field, which it meant, and I certainly couldn't confidently follow it all, the way it was coded. I attempted to unravel this, with, I believe, at least mostly success. In types/Type.i3.Info, "alignment" was once a mixture, but now is value alignment. New field "addr_align" is address alignment. In CG.m3, these are named "base_align" and "addr_align". I renamed the old "align" to "old_align" and maintained its value unchanged, but replaced all references to one of the others. Then there is also "base_value_align", which, rather confusingly, is the value alignment of where the base points, equals the address alignment of the base's contents. This intermediate alignment is needed to compute other things for some of the address modes of the ValRec. In values/Variable.m3, preexisting field "align" is value alignment and preexisting "cg_align" is address alignment. I believe this may have been the original intent, but there were places it was not complete. But, no matter what M3 source code you feed it, INTERNAL CG ERROR should be prevented by earlier compile errors. Note that the restrictions on packing are now less that before. But some of the preexisting ones were not being detected, making things now appear more restrictive at compile time. P.S. Yes, the low-level type system of the IR, like most, doesn't give a lot of info about the type of the referent of a pointer. However, the referent's address alignments do come through most/all of the operators, (always did, assuming they are correct) alongside the CG type. On 4/1/21 12:37 AM, Jay K wrote: > What are the three alignments here? > > ELSIF (t.indirect) THEN > CG.Comment(-1, TRUE, "Variable load_indirect:align:" & > Fmt.Int(t.align) & > " cg_align:" & > Fmt.Int(t.cg_align) & > " type_info.addr_align:" & > Fmt.Int(type_info.addr_align)); > CG.Load_addr (t.cg_var, t.offset, t.cg_align); > CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > > > /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ > > > addr_align: Alignment; (* when type=Addr, alignment of VALUE. *) > (* NOTE: Originally, field 'align' was highly inconsistent on whether it > was the alignment where a value is (or could be) stored, or, when > type=Addr, the alignment of where the value pointed. Most calls > outside of CG passed in the former, while most uses inside CG > expected the latter. This is quite complicated to unravel, so > to reduce breakage risk and facilitate fixes thereof, three values > are maintained. 'old_align' is as 'align' was. 'base_align' is > the former, and 'addr_align' is the latter. It should be possible > to eliminate 'old_align' altogether, after ample testing and > removal of all uses thereof. *) > > > align became cg_align a few places. Why? > What is the difference? > Too many things are called align w/o obvious to me why so many. :( > > commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca > Author: Rodney Bates > Date: Wed Aug 8 15:10:38 2018 -0500 > > packedVars branch, initial commit. > ... > > diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 > index 77064cde0..301e88ccd 100644 > --- a/m3-sys/m3front/src/values/Variable.m3 > +++ b/m3-sys/m3front/src/values/Variable.m3 > > @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = > CG.Load_addr_of (t.bss_var, 0, t.cg_align); > ELSIF (t.cg_var = NIL) THEN (* => global *) > Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); > - CG.Boost_alignment (t.align); > + CG.Boost_addr_alignment (t.cg_align); > ELSIF (t.indirect) THEN > - CG.Load_addr (t.cg_var, t.offset); > - CG.Boost_alignment (t.align); > + CG.Load_addr (t.cg_var, t.offset, t.cg_align); > ELSE > CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); > END; > ELSE (* simple scalar *) > . > . > . > - CG.Boost_alignment (t.align); > - CG.Load_indirect (t.stk_type, 0, t.size); > + CG.Boost_addr_alignment (t.cg_align); > + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > ELSIF (t.indirect) THEN > - CG.Load_addr (t.cg_var, t.offset); > - CG.Boost_alignment (t.align); > - CG.Load_indirect (t.stk_type, 0, t.size); > + CG.Load_addr (t.cg_var, t.offset, t.cg_align); > + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > . > . > . > END Load; > @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = > CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); > END; > ELSIF (t.indirect) THEN > . > . > . > - CG.Boost_alignment (t.align); > + CG.Boost_addr_alignment (t.cg_align); > END LoadLValue; > PROCEDURE SetLValue (t: T) = > @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = > align := CG.Max_alignment; > END; > <*ASSERT t.indirect *> > - CG.Boost_alignment (align); > + CG.Boost_addr_alignment (t.cg_align); > CG.Store_addr (v, t.offset); > END SetLValue; > I think that is the problem. > > Alignment seems like a big mess in the compiler. > > Btw I'm wrong I think about the typing. > I think the parameter could be an indirect double, if m3front would say so. > But that is a separate point. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* M3devel on behalf of Jay K > *Sent:* Thursday, April 1, 2021 4:13 AM > *To:* m3devel at elegosoft.com > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > Hm, so the backend interface doesn't have a notion of pointers to types, does it? > Just untyped pointers? > So needs a lot of work, I suspect. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Thursday, April 1, 2021 4:13 AM > *To:* m3devel at elegosoft.com > *Subject:* INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. > > PROCEDURE ToBinary ( > READONLY source : Buffer; > exp1, exp2 : CHAR; > VAR tmp : Buffer; > VAR used : INTEGER; > VAR value : LONGREAL): BOOLEAN = > VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); > BEGIN > (* copy source to tmp, fix the exponent character and null terminate *) > FOR i := 0 TO nchars -1 DO > ch := source [i]; > IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; > tmp [i] := ch; > END; > tmp [nchars] := '\000'; > > (* finally, do the conversion *) > value := strtod (ADR (tmp [0]), eptr); line 824 > IF eptr = LOOPHOLE (0, ADDRESS) > THEN RETURN FALSE; > ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; > END; > END ToBinary; > > value unfortunately is void* but that can be ok. > With all the casts. Just bad for debugging. > > /*nil pointer_define*/typedef void* T6B01CD09; > > UINT8 > __cdecl > Convert__ToBinary( > /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, > /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, > /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, > /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, > /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, > /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) > . > . > . > > #line 824 "../src/convert/Convert.m3" > (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( > /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), > /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); > #line 824 "../src/convert/Convert.m3" > /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ > #line 824 "../src/convert/Convert.m3" > /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ > #line 824 "../src/convert/Convert.m3" > /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? > #line 824 "../src/convert/Convert.m3" > /* store_indirect offset:0 ztype:double mtype:double */ > #line 824 "../src/convert/Convert.m3" > (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); > #line 824 "../src/convert/Convert.m3" > #line 825 "../src/convert/Convert.m3" > > Because "address" (which really should be double*) has some implied insufficient alignment? > > I'll dig a bit more. I think I am close. > > Thank you, > - Jay > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Ccf581eafb0a84cb78d4108d8f5578563%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529103547175834%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=%2FelA91M6oRtkKJfpgD%2Fda6XINvE3tAGChqCxXNmD6RY%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Fri Apr 2 00:49:11 2021 From: jayk123 at hotmail.com (Jay K) Date: Thu, 1 Apr 2021 22:49:11 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: , , , Message-ID: > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > should be prevented by earlier compile errors. You should be able to see the errors on any host with: C:\s\cm3\m3-libs\m3core>cm3 -DTARGET=I386_LINUX -DM3_BACKEND_MODE=C -boot -keep -override -DROOT=/s/cm3 replace the last parameter as appropriate. "..\src\float\Common\TextToFloat.m3", line 351: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 "..\src\convert\Convert.m3", line 824: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 It isn't really the C backend, except I changed Target.m3 to keep the old alignments for it. If it doesn't repro there, then also try libm3 and m3middle and m3back (after building m3core), but m3core should suffice, at least to get started. - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Thursday, April 1, 2021 10:38 PM To: m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 Some of the ABIs I refer to, not all: x86-32: http://www.sco.com/developers/devspecs/abi386-4.pdf The Intel386 architecture does not require doubleword alignment for doubleprecision values. Nevertheless, for data structure compatibility with other Intel architectures, compilers may provide a method to align double-precision values on doubleword boundaries. mips mipsabi32.pdf (sourceforge.net) double is 8 aligned no mention of int64/longlong. ppc32 http://math-atlas.sourceforge.net/devel/assembly/elfspec_ppc.pdf doubles are 8-aligned " long long (where implemented), and double arguments are considered to have 8-byte size and alignment " sparc32 http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_sparc.pdf double is 8-aligned no mention of 64bit integers sparc32 again http://temlib.org/pub/SparcStation/Standards/V8plus.pdf 2.1.3 C ?long long? Compare with SysV SPARC ABI, Figure 3-1, p.3-2. A C long long is an 8-byte quantity, aligned on an 8-byte boundary. It usually occupies the low-order halves of a register pair: LDD and STD (or two LDs and STs) are usually used to move a long long; not LDX/STX. If you use LDX/STX, you must use a global or out register. More than this I believe are similar. - Jay ________________________________ From: Jay K Sent: Thursday, April 1, 2021 10:14 PM To: m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 I've said it before. Many 32bit ABIs do align int64 and double to 64bits. Just not Linux/x86. I checked several. Linux/mips32, Linux/ppc32, etc. like everything except x86 and m68k. NT/x86 also 64-aligns the 64bit sized types. cm3 is violating many but not all ABIs. In terms of RECORD/struct interop. The underlying native heaps are aligned. They have to be. I will check on Linux/x86. Win32 heaps are aligned to two pointers. Tons of C code would break otherwise. The globals are also handled trivially. It is true the stack is not always aligned but that is ok. It seems wierd, I agree, but that is how C on Win32/x86 works. There is a vague idea that you tend not to do atomic operations against stack, just heap and globals. When we have C like: struct footype { int a; double d; // or int64 }; Most C compilers, 32bit and 64bit targets, will insert 4 bytes of padding between a and d. All Windows compilers will and many Linux ones will. For many years cm3 did too and it worked. It just recently broke. If that were not the case I could not generate portable C for it. There are gcc and Visual C++ extensions to break the alignment but I'd really rather not use them. On the other hand, if cm3 wants padding then it can say like: struct footype { int a; char padding[4]; double d; // or int64 }; and this does give the same layout on all systems. On the hardware side, perhaps, atomic operations care. We don't know which data will be operated on atomically, but it is not usually stack. So you use the alignment that atomics require. i.e. https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedcompareexchange64 " The variables for this function must be aligned on a 64-bit boundary; otherwise, this function will behave unpredictably on multiprocessor x86 systems and any non-x86 systems. See _aligned_malloc. " The last part "See _aligned_malloc" is bogus. There is no need for that. I'll try to get that fixed. The regular heap is already aligned enough. > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > should be prevented by earlier compile errors. It doesn't. Pointers to double are considered to have 32bit alignment and storing a double through them does this. At least in a few places. I am not sure what is the point of attempting to track the alignment of what a pointer points to. Pointers in C and C++ do not really have this. They either point to a strongly specified type and are assumed to have its alignment, or they are void* or char* and you are on your own, usually either operating a byte at a time, or eventually casting back to the original type, that the pointer was already aligned to, so ok. You are also on your own if you cast a pointer amongst types with different alignment, or at least to a pointer to a type with greater alignment. Granted, I am mixing up IR and source. Perhaps C IR tends to look like this? Is cm3 going out of its way to track something that is already correct? - Jay ________________________________ From: Rodney M. Bates Sent: Thursday, April 1, 2021 9:45 PM To: Jay K ; m3devel at elegosoft.com Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 The compiler can't provide larger alignment than is first provided by some other things. The heap allocator must give every heap object the maximum alignment of anything. 64-bit alignment on 32 could be pretty wasteful, depending on what the application is allocating. The heap allocator also would need the same from wherever it gets its heap space. The initial stack setup would have to do the same. Same for all the sections of object modules and executables, thus the linker and loader. The untraced heap is just implemented by using malloc and friends, so it would have to do it too. Then there's the business of aligning the stack on every call. For target machines that do runtime stack operands, this would have to be done in the back end. The front end could maybe do it at the abstract level of the IR, but whether/how that would match the machine instruction set is target-dependent. The abstract stack model of the IR does not view the operand stack as interspersed with activation records, so would have some record-keeping to do. Unless you can first ensure all target machines, OSs and their tool chains would do these things, it is vain to try to get the compiler to do it. Or do you want this introduce a new target-dependency? Tell us again why you want to do this? Is there a 32-bit hardware machine that puts a 64-bit alignment requirement on any value of any kind? If not, why go to this trouble. On the subject of cg_align, etc., here is a summary. The front end previously had lots of variables named "align" or such that failed to distinguish between the alignment of where a value was stored (call this "value alignment") and, in the case where the value was an address, the alignment of where it pointed, (call this the "address alignment"). There were no hints on any alignment field, which it meant, and I certainly couldn't confidently follow it all, the way it was coded. I attempted to unravel this, with, I believe, at least mostly success. In types/Type.i3.Info, "alignment" was once a mixture, but now is value alignment. New field "addr_align" is address alignment. In CG.m3, these are named "base_align" and "addr_align". I renamed the old "align" to "old_align" and maintained its value unchanged, but replaced all references to one of the others. Then there is also "base_value_align", which, rather confusingly, is the value alignment of where the base points, equals the address alignment of the base's contents. This intermediate alignment is needed to compute other things for some of the address modes of the ValRec. In values/Variable.m3, preexisting field "align" is value alignment and preexisting "cg_align" is address alignment. I believe this may have been the original intent, but there were places it was not complete. But, no matter what M3 source code you feed it, INTERNAL CG ERROR should be prevented by earlier compile errors. Note that the restrictions on packing are now less that before. But some of the preexisting ones were not being detected, making things now appear more restrictive at compile time. P.S. Yes, the low-level type system of the IR, like most, doesn't give a lot of info about the type of the referent of a pointer. However, the referent's address alignments do come through most/all of the operators, (always did, assuming they are correct) alongside the CG type. On 4/1/21 12:37 AM, Jay K wrote: > What are the three alignments here? > > ELSIF (t.indirect) THEN > CG.Comment(-1, TRUE, "Variable load_indirect:align:" & > Fmt.Int(t.align) & > " cg_align:" & > Fmt.Int(t.cg_align) & > " type_info.addr_align:" & > Fmt.Int(type_info.addr_align)); > CG.Load_addr (t.cg_var, t.offset, t.cg_align); > CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > > > /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ > > > addr_align: Alignment; (* when type=Addr, alignment of VALUE. *) > (* NOTE: Originally, field 'align' was highly inconsistent on whether it > was the alignment where a value is (or could be) stored, or, when > type=Addr, the alignment of where the value pointed. Most calls > outside of CG passed in the former, while most uses inside CG > expected the latter. This is quite complicated to unravel, so > to reduce breakage risk and facilitate fixes thereof, three values > are maintained. 'old_align' is as 'align' was. 'base_align' is > the former, and 'addr_align' is the latter. It should be possible > to eliminate 'old_align' altogether, after ample testing and > removal of all uses thereof. *) > > > align became cg_align a few places. Why? > What is the difference? > Too many things are called align w/o obvious to me why so many. :( > > commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca > Author: Rodney Bates > Date: Wed Aug 8 15:10:38 2018 -0500 > > packedVars branch, initial commit. > ... > > diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 > index 77064cde0..301e88ccd 100644 > --- a/m3-sys/m3front/src/values/Variable.m3 > +++ b/m3-sys/m3front/src/values/Variable.m3 > > @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = > CG.Load_addr_of (t.bss_var, 0, t.cg_align); > ELSIF (t.cg_var = NIL) THEN (* => global *) > Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); > - CG.Boost_alignment (t.align); > + CG.Boost_addr_alignment (t.cg_align); > ELSIF (t.indirect) THEN > - CG.Load_addr (t.cg_var, t.offset); > - CG.Boost_alignment (t.align); > + CG.Load_addr (t.cg_var, t.offset, t.cg_align); > ELSE > CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); > END; > ELSE (* simple scalar *) > . > . > . > - CG.Boost_alignment (t.align); > - CG.Load_indirect (t.stk_type, 0, t.size); > + CG.Boost_addr_alignment (t.cg_align); > + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > ELSIF (t.indirect) THEN > - CG.Load_addr (t.cg_var, t.offset); > - CG.Boost_alignment (t.align); > - CG.Load_indirect (t.stk_type, 0, t.size); > + CG.Load_addr (t.cg_var, t.offset, t.cg_align); > + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > . > . > . > END Load; > @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = > CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); > END; > ELSIF (t.indirect) THEN > . > . > . > - CG.Boost_alignment (t.align); > + CG.Boost_addr_alignment (t.cg_align); > END LoadLValue; > PROCEDURE SetLValue (t: T) = > @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = > align := CG.Max_alignment; > END; > <*ASSERT t.indirect *> > - CG.Boost_alignment (align); > + CG.Boost_addr_alignment (t.cg_align); > CG.Store_addr (v, t.offset); > END SetLValue; > I think that is the problem. > > Alignment seems like a big mess in the compiler. > > Btw I'm wrong I think about the typing. > I think the parameter could be an indirect double, if m3front would say so. > But that is a separate point. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* M3devel on behalf of Jay K > *Sent:* Thursday, April 1, 2021 4:13 AM > *To:* m3devel at elegosoft.com > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > Hm, so the backend interface doesn't have a notion of pointers to types, does it? > Just untyped pointers? > So needs a lot of work, I suspect. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Thursday, April 1, 2021 4:13 AM > *To:* m3devel at elegosoft.com > *Subject:* INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. > > PROCEDURE ToBinary ( > READONLY source : Buffer; > exp1, exp2 : CHAR; > VAR tmp : Buffer; > VAR used : INTEGER; > VAR value : LONGREAL): BOOLEAN = > VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); > BEGIN > (* copy source to tmp, fix the exponent character and null terminate *) > FOR i := 0 TO nchars -1 DO > ch := source [i]; > IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; > tmp [i] := ch; > END; > tmp [nchars] := '\000'; > > (* finally, do the conversion *) > value := strtod (ADR (tmp [0]), eptr); line 824 > IF eptr = LOOPHOLE (0, ADDRESS) > THEN RETURN FALSE; > ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; > END; > END ToBinary; > > value unfortunately is void* but that can be ok. > With all the casts. Just bad for debugging. > > /*nil pointer_define*/typedef void* T6B01CD09; > > UINT8 > __cdecl > Convert__ToBinary( > /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, > /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, > /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, > /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, > /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, > /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) > . > . > . > > #line 824 "../src/convert/Convert.m3" > (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( > /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), > /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); > #line 824 "../src/convert/Convert.m3" > /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ > #line 824 "../src/convert/Convert.m3" > /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ > #line 824 "../src/convert/Convert.m3" > /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? > #line 824 "../src/convert/Convert.m3" > /* store_indirect offset:0 ztype:double mtype:double */ > #line 824 "../src/convert/Convert.m3" > (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); > #line 824 "../src/convert/Convert.m3" > #line 825 "../src/convert/Convert.m3" > > Because "address" (which really should be double*) has some implied insufficient alignment? > > I'll dig a bit more. I think I am close. > > Thank you, > - Jay > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Ccf581eafb0a84cb78d4108d8f5578563%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529103547175834%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=%2FelA91M6oRtkKJfpgD%2Fda6XINvE3tAGChqCxXNmD6RY%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From peter.mckinna at gmail.com Fri Apr 2 03:19:21 2021 From: peter.mckinna at gmail.com (Peter McKinna) Date: Fri, 2 Apr 2021 12:19:21 +1100 Subject: [M3devel] Maybe change to 'Y' ? Message-ID: new source -> compiling Uconstants.c ../src/unix/Common/Uconstants.c:67: warning: "X" redefined #define X(x) char a##x[x]; ../src/unix/Common/Uconstants.c:38: note: this is the location of the previous definition #define X(x) EXTERN_CONST int Uerror__##x = x; new source -> compiling UstatC.c -------------- next part -------------- An HTML attachment was scrubbed... URL: From peter.mckinna at gmail.com Fri Apr 2 03:30:19 2021 From: peter.mckinna at gmail.com (Peter McKinna) Date: Fri, 2 Apr 2021 12:30:19 +1100 Subject: [M3devel] Alignment warnings Message-ID: Is there a general method of avoiding the loophole alignment warnings in TimeStamp, Swap and PickleStubs? I cant quite work out what is wrong so maybe we just stick a on the appropriate line of code. I'm assuming they work correctly on 64 and 32 bit machines of course. Peter -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Fri Apr 2 03:37:53 2021 From: jayk123 at hotmail.com (Jay K) Date: Fri, 2 Apr 2021 01:37:53 +0000 Subject: [M3devel] Maybe change to 'Y' ? In-Reply-To: References: Message-ID: oops, I will look and fix. That code should be very simple and warning free. It is very tempting to delete most of it -- need to provide Unix.i3 just that we use, or all that has ever been there? - Jay ________________________________ From: M3devel on behalf of Peter McKinna Sent: Friday, April 2, 2021 1:19 AM To: m3devel Subject: [M3devel] Maybe change to 'Y' ? new source -> compiling Uconstants.c ../src/unix/Common/Uconstants.c:67: warning: "X" redefined #define X(x) char a##x[x]; ../src/unix/Common/Uconstants.c:38: note: this is the location of the previous definition #define X(x) EXTERN_CONST int Uerror__##x = x; new source -> compiling UstatC.c -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Fri Apr 2 09:21:18 2021 From: jayk123 at hotmail.com (Jay K) Date: Fri, 2 Apr 2021 07:21:18 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: , , , , Message-ID: For what it is worth, I have gone back a few weeks, and things did work. I386_NT can build and run with the C backend, and the 64bit sized types have 64bit alignment. There was one semi suspicious change of mine, around unaligned accesses, but things worked either way. Which agrees with my recollection that x86 and sparc32 worked years ago, and maybe other 32bit targets (ppc32?) Of course the IR is not super interesting. It did change, the swap stuff on store_indirect for example, but I think the change is all in m3front new enforcements or changed calculations feeding into new or same enforcements. I'll keep digging. I think it comes down to the addresses of things having "address alignment", implied to mean "pointed to", instead of the alignment of the thing pointed to. For example Formal.m3 seems to confuse this. When mode # value, the parameter gets address alignment. But this is not enough to fix it all. This is the very confusion you mentioned and I think it persists. Like, before the code overloaded align and either got it right, though confusing, or enforcements were missing. Now you have tried to clarify it, but either got it wrong or added enforcements. Or maybe I am confused. I do wish I had setup CI long ago to catch this earlier. I hope to get to that soon. - Jay ________________________________ From: Jay K Sent: Thursday, April 1, 2021 10:49 PM To: m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > should be prevented by earlier compile errors. You should be able to see the errors on any host with: C:\s\cm3\m3-libs\m3core>cm3 -DTARGET=I386_LINUX -DM3_BACKEND_MODE=C -boot -keep -override -DROOT=/s/cm3 replace the last parameter as appropriate. "..\src\float\Common\TextToFloat.m3", line 351: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 "..\src\convert\Convert.m3", line 824: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 It isn't really the C backend, except I changed Target.m3 to keep the old alignments for it. If it doesn't repro there, then also try libm3 and m3middle and m3back (after building m3core), but m3core should suffice, at least to get started. - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Thursday, April 1, 2021 10:38 PM To: m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 Some of the ABIs I refer to, not all: x86-32: http://www.sco.com/developers/devspecs/abi386-4.pdf The Intel386 architecture does not require doubleword alignment for doubleprecision values. Nevertheless, for data structure compatibility with other Intel architectures, compilers may provide a method to align double-precision values on doubleword boundaries. mips mipsabi32.pdf (sourceforge.net) double is 8 aligned no mention of int64/longlong. ppc32 http://math-atlas.sourceforge.net/devel/assembly/elfspec_ppc.pdf doubles are 8-aligned " long long (where implemented), and double arguments are considered to have 8-byte size and alignment " sparc32 http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_sparc.pdf double is 8-aligned no mention of 64bit integers sparc32 again http://temlib.org/pub/SparcStation/Standards/V8plus.pdf 2.1.3 C ?long long? Compare with SysV SPARC ABI, Figure 3-1, p.3-2. A C long long is an 8-byte quantity, aligned on an 8-byte boundary. It usually occupies the low-order halves of a register pair: LDD and STD (or two LDs and STs) are usually used to move a long long; not LDX/STX. If you use LDX/STX, you must use a global or out register. More than this I believe are similar. - Jay ________________________________ From: Jay K Sent: Thursday, April 1, 2021 10:14 PM To: m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 I've said it before. Many 32bit ABIs do align int64 and double to 64bits. Just not Linux/x86. I checked several. Linux/mips32, Linux/ppc32, etc. like everything except x86 and m68k. NT/x86 also 64-aligns the 64bit sized types. cm3 is violating many but not all ABIs. In terms of RECORD/struct interop. The underlying native heaps are aligned. They have to be. I will check on Linux/x86. Win32 heaps are aligned to two pointers. Tons of C code would break otherwise. The globals are also handled trivially. It is true the stack is not always aligned but that is ok. It seems wierd, I agree, but that is how C on Win32/x86 works. There is a vague idea that you tend not to do atomic operations against stack, just heap and globals. When we have C like: struct footype { int a; double d; // or int64 }; Most C compilers, 32bit and 64bit targets, will insert 4 bytes of padding between a and d. All Windows compilers will and many Linux ones will. For many years cm3 did too and it worked. It just recently broke. If that were not the case I could not generate portable C for it. There are gcc and Visual C++ extensions to break the alignment but I'd really rather not use them. On the other hand, if cm3 wants padding then it can say like: struct footype { int a; char padding[4]; double d; // or int64 }; and this does give the same layout on all systems. On the hardware side, perhaps, atomic operations care. We don't know which data will be operated on atomically, but it is not usually stack. So you use the alignment that atomics require. i.e. https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedcompareexchange64 " The variables for this function must be aligned on a 64-bit boundary; otherwise, this function will behave unpredictably on multiprocessor x86 systems and any non-x86 systems. See _aligned_malloc. " The last part "See _aligned_malloc" is bogus. There is no need for that. I'll try to get that fixed. The regular heap is already aligned enough. > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > should be prevented by earlier compile errors. It doesn't. Pointers to double are considered to have 32bit alignment and storing a double through them does this. At least in a few places. I am not sure what is the point of attempting to track the alignment of what a pointer points to. Pointers in C and C++ do not really have this. They either point to a strongly specified type and are assumed to have its alignment, or they are void* or char* and you are on your own, usually either operating a byte at a time, or eventually casting back to the original type, that the pointer was already aligned to, so ok. You are also on your own if you cast a pointer amongst types with different alignment, or at least to a pointer to a type with greater alignment. Granted, I am mixing up IR and source. Perhaps C IR tends to look like this? Is cm3 going out of its way to track something that is already correct? - Jay ________________________________ From: Rodney M. Bates Sent: Thursday, April 1, 2021 9:45 PM To: Jay K ; m3devel at elegosoft.com Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 The compiler can't provide larger alignment than is first provided by some other things. The heap allocator must give every heap object the maximum alignment of anything. 64-bit alignment on 32 could be pretty wasteful, depending on what the application is allocating. The heap allocator also would need the same from wherever it gets its heap space. The initial stack setup would have to do the same. Same for all the sections of object modules and executables, thus the linker and loader. The untraced heap is just implemented by using malloc and friends, so it would have to do it too. Then there's the business of aligning the stack on every call. For target machines that do runtime stack operands, this would have to be done in the back end. The front end could maybe do it at the abstract level of the IR, but whether/how that would match the machine instruction set is target-dependent. The abstract stack model of the IR does not view the operand stack as interspersed with activation records, so would have some record-keeping to do. Unless you can first ensure all target machines, OSs and their tool chains would do these things, it is vain to try to get the compiler to do it. Or do you want this introduce a new target-dependency? Tell us again why you want to do this? Is there a 32-bit hardware machine that puts a 64-bit alignment requirement on any value of any kind? If not, why go to this trouble. On the subject of cg_align, etc., here is a summary. The front end previously had lots of variables named "align" or such that failed to distinguish between the alignment of where a value was stored (call this "value alignment") and, in the case where the value was an address, the alignment of where it pointed, (call this the "address alignment"). There were no hints on any alignment field, which it meant, and I certainly couldn't confidently follow it all, the way it was coded. I attempted to unravel this, with, I believe, at least mostly success. In types/Type.i3.Info, "alignment" was once a mixture, but now is value alignment. New field "addr_align" is address alignment. In CG.m3, these are named "base_align" and "addr_align". I renamed the old "align" to "old_align" and maintained its value unchanged, but replaced all references to one of the others. Then there is also "base_value_align", which, rather confusingly, is the value alignment of where the base points, equals the address alignment of the base's contents. This intermediate alignment is needed to compute other things for some of the address modes of the ValRec. In values/Variable.m3, preexisting field "align" is value alignment and preexisting "cg_align" is address alignment. I believe this may have been the original intent, but there were places it was not complete. But, no matter what M3 source code you feed it, INTERNAL CG ERROR should be prevented by earlier compile errors. Note that the restrictions on packing are now less that before. But some of the preexisting ones were not being detected, making things now appear more restrictive at compile time. P.S. Yes, the low-level type system of the IR, like most, doesn't give a lot of info about the type of the referent of a pointer. However, the referent's address alignments do come through most/all of the operators, (always did, assuming they are correct) alongside the CG type. On 4/1/21 12:37 AM, Jay K wrote: > What are the three alignments here? > > ELSIF (t.indirect) THEN > CG.Comment(-1, TRUE, "Variable load_indirect:align:" & > Fmt.Int(t.align) & > " cg_align:" & > Fmt.Int(t.cg_align) & > " type_info.addr_align:" & > Fmt.Int(type_info.addr_align)); > CG.Load_addr (t.cg_var, t.offset, t.cg_align); > CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > > > /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ > > > addr_align: Alignment; (* when type=Addr, alignment of VALUE. *) > (* NOTE: Originally, field 'align' was highly inconsistent on whether it > was the alignment where a value is (or could be) stored, or, when > type=Addr, the alignment of where the value pointed. Most calls > outside of CG passed in the former, while most uses inside CG > expected the latter. This is quite complicated to unravel, so > to reduce breakage risk and facilitate fixes thereof, three values > are maintained. 'old_align' is as 'align' was. 'base_align' is > the former, and 'addr_align' is the latter. It should be possible > to eliminate 'old_align' altogether, after ample testing and > removal of all uses thereof. *) > > > align became cg_align a few places. Why? > What is the difference? > Too many things are called align w/o obvious to me why so many. :( > > commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca > Author: Rodney Bates > Date: Wed Aug 8 15:10:38 2018 -0500 > > packedVars branch, initial commit. > ... > > diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 > index 77064cde0..301e88ccd 100644 > --- a/m3-sys/m3front/src/values/Variable.m3 > +++ b/m3-sys/m3front/src/values/Variable.m3 > > @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = > CG.Load_addr_of (t.bss_var, 0, t.cg_align); > ELSIF (t.cg_var = NIL) THEN (* => global *) > Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); > - CG.Boost_alignment (t.align); > + CG.Boost_addr_alignment (t.cg_align); > ELSIF (t.indirect) THEN > - CG.Load_addr (t.cg_var, t.offset); > - CG.Boost_alignment (t.align); > + CG.Load_addr (t.cg_var, t.offset, t.cg_align); > ELSE > CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); > END; > ELSE (* simple scalar *) > . > . > . > - CG.Boost_alignment (t.align); > - CG.Load_indirect (t.stk_type, 0, t.size); > + CG.Boost_addr_alignment (t.cg_align); > + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > ELSIF (t.indirect) THEN > - CG.Load_addr (t.cg_var, t.offset); > - CG.Boost_alignment (t.align); > - CG.Load_indirect (t.stk_type, 0, t.size); > + CG.Load_addr (t.cg_var, t.offset, t.cg_align); > + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); > . > . > . > END Load; > @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = > CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); > END; > ELSIF (t.indirect) THEN > . > . > . > - CG.Boost_alignment (t.align); > + CG.Boost_addr_alignment (t.cg_align); > END LoadLValue; > PROCEDURE SetLValue (t: T) = > @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = > align := CG.Max_alignment; > END; > <*ASSERT t.indirect *> > - CG.Boost_alignment (align); > + CG.Boost_addr_alignment (t.cg_align); > CG.Store_addr (v, t.offset); > END SetLValue; > I think that is the problem. > > Alignment seems like a big mess in the compiler. > > Btw I'm wrong I think about the typing. > I think the parameter could be an indirect double, if m3front would say so. > But that is a separate point. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* M3devel on behalf of Jay K > *Sent:* Thursday, April 1, 2021 4:13 AM > *To:* m3devel at elegosoft.com > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > Hm, so the backend interface doesn't have a notion of pointers to types, does it? > Just untyped pointers? > So needs a lot of work, I suspect. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Thursday, April 1, 2021 4:13 AM > *To:* m3devel at elegosoft.com > *Subject:* INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. > > PROCEDURE ToBinary ( > READONLY source : Buffer; > exp1, exp2 : CHAR; > VAR tmp : Buffer; > VAR used : INTEGER; > VAR value : LONGREAL): BOOLEAN = > VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); > BEGIN > (* copy source to tmp, fix the exponent character and null terminate *) > FOR i := 0 TO nchars -1 DO > ch := source [i]; > IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; > tmp [i] := ch; > END; > tmp [nchars] := '\000'; > > (* finally, do the conversion *) > value := strtod (ADR (tmp [0]), eptr); line 824 > IF eptr = LOOPHOLE (0, ADDRESS) > THEN RETURN FALSE; > ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; > END; > END ToBinary; > > value unfortunately is void* but that can be ok. > With all the casts. Just bad for debugging. > > /*nil pointer_define*/typedef void* T6B01CD09; > > UINT8 > __cdecl > Convert__ToBinary( > /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, > /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, > /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, > /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, > /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, > /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) > . > . > . > > #line 824 "../src/convert/Convert.m3" > (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( > /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), > /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); > #line 824 "../src/convert/Convert.m3" > /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ > #line 824 "../src/convert/Convert.m3" > /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ > #line 824 "../src/convert/Convert.m3" > /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? > #line 824 "../src/convert/Convert.m3" > /* store_indirect offset:0 ztype:double mtype:double */ > #line 824 "../src/convert/Convert.m3" > (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); > #line 824 "../src/convert/Convert.m3" > #line 825 "../src/convert/Convert.m3" > > Because "address" (which really should be double*) has some implied insufficient alignment? > > I'll dig a bit more. I think I am close. > > Thank you, > - Jay > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Ccf581eafb0a84cb78d4108d8f5578563%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529103547175834%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=%2FelA91M6oRtkKJfpgD%2Fda6XINvE3tAGChqCxXNmD6RY%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Fri Apr 2 21:58:50 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 2 Apr 2021 14:58:50 -0500 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: Message-ID: So, you just want the front end to assume that the existence of something in Target.i3 with 64-bit alignment means those things we discussed will arrive 64-bit aligned and go with that? On 4/2/21 2:21 AM, Jay K wrote: > For what it is worth, I have gone back a few weeks, and things did work. > > I386_NT can build and run with the C backend, and the 64bit sized types have 64bit alignment. > > There was one semi suspicious change of mine, around unaligned accesses, but things worked either way. > > Which agrees with my recollection that x86 and sparc32 worked years ago, and maybe other 32bit targets (ppc32?) > > Of course the IR is not super interesting. > It did change, the swap stuff on store_indirect for > example, but I think the change is all in m3front > new enforcements or changed calculations feeding > into new or same enforcements. > > I'll keep digging. > > I think it comes down to the addresses of things having "address alignment", > implied to mean "pointed to", instead of the alignment of the thing pointed to. > > For example Formal.m3 seems to confuse this. > When mode # value, the parameter gets address alignment. > > But this is not enough to fix it all. > > This is the very confusion you mentioned and I think it persists. > Like, before the code overloaded align and either got it right, though confusing, > or enforcements were missing. Now you have tried to clarify it, but either > got it wrong or added enforcements. Or maybe I am confused. > > I do wish I had setup CI long ago to catch this earlier. > I hope to get to that soon. > > ?- Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Thursday, April 1, 2021 10:49 PM > *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > ?> But, no matter what M3 source code you feed it, INTERNAL CG ERROR > ?> should be prevented by earlier compile errors. > > ?You should be able to see the errors on any host with: > > ? C:\s\cm3\m3-libs\m3core>cm3 -DTARGET=I386_LINUX -DM3_BACKEND_MODE=C -boot -keep -override -DROOT=/s/cm3 > ? replace the last parameter as appropriate. > > ?"..\src\float\Common\TextToFloat.m3", line 351: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel ?s/a=64/32 > ?"..\src\convert\Convert.m3", line 824: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel ?s/a=64/32 > > It isn't really the C backend, except I changed Target.m3 to keep the old alignments for it. > > If it doesn't repro there, then also try libm3 and m3middle and m3back (after building m3core), but m3core should suffice, at least to get started. > > ?- Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* M3devel on behalf of Jay K > *Sent:* Thursday, April 1, 2021 10:38 PM > *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > Some of the ABIs I refer to, not all: > > x86-32: > > http://www.sco.com/developers/devspecs/abi386-4.pdf > The Intel386 architecture does not require doubleword alignment for doubleprecision values. > Nevertheless, for data structure compatibility with other Intel > architectures, compilers may provide a method to align double-precision > values on doubleword boundaries. > > mips > mipsabi32.pdf (sourceforge.net) > double is 8 aligned > no mention of int64/longlong. > > > ppc32 > http://math-atlas.sourceforge.net/devel/assembly/elfspec_ppc.pdf > doubles are 8-aligned > " > long long (where implemented), and double arguments are considered to have 8-byte > size and alignment > " > > sparc32 > http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_sparc.pdf > double is 8-aligned > no mention of 64bit integers > > sparc32 again > http://temlib.org/pub/SparcStation/Standards/V8plus.pdf > 2.1.3 C ?long long? > Compare with SysV SPARC ABI, Figure 3-1, p.3-2. > A C long long is an 8-byte quantity, aligned on an 8-byte boundary. It usually > occupies the low-order halves of a register pair: LDD and STD (or two LDs and > STs) are usually used to move a long long; not LDX/STX. If you use LDX/STX, > you must use a global or out register. > > More than this I believe are similar. > > ?- Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Thursday, April 1, 2021 10:14 PM > *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > I've said it before. > > Many 32bit ABIs do align int64 and double to 64bits. > Just not Linux/x86. I checked several. > Linux/mips32, Linux/ppc32, etc. like everything except x86 and m68k. > NT/x86 also 64-aligns the 64bit sized types. > cm3 is violating many but not all ABIs. > ?In terms of RECORD/struct interop. > > The underlying native heaps are aligned. They have to be. > I will check on Linux/x86. > Win32 heaps are aligned to two pointers. > Tons of C code would break otherwise. > The globals are also handled trivially. > It is true the stack is not always aligned but that is ok. > It seems wierd, I agree, but that is how C on Win32/x86 works. > There is a vague idea that you tend not to do atomic operations against stack, just heap and globals. > > ?When we have C like: > > ?struct footype > ?{ > ? int a; > ? double d; // or int64 > ?}; > > ?Most C compilers, 32bit and 64bit targets, will insert 4 bytes of padding between a and d. > ?All Windows compilers will and many Linux ones will. > > ?For many years cm3 did too and it worked. It just recently broke. > ?If that were not the case I could not generate portable C for it. > ?There are gcc and Visual C++ extensions to break the alignment but I'd really rather not use them. > > ?On the other hand, if cm3 wants padding then it can say like: > > struct footype > { > ?int a; > ?char padding[4]; > ?double d; // or int64 > }; > > and this does give the same layout on all systems. > > On the hardware side, perhaps, atomic operations care. > We don't know which data will be operated on atomically, but it is not usually stack. > So you use the alignment that atomics require. > > i.e. > https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedcompareexchange64 > " > The variables for this function must be aligned on a 64-bit boundary; > otherwise, this function will behave unpredictably on multiprocessor > x86 systems and any non-x86 systems. > > See _aligned_malloc. > " > > The last part "See _aligned_malloc" is bogus. There is no need for that. > I'll try to get that fixed. The regular heap is already aligned enough. > > ?> But, no matter what M3 source code you feed it, INTERNAL CG ERROR > ?> should be prevented by earlier compile errors. > > It doesn't. > Pointers to double are considered to have 32bit alignment and storing a double through them does this. > At least in a few places. > > I am not sure what is the point of attempting to track the alignment of what a pointer points to. > Pointers in C and C++ do not really have this. They either point to a strongly specified type > and are assumed to have its alignment, or they are void* or char* and you are on your own, > usually either operating a byte at a time, or eventually casting back to the original type, > that the pointer was already aligned to, so ok. > You are also on your own if you cast a pointer amongst types with different alignment, or > at least to a pointer to a type with greater alignment. > Granted, I am mixing up IR and source. Perhaps C IR tends to look like this? > > Is cm3 going out of its way to track something that is already correct? > > ?- Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Rodney M. Bates > *Sent:* Thursday, April 1, 2021 9:45 PM > *To:* Jay K ; m3devel at elegosoft.com > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > The compiler can't provide larger alignment than is first provided by > some other things.? The heap allocator must give every heap object the > maximum alignment of anything.? 64-bit alignment on 32 could be pretty > wasteful, depending on what the application is allocating.? The heap > allocator also would need the same from wherever it gets its heap > space.? The initial stack setup would have to do the same.? Same for > all the sections of object modules and executables, thus the linker > and loader.? The untraced heap is just implemented by using malloc and > friends, so it would have to do it too. > > Then there's the business of aligning the stack on every call.? For > target machines that do runtime stack operands, this would have to be > done in the back end.? The front end could maybe do it at the abstract > level of the IR, but whether/how that would match the machine > instruction set is target-dependent.? The abstract stack model of the > IR does not view the operand stack as interspersed with activation > records, so would have some record-keeping to do. > > Unless you can first ensure all target machines, OSs and their tool > chains would do these things, it is vain to try to get the compiler to > do it. Or do you want this introduce a new target-dependency? > > Tell us again why you want to do this?? Is there a 32-bit hardware > machine that puts a 64-bit alignment requirement on any value of any > kind?? If not, why go to this trouble. > > On the subject of cg_align, etc., here is a summary.? The front end > previously had lots of variables named "align" or such that failed to > distinguish between the alignment of where a value was stored (call > this "value alignment") and, in the case where the value was an > address, the alignment of where it pointed, (call this the "address > alignment").? There were no hints on any alignment field, which it > meant, and I certainly couldn't confidently follow it all, the way it > was coded.? I attempted to unravel this, with, I believe, at least > mostly success. > > In types/Type.i3.Info, "alignment" was once a mixture, but now is > value alignment.? New field "addr_align" is address alignment. > > In CG.m3, these are named "base_align" and "addr_align".? I renamed > the old "align" to "old_align" and maintained its value unchanged, but > replaced all references to one of the others.? Then there is also > "base_value_align", which, rather confusingly, is the value alignment > of where the base points, equals the address alignment of the base's > contents.? This intermediate alignment is needed to compute other > things for some of the address modes of the ValRec. > > In values/Variable.m3, preexisting field "align" is value alignment > and preexisting "cg_align" is address alignment. I believe this may > have been the original intent, but there were places it was not > complete. > > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > should be prevented by earlier compile errors.? Note that the > restrictions on packing are now less that before.? But some of the > preexisting ones were not being detected, making things now appear > more restrictive at compile time. > > P.S.? Yes, the low-level type system of the IR, like most, doesn't > give a lot of info about the type of the referent of a pointer. > However, the referent's address alignments do come through most/all of > the operators, (always did, assuming they are correct) alongside the > CG type. > > > On 4/1/21 12:37 AM, Jay K wrote: >> What are the three alignments here? >> >>? ? ? ? ELSIF (t.indirect) THEN >>? ? ? ? ? CG.Comment(-1, TRUE, "Variable load_indirect:align:" & >>? ? ? ? ? ? Fmt.Int(t.align) & >>? ? ? ? ? ? " cg_align:" & >>? ? ? ? ? ? Fmt.Int(t.cg_align) & >>? ? ? ? ? ? " type_info.addr_align:" & >>? ? ? ? ? ? Fmt.Int(type_info.addr_align)); >>? ? ? ? ? CG.Load_addr (t.cg_var, t.offset, t.cg_align); >>? ? ? ? ? CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >> >> >> /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ >> >> >>? ? ? addr_align: Alignment; ? ?(* when type=Addr, alignment of VALUE. *) >>? ? ? (* NOTE: Originally, field 'align' was highly inconsistent on whether it >>? ? ? ? ? ? ? ?was the alignment where a value is (or could be) stored, or, when >>? ? ? ? ? ? ? ?type=Addr, the alignment of where the value pointed. ?Most calls >>? ? ? ? ? ? ? ?outside of CG passed in the former, while most uses inside CG >>? ? ? ? ? ? ? ?expected the latter. ?This is quite complicated to unravel, so >>? ? ? ? ? ? ? ?to reduce breakage risk and facilitate fixes thereof, three values >>? ? ? ? ? ? ? ?are maintained. ?'old_align' is as 'align' was. ?'base_align' is >>? ? ? ? ? ? ? ?the former, and 'addr_align' is the latter. ?It should be possible >>? ? ? ? ? ? ? ?to eliminate 'old_align' altogether, after ample testing and >>? ? ? ? ? ? ? ?removal of all uses thereof. *) >> >> >> align became cg_align a few places. Why? >> What is the difference? >> Too many things are called align w/o obvious to me why so many. :( >> >> commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca >> Author: Rodney Bates >> Date: ? Wed Aug 8 15:10:38 2018 -0500 >> >>? ? ? packedVars branch, initial commit. >> ... >> >> diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 >> index 77064cde0..301e88ccd 100644 >> --- a/m3-sys/m3front/src/values/Variable.m3 >> +++ b/m3-sys/m3front/src/values/Variable.m3 >> >> @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = >>? ? ? ? ? ?CG.Load_addr_of (t.bss_var, 0, t.cg_align); >>? ? ? ? ?ELSIF (t.cg_var = NIL) THEN (* => global *) >>? ? ? ? ? ?Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); >> - ? ? ? ?CG.Boost_alignment (t.align); >> + ? ? ? ?CG.Boost_addr_alignment (t.cg_align); >>? ? ? ? ?ELSIF (t.indirect) THEN >> - ? ? ? ?CG.Load_addr (t.cg_var, t.offset); >> - ? ? ? ?CG.Boost_alignment (t.align); >> + ? ? ? ?CG.Load_addr (t.cg_var, t.offset, t.cg_align); >>? ? ? ? ?ELSE >>? ? ? ? ? ?CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); >>? ? ? ? ?END; >>? ? ? ?ELSE (* simple scalar *) >> . >> . >> . >> - ? ? ? ?CG.Boost_alignment (t.align); >> - ? ? ? ?CG.Load_indirect (t.stk_type, 0, t.size); >> + ? ? ? ?CG.Boost_addr_alignment (t.cg_align); >> + ? ? ? ?CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >>? ? ? ? ?ELSIF (t.indirect) THEN >> - ? ? ? ?CG.Load_addr (t.cg_var, t.offset); >> - ? ? ? ?CG.Boost_alignment (t.align); >> - ? ? ? ?CG.Load_indirect (t.stk_type, 0, t.size); >> + ? ? ? ?CG.Load_addr (t.cg_var, t.offset, t.cg_align); >> + ? ? ? ?CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >> . >> . >> . >>? ? ?END Load; >> @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = >>? ? ? ? ? ?CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); >>? ? ? ? ?END; >>? ? ? ?ELSIF (t.indirect) THEN >> . >> . >> . >> - ? ?CG.Boost_alignment (t.align); >> + ? ?CG.Boost_addr_alignment (t.cg_align); >>? ? ?END LoadLValue; >>? ?PROCEDURE SetLValue (t: T) = >> @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = >>? ? ? ? ?align := CG.Max_alignment; >>? ? ? ?END; >>? ? ? ?<*ASSERT t.indirect *> >> - ? ?CG.Boost_alignment (align); >> + ? ?CG.Boost_addr_alignment (t.cg_align); >>? ? ? ?CG.Store_addr (v, t.offset); >>? ? ?END SetLValue; >> I think that is the problem. >> >> Alignment seems like a big mess in the compiler. >> >> Btw I'm wrong I think about the typing. >> I think the parameter could be an indirect double, if m3front would say so. >> But that is a separate point. >> >>? ?- Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* M3devel on behalf of Jay K >> *Sent:* Thursday, April 1, 2021 4:13 AM >> *To:* m3devel at elegosoft.com >> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> Hm, so the backend interface doesn't have a notion of pointers to types, does it? >> Just untyped pointers? >> So needs a lot of work, I suspect. >> >>? ?- Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* Jay K >> *Sent:* Thursday, April 1, 2021 4:13 AM >> *To:* m3devel at elegosoft.com >> *Subject:* INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. >> >> PROCEDURE ToBinary ( >>? ? ? READONLY source ? ? : Buffer; >>? ? ? ? ? ? ? ?exp1, exp2 : CHAR; >>? ? ? ? ? ?VAR tmp ? ? ? ?: Buffer; >>? ? ? ? ? ?VAR used ? ? ? : INTEGER; >>? ? ? ? ? ?VAR value ? ? ?: LONGREAL): BOOLEAN = >>? ? VAR ch: CHAR; ?eptr: ADDRESS; ?nchars: INTEGER := NUMBER (source); >>? ? BEGIN >>? ? ? (* copy source to tmp, fix the exponent character and null terminate *) >>? ? ? FOR i := 0 TO nchars -1 DO >>? ? ? ? ch := source [i]; >>? ? ? ? IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; >>? ? ? ? tmp [i] := ch; >>? ? ? END; >>? ? ? tmp [nchars] := '\000'; >> >>? ? ? (* finally, do the conversion *) >>? ? ? value := strtod (ADR (tmp [0]), eptr); ? ? ? ? ? ? ? ? ?line 824 >>? ? ? IF eptr = LOOPHOLE (0, ADDRESS) >>? ? ? ? THEN RETURN FALSE; >>? ? ? ? ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; >>? ? ? END; >>? ? END ToBinary; >> >> value unfortunately is void* but that can be ok. >> With all the casts. Just bad for debugging. >> >> /*nil pointer_define*/typedef void* T6B01CD09; >> >> UINT8 >> __cdecl >> Convert__ToBinary( >>? ? ?/* Param_Type 1 */ T7632CB42 /* strong_type1 */ ?source_L_245, >>? ? ?/* Param_Type 1 */ CHAR /* strong_type1 */ ?exp1_L_246, >>? ? ?/* Param_Type 1 */ CHAR /* strong_type1 */ ?exp2_L_247, >>? ? ?/* Param_Type 1 */ T7632CB42 /* strong_type1 */ ?tmp_L_248, >>? ? ?/* Param_Type 1 */ TE6A3D58B /* strong_type1 */ ?used_L_249, >>? ? ?/* Param_Type 1 */ T6B01CD09 /* strong_type1 */ ?value_L_250) >> . >> . >> . >> >> #line 824 "../src/convert/Convert.m3" >> (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( >>? ? /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ ?/* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), >>? ? /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ ?/* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); >> #line 824 "../src/convert/Convert.m3" >>? ?/* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ >> #line 824 "../src/convert/Convert.m3" >>? ?/* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ >> #line 824 "../src/convert/Convert.m3" >>? ?/* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel ?s/a=64/32 */ ?<== Why this? >> #line 824 "../src/convert/Convert.m3" >>? ?/* store_indirect ?offset:0 ztype:double mtype:double */ >> #line 824 "../src/convert/Convert.m3" >> (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); >> #line 824 "../src/convert/Convert.m3" >> #line 825 "../src/convert/Convert.m3" >> >> Because "address" (which really should be double*) has some implied insufficient alignment? >> >> I'll dig a bit more. I think I am close. >> >> Thank you, >>? ?- Jay >> >> _______________________________________________ >> M3devel mailing list >> M3devel at elegosoft.com >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Ccf581eafb0a84cb78d4108d8f5578563%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529103547175834%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=%2FelA91M6oRtkKJfpgD%2Fda6XINvE3tAGChqCxXNmD6RY%3D&reserved=0 >> > > -- > Rodney Bates > rodney.m.bates at acm.org > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://m3lists.elegosoft.com/mailman/listinfo/m3devel > -- Rodney Bates rodney.m.bates at acm.org From jayk123 at hotmail.com Fri Apr 2 22:21:28 2021 From: jayk123 at hotmail.com (Jay K) Date: Fri, 2 Apr 2021 20:21:28 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: , Message-ID: Not exactly. The frontend should align record offsets to the stated alignment. This is the most important thing and is currently broken. If you ask it to do this, you get compilation problems. This is where the known bugs are. Everything else has seemed to be working, but we can/should double check. The runtime traced allocator should alway align to at least 64. Maybe 128 on 64bit target. That is for us to look into and fix if it is broken. "segments" are likely already properly aligned by the backend/linker. But we can for example union them with an int64 and double and possibly int128, in the m3cc backend. I think they already are strongly enough typed that it already works though. From my experience debugging i386_cygwin. We can investigate the malloc behavior across systems. However, notice that gcc has -malign-double for x86. Notice gcc behavior on all the other systems. Therefore malloc can be assumed to be at least 64-aligned, yes. But we can check if you are skeptical. On Windows, heap alignment is in the ABI and adequate. mmap aligns to at least 4k bytes on all modern systems, often 8k or 64k. How do the 64bit targets work today? Where is the code to ensure they get their 64bit alignment? Where is the code to ensure even 32bit alignment? I don't believe Linux/x86 stack has any such guarantee. We just kinda assume it. Except, again, we don't really care. Repeating: The most important factor is for m3front to layout records. Again, malloc takes care of whatever the platform needs. "segments" might need some attention, but this does not change that, really. Stack can be ignored. - Jay ________________________________ From: Rodney M. Bates Sent: Friday, April 2, 2021 7:58 PM To: Jay K ; m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 So, you just want the front end to assume that the existence of something in Target.i3 with 64-bit alignment means those things we discussed will arrive 64-bit aligned and go with that? On 4/2/21 2:21 AM, Jay K wrote: > For what it is worth, I have gone back a few weeks, and things did work. > > I386_NT can build and run with the C backend, and the 64bit sized types have 64bit alignment. > > There was one semi suspicious change of mine, around unaligned accesses, but things worked either way. > > Which agrees with my recollection that x86 and sparc32 worked years ago, and maybe other 32bit targets (ppc32?) > > Of course the IR is not super interesting. > It did change, the swap stuff on store_indirect for > example, but I think the change is all in m3front > new enforcements or changed calculations feeding > into new or same enforcements. > > I'll keep digging. > > I think it comes down to the addresses of things having "address alignment", > implied to mean "pointed to", instead of the alignment of the thing pointed to. > > For example Formal.m3 seems to confuse this. > When mode # value, the parameter gets address alignment. > > But this is not enough to fix it all. > > This is the very confusion you mentioned and I think it persists. > Like, before the code overloaded align and either got it right, though confusing, > or enforcements were missing. Now you have tried to clarify it, but either > got it wrong or added enforcements. Or maybe I am confused. > > I do wish I had setup CI long ago to catch this earlier. > I hope to get to that soon. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Thursday, April 1, 2021 10:49 PM > *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > > should be prevented by earlier compile errors. > > You should be able to see the errors on any host with: > > C:\s\cm3\m3-libs\m3core>cm3 -DTARGET=I386_LINUX -DM3_BACKEND_MODE=C -boot -keep -override -DROOT=/s/cm3 > replace the last parameter as appropriate. > > "..\src\float\Common\TextToFloat.m3", line 351: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > "..\src\convert\Convert.m3", line 824: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > > It isn't really the C backend, except I changed Target.m3 to keep the old alignments for it. > > If it doesn't repro there, then also try libm3 and m3middle and m3back (after building m3core), but m3core should suffice, at least to get started. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* M3devel on behalf of Jay K > *Sent:* Thursday, April 1, 2021 10:38 PM > *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > Some of the ABIs I refer to, not all: > > x86-32: > > https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.sco.com%2Fdevelopers%2Fdevspecs%2Fabi386-4.pdf&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517629104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=RNBlSupaJk5FCWcHv27KKkzw8GWtL3PzHjimKEfW5og%3D&reserved=0 > The Intel386 architecture does not require doubleword alignment for doubleprecision values. > Nevertheless, for data structure compatibility with other Intel > architectures, compilers may provide a method to align double-precision > values on doubleword boundaries. > > mips > mipsabi32.pdf (sourceforge.net) > double is 8 aligned > no mention of int64/longlong. > > > ppc32 > https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmath-atlas.sourceforge.net%2Fdevel%2Fassembly%2Felfspec_ppc.pdf&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517629104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=zZk5xwoOl84kiRPova8RcCMlUC%2BYfyeJ1Mi%2FbHOudcs%3D&reserved=0 > doubles are 8-aligned > " > long long (where implemented), and double arguments are considered to have 8-byte > size and alignment > " > > sparc32 > https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmath-atlas.sourceforge.net%2Fdevel%2Fassembly%2Fabi_sysV_sparc.pdf&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517629104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=ZjMmRMEXavsj61v5P%2BVIi0z9jLgJbe4MCxo5T3Jbq1c%3D&reserved=0 > double is 8-aligned > no mention of 64bit integers > > sparc32 again > https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Ftemlib.org%2Fpub%2FSparcStation%2FStandards%2FV8plus.pdf&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517629104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=cWcNdvRqnJ7fJekqgdoPFmK9sHzToBH5L8U%2FGRj0fnk%3D&reserved=0 > 2.1.3 C ?long long? > Compare with SysV SPARC ABI, Figure 3-1, p.3-2. > A C long long is an 8-byte quantity, aligned on an 8-byte boundary. It usually > occupies the low-order halves of a register pair: LDD and STD (or two LDs and > STs) are usually used to move a long long; not LDX/STX. If you use LDX/STX, > you must use a global or out register. > > More than this I believe are similar. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Thursday, April 1, 2021 10:14 PM > *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > I've said it before. > > Many 32bit ABIs do align int64 and double to 64bits. > Just not Linux/x86. I checked several. > Linux/mips32, Linux/ppc32, etc. like everything except x86 and m68k. > NT/x86 also 64-aligns the 64bit sized types. > cm3 is violating many but not all ABIs. > In terms of RECORD/struct interop. > > The underlying native heaps are aligned. They have to be. > I will check on Linux/x86. > Win32 heaps are aligned to two pointers. > Tons of C code would break otherwise. > The globals are also handled trivially. > It is true the stack is not always aligned but that is ok. > It seems wierd, I agree, but that is how C on Win32/x86 works. > There is a vague idea that you tend not to do atomic operations against stack, just heap and globals. > > When we have C like: > > struct footype > { > int a; > double d; // or int64 > }; > > Most C compilers, 32bit and 64bit targets, will insert 4 bytes of padding between a and d. > All Windows compilers will and many Linux ones will. > > For many years cm3 did too and it worked. It just recently broke. > If that were not the case I could not generate portable C for it. > There are gcc and Visual C++ extensions to break the alignment but I'd really rather not use them. > > On the other hand, if cm3 wants padding then it can say like: > > struct footype > { > int a; > char padding[4]; > double d; // or int64 > }; > > and this does give the same layout on all systems. > > On the hardware side, perhaps, atomic operations care. > We don't know which data will be operated on atomically, but it is not usually stack. > So you use the alignment that atomics require. > > i.e. > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fwindows%2Fwin32%2Fapi%2Fwinnt%2Fnf-winnt-interlockedcompareexchange64&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517639100%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=cTL8i7R8HVEQj2sGpEPKkSkCG7hbPfIj828oWY1YkiA%3D&reserved=0 > " > The variables for this function must be aligned on a 64-bit boundary; > otherwise, this function will behave unpredictably on multiprocessor > x86 systems and any non-x86 systems. > > See _aligned_malloc. > " > > The last part "See _aligned_malloc" is bogus. There is no need for that. > I'll try to get that fixed. The regular heap is already aligned enough. > > > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > > should be prevented by earlier compile errors. > > It doesn't. > Pointers to double are considered to have 32bit alignment and storing a double through them does this. > At least in a few places. > > I am not sure what is the point of attempting to track the alignment of what a pointer points to. > Pointers in C and C++ do not really have this. They either point to a strongly specified type > and are assumed to have its alignment, or they are void* or char* and you are on your own, > usually either operating a byte at a time, or eventually casting back to the original type, > that the pointer was already aligned to, so ok. > You are also on your own if you cast a pointer amongst types with different alignment, or > at least to a pointer to a type with greater alignment. > Granted, I am mixing up IR and source. Perhaps C IR tends to look like this? > > Is cm3 going out of its way to track something that is already correct? > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Rodney M. Bates > *Sent:* Thursday, April 1, 2021 9:45 PM > *To:* Jay K ; m3devel at elegosoft.com > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > The compiler can't provide larger alignment than is first provided by > some other things. The heap allocator must give every heap object the > maximum alignment of anything. 64-bit alignment on 32 could be pretty > wasteful, depending on what the application is allocating. The heap > allocator also would need the same from wherever it gets its heap > space. The initial stack setup would have to do the same. Same for > all the sections of object modules and executables, thus the linker > and loader. The untraced heap is just implemented by using malloc and > friends, so it would have to do it too. > > Then there's the business of aligning the stack on every call. For > target machines that do runtime stack operands, this would have to be > done in the back end. The front end could maybe do it at the abstract > level of the IR, but whether/how that would match the machine > instruction set is target-dependent. The abstract stack model of the > IR does not view the operand stack as interspersed with activation > records, so would have some record-keeping to do. > > Unless you can first ensure all target machines, OSs and their tool > chains would do these things, it is vain to try to get the compiler to > do it. Or do you want this introduce a new target-dependency? > > Tell us again why you want to do this? Is there a 32-bit hardware > machine that puts a 64-bit alignment requirement on any value of any > kind? If not, why go to this trouble. > > On the subject of cg_align, etc., here is a summary. The front end > previously had lots of variables named "align" or such that failed to > distinguish between the alignment of where a value was stored (call > this "value alignment") and, in the case where the value was an > address, the alignment of where it pointed, (call this the "address > alignment"). There were no hints on any alignment field, which it > meant, and I certainly couldn't confidently follow it all, the way it > was coded. I attempted to unravel this, with, I believe, at least > mostly success. > > In types/Type.i3.Info, "alignment" was once a mixture, but now is > value alignment. New field "addr_align" is address alignment. > > In CG.m3, these are named "base_align" and "addr_align". I renamed > the old "align" to "old_align" and maintained its value unchanged, but > replaced all references to one of the others. Then there is also > "base_value_align", which, rather confusingly, is the value alignment > of where the base points, equals the address alignment of the base's > contents. This intermediate alignment is needed to compute other > things for some of the address modes of the ValRec. > > In values/Variable.m3, preexisting field "align" is value alignment > and preexisting "cg_align" is address alignment. I believe this may > have been the original intent, but there were places it was not > complete. > > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > should be prevented by earlier compile errors. Note that the > restrictions on packing are now less that before. But some of the > preexisting ones were not being detected, making things now appear > more restrictive at compile time. > > P.S. Yes, the low-level type system of the IR, like most, doesn't > give a lot of info about the type of the referent of a pointer. > However, the referent's address alignments do come through most/all of > the operators, (always did, assuming they are correct) alongside the > CG type. > > > On 4/1/21 12:37 AM, Jay K wrote: >> What are the three alignments here? >> >> ELSIF (t.indirect) THEN >> CG.Comment(-1, TRUE, "Variable load_indirect:align:" & >> Fmt.Int(t.align) & >> " cg_align:" & >> Fmt.Int(t.cg_align) & >> " type_info.addr_align:" & >> Fmt.Int(type_info.addr_align)); >> CG.Load_addr (t.cg_var, t.offset, t.cg_align); >> CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >> >> >> /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ >> >> >> addr_align: Alignment; (* when type=Addr, alignment of VALUE. *) >> (* NOTE: Originally, field 'align' was highly inconsistent on whether it >> was the alignment where a value is (or could be) stored, or, when >> type=Addr, the alignment of where the value pointed. Most calls >> outside of CG passed in the former, while most uses inside CG >> expected the latter. This is quite complicated to unravel, so >> to reduce breakage risk and facilitate fixes thereof, three values >> are maintained. 'old_align' is as 'align' was. 'base_align' is >> the former, and 'addr_align' is the latter. It should be possible >> to eliminate 'old_align' altogether, after ample testing and >> removal of all uses thereof. *) >> >> >> align became cg_align a few places. Why? >> What is the difference? >> Too many things are called align w/o obvious to me why so many. :( >> >> commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca >> Author: Rodney Bates >> Date: Wed Aug 8 15:10:38 2018 -0500 >> >> packedVars branch, initial commit. >> ... >> >> diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 >> index 77064cde0..301e88ccd 100644 >> --- a/m3-sys/m3front/src/values/Variable.m3 >> +++ b/m3-sys/m3front/src/values/Variable.m3 >> >> @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = >> CG.Load_addr_of (t.bss_var, 0, t.cg_align); >> ELSIF (t.cg_var = NIL) THEN (* => global *) >> Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); >> - CG.Boost_alignment (t.align); >> + CG.Boost_addr_alignment (t.cg_align); >> ELSIF (t.indirect) THEN >> - CG.Load_addr (t.cg_var, t.offset); >> - CG.Boost_alignment (t.align); >> + CG.Load_addr (t.cg_var, t.offset, t.cg_align); >> ELSE >> CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); >> END; >> ELSE (* simple scalar *) >> . >> . >> . >> - CG.Boost_alignment (t.align); >> - CG.Load_indirect (t.stk_type, 0, t.size); >> + CG.Boost_addr_alignment (t.cg_align); >> + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >> ELSIF (t.indirect) THEN >> - CG.Load_addr (t.cg_var, t.offset); >> - CG.Boost_alignment (t.align); >> - CG.Load_indirect (t.stk_type, 0, t.size); >> + CG.Load_addr (t.cg_var, t.offset, t.cg_align); >> + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >> . >> . >> . >> END Load; >> @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = >> CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); >> END; >> ELSIF (t.indirect) THEN >> . >> . >> . >> - CG.Boost_alignment (t.align); >> + CG.Boost_addr_alignment (t.cg_align); >> END LoadLValue; >> PROCEDURE SetLValue (t: T) = >> @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = >> align := CG.Max_alignment; >> END; >> <*ASSERT t.indirect *> >> - CG.Boost_alignment (align); >> + CG.Boost_addr_alignment (t.cg_align); >> CG.Store_addr (v, t.offset); >> END SetLValue; >> I think that is the problem. >> >> Alignment seems like a big mess in the compiler. >> >> Btw I'm wrong I think about the typing. >> I think the parameter could be an indirect double, if m3front would say so. >> But that is a separate point. >> >> - Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* M3devel on behalf of Jay K >> *Sent:* Thursday, April 1, 2021 4:13 AM >> *To:* m3devel at elegosoft.com >> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> Hm, so the backend interface doesn't have a notion of pointers to types, does it? >> Just untyped pointers? >> So needs a lot of work, I suspect. >> >> - Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* Jay K >> *Sent:* Thursday, April 1, 2021 4:13 AM >> *To:* m3devel at elegosoft.com >> *Subject:* INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. >> >> PROCEDURE ToBinary ( >> READONLY source : Buffer; >> exp1, exp2 : CHAR; >> VAR tmp : Buffer; >> VAR used : INTEGER; >> VAR value : LONGREAL): BOOLEAN = >> VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); >> BEGIN >> (* copy source to tmp, fix the exponent character and null terminate *) >> FOR i := 0 TO nchars -1 DO >> ch := source [i]; >> IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; >> tmp [i] := ch; >> END; >> tmp [nchars] := '\000'; >> >> (* finally, do the conversion *) >> value := strtod (ADR (tmp [0]), eptr); line 824 >> IF eptr = LOOPHOLE (0, ADDRESS) >> THEN RETURN FALSE; >> ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; >> END; >> END ToBinary; >> >> value unfortunately is void* but that can be ok. >> With all the casts. Just bad for debugging. >> >> /*nil pointer_define*/typedef void* T6B01CD09; >> >> UINT8 >> __cdecl >> Convert__ToBinary( >> /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, >> /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, >> /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, >> /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, >> /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, >> /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) >> . >> . >> . >> >> #line 824 "../src/convert/Convert.m3" >> (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( >> /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), >> /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); >> #line 824 "../src/convert/Convert.m3" >> /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ >> #line 824 "../src/convert/Convert.m3" >> /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ >> #line 824 "../src/convert/Convert.m3" >> /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? >> #line 824 "../src/convert/Convert.m3" >> /* store_indirect offset:0 ztype:double mtype:double */ >> #line 824 "../src/convert/Convert.m3" >> (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); >> #line 824 "../src/convert/Convert.m3" >> #line 825 "../src/convert/Convert.m3" >> >> Because "address" (which really should be double*) has some implied insufficient alignment? >> >> I'll dig a bit more. I think I am close. >> >> Thank you, >> - Jay >> >> _______________________________________________ >> M3devel mailing list >> M3devel at elegosoft.com >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517639100%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=EJ4Nkpv7Gf4ZI7pW3KPsW9%2FPmJjr7vJtFCTdXkg6si8%3D&reserved=0 >> > > -- > Rodney Bates > rodney.m.bates at acm.org > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517639100%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=EJ4Nkpv7Gf4ZI7pW3KPsW9%2FPmJjr7vJtFCTdXkg6si8%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Fri Apr 2 22:41:50 2021 From: jayk123 at hotmail.com (Jay K) Date: Fri, 2 Apr 2021 20:41:50 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: , , Message-ID: And, what if the answer is yes? As I understand, m3front does not really generate code dependent on the stated alignment. Alignment in m3front is: - record layout - tell the backend, like so structs with char arrays are more aligned than char (but better handled with strongly typed fields) If the backend decides lower alignment is adequate, that can be ok. The m3front-generated code doesn't care much. Right? We should make sure traced allocations are 64 or two pointer aligned, though. - Jay ________________________________ From: Jay K Sent: Friday, April 2, 2021 8:21 PM To: m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 Not exactly. The frontend should align record offsets to the stated alignment. This is the most important thing and is currently broken. If you ask it to do this, you get compilation problems. This is where the known bugs are. Everything else has seemed to be working, but we can/should double check. The runtime traced allocator should alway align to at least 64. Maybe 128 on 64bit target. That is for us to look into and fix if it is broken. "segments" are likely already properly aligned by the backend/linker. But we can for example union them with an int64 and double and possibly int128, in the m3cc backend. I think they already are strongly enough typed that it already works though. From my experience debugging i386_cygwin. We can investigate the malloc behavior across systems. However, notice that gcc has -malign-double for x86. Notice gcc behavior on all the other systems. Therefore malloc can be assumed to be at least 64-aligned, yes. But we can check if you are skeptical. On Windows, heap alignment is in the ABI and adequate. mmap aligns to at least 4k bytes on all modern systems, often 8k or 64k. How do the 64bit targets work today? Where is the code to ensure they get their 64bit alignment? Where is the code to ensure even 32bit alignment? I don't believe Linux/x86 stack has any such guarantee. We just kinda assume it. Except, again, we don't really care. Repeating: The most important factor is for m3front to layout records. Again, malloc takes care of whatever the platform needs. "segments" might need some attention, but this does not change that, really. Stack can be ignored. - Jay ________________________________ From: Rodney M. Bates Sent: Friday, April 2, 2021 7:58 PM To: Jay K ; m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 So, you just want the front end to assume that the existence of something in Target.i3 with 64-bit alignment means those things we discussed will arrive 64-bit aligned and go with that? On 4/2/21 2:21 AM, Jay K wrote: > For what it is worth, I have gone back a few weeks, and things did work. > > I386_NT can build and run with the C backend, and the 64bit sized types have 64bit alignment. > > There was one semi suspicious change of mine, around unaligned accesses, but things worked either way. > > Which agrees with my recollection that x86 and sparc32 worked years ago, and maybe other 32bit targets (ppc32?) > > Of course the IR is not super interesting. > It did change, the swap stuff on store_indirect for > example, but I think the change is all in m3front > new enforcements or changed calculations feeding > into new or same enforcements. > > I'll keep digging. > > I think it comes down to the addresses of things having "address alignment", > implied to mean "pointed to", instead of the alignment of the thing pointed to. > > For example Formal.m3 seems to confuse this. > When mode # value, the parameter gets address alignment. > > But this is not enough to fix it all. > > This is the very confusion you mentioned and I think it persists. > Like, before the code overloaded align and either got it right, though confusing, > or enforcements were missing. Now you have tried to clarify it, but either > got it wrong or added enforcements. Or maybe I am confused. > > I do wish I had setup CI long ago to catch this earlier. > I hope to get to that soon. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Thursday, April 1, 2021 10:49 PM > *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > > should be prevented by earlier compile errors. > > You should be able to see the errors on any host with: > > C:\s\cm3\m3-libs\m3core>cm3 -DTARGET=I386_LINUX -DM3_BACKEND_MODE=C -boot -keep -override -DROOT=/s/cm3 > replace the last parameter as appropriate. > > "..\src\float\Common\TextToFloat.m3", line 351: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > "..\src\convert\Convert.m3", line 824: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > > It isn't really the C backend, except I changed Target.m3 to keep the old alignments for it. > > If it doesn't repro there, then also try libm3 and m3middle and m3back (after building m3core), but m3core should suffice, at least to get started. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* M3devel on behalf of Jay K > *Sent:* Thursday, April 1, 2021 10:38 PM > *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > Some of the ABIs I refer to, not all: > > x86-32: > > https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.sco.com%2Fdevelopers%2Fdevspecs%2Fabi386-4.pdf&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517629104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=RNBlSupaJk5FCWcHv27KKkzw8GWtL3PzHjimKEfW5og%3D&reserved=0 > The Intel386 architecture does not require doubleword alignment for doubleprecision values. > Nevertheless, for data structure compatibility with other Intel > architectures, compilers may provide a method to align double-precision > values on doubleword boundaries. > > mips > mipsabi32.pdf (sourceforge.net) > double is 8 aligned > no mention of int64/longlong. > > > ppc32 > https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmath-atlas.sourceforge.net%2Fdevel%2Fassembly%2Felfspec_ppc.pdf&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517629104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=zZk5xwoOl84kiRPova8RcCMlUC%2BYfyeJ1Mi%2FbHOudcs%3D&reserved=0 > doubles are 8-aligned > " > long long (where implemented), and double arguments are considered to have 8-byte > size and alignment > " > > sparc32 > https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmath-atlas.sourceforge.net%2Fdevel%2Fassembly%2Fabi_sysV_sparc.pdf&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517629104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=ZjMmRMEXavsj61v5P%2BVIi0z9jLgJbe4MCxo5T3Jbq1c%3D&reserved=0 > double is 8-aligned > no mention of 64bit integers > > sparc32 again > https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Ftemlib.org%2Fpub%2FSparcStation%2FStandards%2FV8plus.pdf&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517629104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=cWcNdvRqnJ7fJekqgdoPFmK9sHzToBH5L8U%2FGRj0fnk%3D&reserved=0 > 2.1.3 C ?long long? > Compare with SysV SPARC ABI, Figure 3-1, p.3-2. > A C long long is an 8-byte quantity, aligned on an 8-byte boundary. It usually > occupies the low-order halves of a register pair: LDD and STD (or two LDs and > STs) are usually used to move a long long; not LDX/STX. If you use LDX/STX, > you must use a global or out register. > > More than this I believe are similar. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Thursday, April 1, 2021 10:14 PM > *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > I've said it before. > > Many 32bit ABIs do align int64 and double to 64bits. > Just not Linux/x86. I checked several. > Linux/mips32, Linux/ppc32, etc. like everything except x86 and m68k. > NT/x86 also 64-aligns the 64bit sized types. > cm3 is violating many but not all ABIs. > In terms of RECORD/struct interop. > > The underlying native heaps are aligned. They have to be. > I will check on Linux/x86. > Win32 heaps are aligned to two pointers. > Tons of C code would break otherwise. > The globals are also handled trivially. > It is true the stack is not always aligned but that is ok. > It seems wierd, I agree, but that is how C on Win32/x86 works. > There is a vague idea that you tend not to do atomic operations against stack, just heap and globals. > > When we have C like: > > struct footype > { > int a; > double d; // or int64 > }; > > Most C compilers, 32bit and 64bit targets, will insert 4 bytes of padding between a and d. > All Windows compilers will and many Linux ones will. > > For many years cm3 did too and it worked. It just recently broke. > If that were not the case I could not generate portable C for it. > There are gcc and Visual C++ extensions to break the alignment but I'd really rather not use them. > > On the other hand, if cm3 wants padding then it can say like: > > struct footype > { > int a; > char padding[4]; > double d; // or int64 > }; > > and this does give the same layout on all systems. > > On the hardware side, perhaps, atomic operations care. > We don't know which data will be operated on atomically, but it is not usually stack. > So you use the alignment that atomics require. > > i.e. > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fwindows%2Fwin32%2Fapi%2Fwinnt%2Fnf-winnt-interlockedcompareexchange64&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517639100%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=cTL8i7R8HVEQj2sGpEPKkSkCG7hbPfIj828oWY1YkiA%3D&reserved=0 > " > The variables for this function must be aligned on a 64-bit boundary; > otherwise, this function will behave unpredictably on multiprocessor > x86 systems and any non-x86 systems. > > See _aligned_malloc. > " > > The last part "See _aligned_malloc" is bogus. There is no need for that. > I'll try to get that fixed. The regular heap is already aligned enough. > > > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > > should be prevented by earlier compile errors. > > It doesn't. > Pointers to double are considered to have 32bit alignment and storing a double through them does this. > At least in a few places. > > I am not sure what is the point of attempting to track the alignment of what a pointer points to. > Pointers in C and C++ do not really have this. They either point to a strongly specified type > and are assumed to have its alignment, or they are void* or char* and you are on your own, > usually either operating a byte at a time, or eventually casting back to the original type, > that the pointer was already aligned to, so ok. > You are also on your own if you cast a pointer amongst types with different alignment, or > at least to a pointer to a type with greater alignment. > Granted, I am mixing up IR and source. Perhaps C IR tends to look like this? > > Is cm3 going out of its way to track something that is already correct? > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Rodney M. Bates > *Sent:* Thursday, April 1, 2021 9:45 PM > *To:* Jay K ; m3devel at elegosoft.com > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > The compiler can't provide larger alignment than is first provided by > some other things. The heap allocator must give every heap object the > maximum alignment of anything. 64-bit alignment on 32 could be pretty > wasteful, depending on what the application is allocating. The heap > allocator also would need the same from wherever it gets its heap > space. The initial stack setup would have to do the same. Same for > all the sections of object modules and executables, thus the linker > and loader. The untraced heap is just implemented by using malloc and > friends, so it would have to do it too. > > Then there's the business of aligning the stack on every call. For > target machines that do runtime stack operands, this would have to be > done in the back end. The front end could maybe do it at the abstract > level of the IR, but whether/how that would match the machine > instruction set is target-dependent. The abstract stack model of the > IR does not view the operand stack as interspersed with activation > records, so would have some record-keeping to do. > > Unless you can first ensure all target machines, OSs and their tool > chains would do these things, it is vain to try to get the compiler to > do it. Or do you want this introduce a new target-dependency? > > Tell us again why you want to do this? Is there a 32-bit hardware > machine that puts a 64-bit alignment requirement on any value of any > kind? If not, why go to this trouble. > > On the subject of cg_align, etc., here is a summary. The front end > previously had lots of variables named "align" or such that failed to > distinguish between the alignment of where a value was stored (call > this "value alignment") and, in the case where the value was an > address, the alignment of where it pointed, (call this the "address > alignment"). There were no hints on any alignment field, which it > meant, and I certainly couldn't confidently follow it all, the way it > was coded. I attempted to unravel this, with, I believe, at least > mostly success. > > In types/Type.i3.Info, "alignment" was once a mixture, but now is > value alignment. New field "addr_align" is address alignment. > > In CG.m3, these are named "base_align" and "addr_align". I renamed > the old "align" to "old_align" and maintained its value unchanged, but > replaced all references to one of the others. Then there is also > "base_value_align", which, rather confusingly, is the value alignment > of where the base points, equals the address alignment of the base's > contents. This intermediate alignment is needed to compute other > things for some of the address modes of the ValRec. > > In values/Variable.m3, preexisting field "align" is value alignment > and preexisting "cg_align" is address alignment. I believe this may > have been the original intent, but there were places it was not > complete. > > But, no matter what M3 source code you feed it, INTERNAL CG ERROR > should be prevented by earlier compile errors. Note that the > restrictions on packing are now less that before. But some of the > preexisting ones were not being detected, making things now appear > more restrictive at compile time. > > P.S. Yes, the low-level type system of the IR, like most, doesn't > give a lot of info about the type of the referent of a pointer. > However, the referent's address alignments do come through most/all of > the operators, (always did, assuming they are correct) alongside the > CG type. > > > On 4/1/21 12:37 AM, Jay K wrote: >> What are the three alignments here? >> >> ELSIF (t.indirect) THEN >> CG.Comment(-1, TRUE, "Variable load_indirect:align:" & >> Fmt.Int(t.align) & >> " cg_align:" & >> Fmt.Int(t.cg_align) & >> " type_info.addr_align:" & >> Fmt.Int(type_info.addr_align)); >> CG.Load_addr (t.cg_var, t.offset, t.cg_align); >> CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >> >> >> /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ >> >> >> addr_align: Alignment; (* when type=Addr, alignment of VALUE. *) >> (* NOTE: Originally, field 'align' was highly inconsistent on whether it >> was the alignment where a value is (or could be) stored, or, when >> type=Addr, the alignment of where the value pointed. Most calls >> outside of CG passed in the former, while most uses inside CG >> expected the latter. This is quite complicated to unravel, so >> to reduce breakage risk and facilitate fixes thereof, three values >> are maintained. 'old_align' is as 'align' was. 'base_align' is >> the former, and 'addr_align' is the latter. It should be possible >> to eliminate 'old_align' altogether, after ample testing and >> removal of all uses thereof. *) >> >> >> align became cg_align a few places. Why? >> What is the difference? >> Too many things are called align w/o obvious to me why so many. :( >> >> commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca >> Author: Rodney Bates >> Date: Wed Aug 8 15:10:38 2018 -0500 >> >> packedVars branch, initial commit. >> ... >> >> diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 >> index 77064cde0..301e88ccd 100644 >> --- a/m3-sys/m3front/src/values/Variable.m3 >> +++ b/m3-sys/m3front/src/values/Variable.m3 >> >> @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = >> CG.Load_addr_of (t.bss_var, 0, t.cg_align); >> ELSIF (t.cg_var = NIL) THEN (* => global *) >> Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); >> - CG.Boost_alignment (t.align); >> + CG.Boost_addr_alignment (t.cg_align); >> ELSIF (t.indirect) THEN >> - CG.Load_addr (t.cg_var, t.offset); >> - CG.Boost_alignment (t.align); >> + CG.Load_addr (t.cg_var, t.offset, t.cg_align); >> ELSE >> CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); >> END; >> ELSE (* simple scalar *) >> . >> . >> . >> - CG.Boost_alignment (t.align); >> - CG.Load_indirect (t.stk_type, 0, t.size); >> + CG.Boost_addr_alignment (t.cg_align); >> + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >> ELSIF (t.indirect) THEN >> - CG.Load_addr (t.cg_var, t.offset); >> - CG.Boost_alignment (t.align); >> - CG.Load_indirect (t.stk_type, 0, t.size); >> + CG.Load_addr (t.cg_var, t.offset, t.cg_align); >> + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >> . >> . >> . >> END Load; >> @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = >> CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); >> END; >> ELSIF (t.indirect) THEN >> . >> . >> . >> - CG.Boost_alignment (t.align); >> + CG.Boost_addr_alignment (t.cg_align); >> END LoadLValue; >> PROCEDURE SetLValue (t: T) = >> @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = >> align := CG.Max_alignment; >> END; >> <*ASSERT t.indirect *> >> - CG.Boost_alignment (align); >> + CG.Boost_addr_alignment (t.cg_align); >> CG.Store_addr (v, t.offset); >> END SetLValue; >> I think that is the problem. >> >> Alignment seems like a big mess in the compiler. >> >> Btw I'm wrong I think about the typing. >> I think the parameter could be an indirect double, if m3front would say so. >> But that is a separate point. >> >> - Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* M3devel on behalf of Jay K >> *Sent:* Thursday, April 1, 2021 4:13 AM >> *To:* m3devel at elegosoft.com >> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> Hm, so the backend interface doesn't have a notion of pointers to types, does it? >> Just untyped pointers? >> So needs a lot of work, I suspect. >> >> - Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* Jay K >> *Sent:* Thursday, April 1, 2021 4:13 AM >> *To:* m3devel at elegosoft.com >> *Subject:* INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. >> >> PROCEDURE ToBinary ( >> READONLY source : Buffer; >> exp1, exp2 : CHAR; >> VAR tmp : Buffer; >> VAR used : INTEGER; >> VAR value : LONGREAL): BOOLEAN = >> VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); >> BEGIN >> (* copy source to tmp, fix the exponent character and null terminate *) >> FOR i := 0 TO nchars -1 DO >> ch := source [i]; >> IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; >> tmp [i] := ch; >> END; >> tmp [nchars] := '\000'; >> >> (* finally, do the conversion *) >> value := strtod (ADR (tmp [0]), eptr); line 824 >> IF eptr = LOOPHOLE (0, ADDRESS) >> THEN RETURN FALSE; >> ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; >> END; >> END ToBinary; >> >> value unfortunately is void* but that can be ok. >> With all the casts. Just bad for debugging. >> >> /*nil pointer_define*/typedef void* T6B01CD09; >> >> UINT8 >> __cdecl >> Convert__ToBinary( >> /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, >> /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, >> /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, >> /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, >> /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, >> /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) >> . >> . >> . >> >> #line 824 "../src/convert/Convert.m3" >> (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( >> /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), >> /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); >> #line 824 "../src/convert/Convert.m3" >> /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ >> #line 824 "../src/convert/Convert.m3" >> /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ >> #line 824 "../src/convert/Convert.m3" >> /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? >> #line 824 "../src/convert/Convert.m3" >> /* store_indirect offset:0 ztype:double mtype:double */ >> #line 824 "../src/convert/Convert.m3" >> (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); >> #line 824 "../src/convert/Convert.m3" >> #line 825 "../src/convert/Convert.m3" >> >> Because "address" (which really should be double*) has some implied insufficient alignment? >> >> I'll dig a bit more. I think I am close. >> >> Thank you, >> - Jay >> >> _______________________________________________ >> M3devel mailing list >> M3devel at elegosoft.com >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517639100%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=EJ4Nkpv7Gf4ZI7pW3KPsW9%2FPmJjr7vJtFCTdXkg6si8%3D&reserved=0 >> > > -- > Rodney Bates > rodney.m.bates at acm.org > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517639100%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=EJ4Nkpv7Gf4ZI7pW3KPsW9%2FPmJjr7vJtFCTdXkg6si8%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Fri Apr 2 22:51:19 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 2 Apr 2021 15:51:19 -0500 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: Message-ID: On 4/1/21 5:49 PM, Jay K wrote: > ?> But, no matter what M3 source code you feed it, INTERNAL CG ERROR > ?> should be prevented by earlier compile errors. > > ?You should be able to see the errors on any host with: > > ? C:\s\cm3\m3-libs\m3core>cm3 -DTARGET=I386_LINUX -DM3_BACKEND_MODE=C -boot -keep -override -DROOT=/s/cm3 > ? replace the last parameter as appropriate. I can't reproduce in commit 5069e5e, running a compiler from 5d8073a. Did m3core, libm3, sysutils, m3objfile, m3middle, and m3back, each without and with cleaning. I am currently unable to compile a compiler, but should get that resolved soon. > > ?"..\src\float\Common\TextToFloat.m3", line 351: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel ?s/a=64/32 > ?"..\src\convert\Convert.m3", line 824: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel ?s/a=64/32 > > It isn't really the C backend, except I changed Target.m3 to keep the old alignments for it. > > If it doesn't repro there, then also try libm3 and m3middle and m3back (after building m3core), but m3core should suffice, at least to get started. > > ?- Jay > > -- Rodney Bates rodney.m.bates at acm.org From rodney_bates at lcwb.coop Fri Apr 2 23:01:11 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 2 Apr 2021 16:01:11 -0500 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: Message-ID: On 4/2/21 3:21 PM, Jay K wrote: > Not exactly. > > The frontend should align record offsets to the stated alignment. > This is the most important thing and is currently broken. Not sure I understand. Do you mean each field should be aligned within the record according to the field's type's alignment? Or are you talking about alignment of the whole record? The only thing I can think of that would not be happening, is giving things alignment larger than the word size. Alignment of a whole record is max of alignment of its fields. There aren't any BITS FOR getting in the ointment are there? Per Modula 3, those never get padded to anything, just put at the next available bit. > If you ask it to do this, you get compilation problems. > This is where the known bugs are. > Everything else has seemed to be working, but we can/should double check. > > The runtime traced allocator should alway align to at least 64. > Maybe 128 on 64bit target. > That is for us to look into and fix if it is broken. > > "segments" are likely already properly aligned by the backend/linker. > But we can for example union them with an int64 and double and possibly int128, > in the m3cc backend. I think they already are strongly enough typed > that it already works though. From my experience debugging i386_cygwin. > > We can investigate the malloc behavior across systems. > However, notice that gcc has -malign-double for x86. > Notice gcc behavior on all the other systems. > Therefore malloc can be assumed to be at least 64-aligned, yes. > But we can check if you are skeptical. > On Windows, heap alignment is in the ABI and adequate. > mmap aligns to at least 4k bytes on all modern systems, often 8k or 64k. > > How do the 64bit targets work today? > Where is the code to ensure they get their 64bit alignment? > Where is the code to ensure even 32bit alignment? > I don't believe Linux/x86 stack has any such guarantee. > We just kinda assume it. > Except, again, we don't really care. > > Repeating: The most important factor is for m3front to layout records. > Again, malloc takes care of whatever the platform needs. > "segments" might need some attention, but this does not change that, really. > Stack can be ignored. > > ?- Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Rodney M. Bates > *Sent:* Friday, April 2, 2021 7:58 PM > *To:* Jay K ; m3devel at elegosoft.com ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > So, you just want the front end to assume that the existence of something in Target.i3 > with 64-bit alignment means those things we discussed will arrive 64-bit aligned and > go with that? > > > > On 4/2/21 2:21 AM, Jay K wrote: >> For what it is worth, I have gone back a few weeks, and things did work. >> >> I386_NT can build and run with the C backend, and the 64bit sized types have 64bit alignment. >> >> There was one semi suspicious change of mine, around unaligned accesses, but things worked either way. >> >> Which agrees with my recollection that x86 and sparc32 worked years ago, and maybe other 32bit targets (ppc32?) >> >> Of course the IR is not super interesting. >> It did change, the swap stuff on store_indirect for >> example, but I think the change is all in m3front >> new enforcements or changed calculations feeding >> into new or same enforcements. >> >> I'll keep digging. >> >> I think it comes down to the addresses of things having "address alignment", >> implied to mean "pointed to", instead of the alignment of the thing pointed to. >> >> For example Formal.m3 seems to confuse this. >> When mode # value, the parameter gets address alignment. >> >> But this is not enough to fix it all. >> >> This is the very confusion you mentioned and I think it persists. >> Like, before the code overloaded align and either got it right, though confusing, >> or enforcements were missing. Now you have tried to clarify it, but either >> got it wrong or added enforcements. Or maybe I am confused. >> >> I do wish I had setup CI long ago to catch this earlier. >> I hope to get to that soon. >> >>? ?- Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* Jay K >> *Sent:* Thursday, April 1, 2021 10:49 PM >> *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org >> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >>? ?> But, no matter what M3 source code you feed it, INTERNAL CG ERROR >>? ?> should be prevented by earlier compile errors. >> >>? ?You should be able to see the errors on any host with: >> >>? ? C:\s\cm3\m3-libs\m3core>cm3 -DTARGET=I386_LINUX -DM3_BACKEND_MODE=C -boot -keep -override -DROOT=/s/cm3 >>? ? replace the last parameter as appropriate. >> >>? ?"..\src\float\Common\TextToFloat.m3", line 351: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel ?s/a=64/32 >>? ?"..\src\convert\Convert.m3", line 824: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel ?s/a=64/32 >> >> It isn't really the C backend, except I changed Target.m3 to keep the old alignments for it. >> >> If it doesn't repro there, then also try libm3 and m3middle and m3back (after building m3core), but m3core should suffice, at least to get started. >> >>? ?- Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* M3devel on behalf of Jay K >> *Sent:* Thursday, April 1, 2021 10:38 PM >> *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org >> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> Some of the ABIs I refer to, not all: >> >> x86-32: >> >> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.sco.com%2Fdevelopers%2Fdevspecs%2Fabi386-4.pdf&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517629104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=RNBlSupaJk5FCWcHv27KKkzw8GWtL3PzHjimKEfW5og%3D&reserved=0 >> The Intel386 architecture does not require doubleword alignment for doubleprecision values. >> Nevertheless, for data structure compatibility with other Intel >> architectures, compilers may provide a method to align double-precision >> values on doubleword boundaries. >> >> mips >> mipsabi32.pdf (sourceforge.net) >> double is 8 aligned >> no mention of int64/longlong. >> >> >> ppc32 >> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmath-atlas.sourceforge.net%2Fdevel%2Fassembly%2Felfspec_ppc.pdf&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517629104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=zZk5xwoOl84kiRPova8RcCMlUC%2BYfyeJ1Mi%2FbHOudcs%3D&reserved=0 >> doubles are 8-aligned >> " >> long long (where implemented), and double arguments are considered to have 8-byte >> size and alignment >> " >> >> sparc32 >> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmath-atlas.sourceforge.net%2Fdevel%2Fassembly%2Fabi_sysV_sparc.pdf&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517629104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=ZjMmRMEXavsj61v5P%2BVIi0z9jLgJbe4MCxo5T3Jbq1c%3D&reserved=0 >> double is 8-aligned >> no mention of 64bit integers >> >> sparc32 again >> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Ftemlib.org%2Fpub%2FSparcStation%2FStandards%2FV8plus.pdf&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517629104%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=cWcNdvRqnJ7fJekqgdoPFmK9sHzToBH5L8U%2FGRj0fnk%3D&reserved=0 >> 2.1.3 C ?long long? >> Compare with SysV SPARC ABI, Figure 3-1, p.3-2. >> A C long long is an 8-byte quantity, aligned on an 8-byte boundary. It usually >> occupies the low-order halves of a register pair: LDD and STD (or two LDs and >> STs) are usually used to move a long long; not LDX/STX. If you use LDX/STX, >> you must use a global or out register. >> >> More than this I believe are similar. >> >>? ?- Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* Jay K >> *Sent:* Thursday, April 1, 2021 10:14 PM >> *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org >> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> I've said it before. >> >> Many 32bit ABIs do align int64 and double to 64bits. >> Just not Linux/x86. I checked several. >> Linux/mips32, Linux/ppc32, etc. like everything except x86 and m68k. >> NT/x86 also 64-aligns the 64bit sized types. >> cm3 is violating many but not all ABIs. >>? ?In terms of RECORD/struct interop. >> >> The underlying native heaps are aligned. They have to be. >> I will check on Linux/x86. >> Win32 heaps are aligned to two pointers. >> Tons of C code would break otherwise. >> The globals are also handled trivially. >> It is true the stack is not always aligned but that is ok. >> It seems wierd, I agree, but that is how C on Win32/x86 works. >> There is a vague idea that you tend not to do atomic operations against stack, just heap and globals. >> >>? ?When we have C like: >> >>? ?struct footype >>? ?{ >>? ? int a; >>? ? double d; // or int64 >>? ?}; >> >>? ?Most C compilers, 32bit and 64bit targets, will insert 4 bytes of padding between a and d. >>? ?All Windows compilers will and many Linux ones will. >> >>? ?For many years cm3 did too and it worked. It just recently broke. >>? ?If that were not the case I could not generate portable C for it. >>? ?There are gcc and Visual C++ extensions to break the alignment but I'd really rather not use them. >> >>? ?On the other hand, if cm3 wants padding then it can say like: >> >> struct footype >> { >>? ?int a; >>? ?char padding[4]; >>? ?double d; // or int64 >> }; >> >> and this does give the same layout on all systems. >> >> On the hardware side, perhaps, atomic operations care. >> We don't know which data will be operated on atomically, but it is not usually stack. >> So you use the alignment that atomics require. >> >> i.e. >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fwindows%2Fwin32%2Fapi%2Fwinnt%2Fnf-winnt-interlockedcompareexchange64&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517639100%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=cTL8i7R8HVEQj2sGpEPKkSkCG7hbPfIj828oWY1YkiA%3D&reserved=0 >> " >> The variables for this function must be aligned on a 64-bit boundary; >> otherwise, this function will behave unpredictably on multiprocessor >> x86 systems and any non-x86 systems. >> >> See _aligned_malloc. >> " >> >> The last part "See _aligned_malloc" is bogus. There is no need for that. >> I'll try to get that fixed. The regular heap is already aligned enough. >> >>? ?> But, no matter what M3 source code you feed it, INTERNAL CG ERROR >>? ?> should be prevented by earlier compile errors. >> >> It doesn't. >> Pointers to double are considered to have 32bit alignment and storing a double through them does this. >> At least in a few places. >> >> I am not sure what is the point of attempting to track the alignment of what a pointer points to. >> Pointers in C and C++ do not really have this. They either point to a strongly specified type >> and are assumed to have its alignment, or they are void* or char* and you are on your own, >> usually either operating a byte at a time, or eventually casting back to the original type, >> that the pointer was already aligned to, so ok. >> You are also on your own if you cast a pointer amongst types with different alignment, or >> at least to a pointer to a type with greater alignment. >> Granted, I am mixing up IR and source. Perhaps C IR tends to look like this? >> >> Is cm3 going out of its way to track something that is already correct? >> >>? ?- Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* Rodney M. Bates >> *Sent:* Thursday, April 1, 2021 9:45 PM >> *To:* Jay K ; m3devel at elegosoft.com >> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> The compiler can't provide larger alignment than is first provided by >> some other things.? The heap allocator must give every heap object the >> maximum alignment of anything.? 64-bit alignment on 32 could be pretty >> wasteful, depending on what the application is allocating.? The heap >> allocator also would need the same from wherever it gets its heap >> space.? The initial stack setup would have to do the same.? Same for >> all the sections of object modules and executables, thus the linker >> and loader.? The untraced heap is just implemented by using malloc and >> friends, so it would have to do it too. >> >> Then there's the business of aligning the stack on every call.? For >> target machines that do runtime stack operands, this would have to be >> done in the back end.? The front end could maybe do it at the abstract >> level of the IR, but whether/how that would match the machine >> instruction set is target-dependent.? The abstract stack model of the >> IR does not view the operand stack as interspersed with activation >> records, so would have some record-keeping to do. >> >> Unless you can first ensure all target machines, OSs and their tool >> chains would do these things, it is vain to try to get the compiler to >> do it. Or do you want this introduce a new target-dependency? >> >> Tell us again why you want to do this?? Is there a 32-bit hardware >> machine that puts a 64-bit alignment requirement on any value of any >> kind?? If not, why go to this trouble. >> >> On the subject of cg_align, etc., here is a summary.? The front end >> previously had lots of variables named "align" or such that failed to >> distinguish between the alignment of where a value was stored (call >> this "value alignment") and, in the case where the value was an >> address, the alignment of where it pointed, (call this the "address >> alignment").? There were no hints on any alignment field, which it >> meant, and I certainly couldn't confidently follow it all, the way it >> was coded.? I attempted to unravel this, with, I believe, at least >> mostly success. >> >> In types/Type.i3.Info, "alignment" was once a mixture, but now is >> value alignment.? New field "addr_align" is address alignment. >> >> In CG.m3, these are named "base_align" and "addr_align".? I renamed >> the old "align" to "old_align" and maintained its value unchanged, but >> replaced all references to one of the others.? Then there is also >> "base_value_align", which, rather confusingly, is the value alignment >> of where the base points, equals the address alignment of the base's >> contents.? This intermediate alignment is needed to compute other >> things for some of the address modes of the ValRec. >> >> In values/Variable.m3, preexisting field "align" is value alignment >> and preexisting "cg_align" is address alignment. I believe this may >> have been the original intent, but there were places it was not >> complete. >> >> But, no matter what M3 source code you feed it, INTERNAL CG ERROR >> should be prevented by earlier compile errors.? Note that the >> restrictions on packing are now less that before.? But some of the >> preexisting ones were not being detected, making things now appear >> more restrictive at compile time. >> >> P.S.? Yes, the low-level type system of the IR, like most, doesn't >> give a lot of info about the type of the referent of a pointer. >> However, the referent's address alignments do come through most/all of >> the operators, (always did, assuming they are correct) alongside the >> CG type. >> >> >> On 4/1/21 12:37 AM, Jay K wrote: >>> What are the three alignments here? >>> >>>? ? ? ? ELSIF (t.indirect) THEN >>>? ? ? ? ? CG.Comment(-1, TRUE, "Variable load_indirect:align:" & >>>? ? ? ? ? ? Fmt.Int(t.align) & >>>? ? ? ? ? ? " cg_align:" & >>>? ? ? ? ? ? Fmt.Int(t.cg_align) & >>>? ? ? ? ? ? " type_info.addr_align:" & >>>? ? ? ? ? ? Fmt.Int(type_info.addr_align)); >>>? ? ? ? ? CG.Load_addr (t.cg_var, t.offset, t.cg_align); >>>? ? ? ? ? CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >>> >>> >>> /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ >>> >>> >>>? ? ? addr_align: Alignment; ? ?(* when type=Addr, alignment of VALUE. *) >>>? ? ? (* NOTE: Originally, field 'align' was highly inconsistent on whether it >>>? ? ? ? ? ? ? ?was the alignment where a value is (or could be) stored, or, when >>>? ? ? ? ? ? ? ?type=Addr, the alignment of where the value pointed. ?Most calls >>>? ? ? ? ? ? ? ?outside of CG passed in the former, while most uses inside CG >>>? ? ? ? ? ? ? ?expected the latter. ?This is quite complicated to unravel, so >>>? ? ? ? ? ? ? ?to reduce breakage risk and facilitate fixes thereof, three values >>>? ? ? ? ? ? ? ?are maintained. ?'old_align' is as 'align' was. ?'base_align' is >>>? ? ? ? ? ? ? ?the former, and 'addr_align' is the latter. ?It should be possible >>>? ? ? ? ? ? ? ?to eliminate 'old_align' altogether, after ample testing and >>>? ? ? ? ? ? ? ?removal of all uses thereof. *) >>> >>> >>> align became cg_align a few places. Why? >>> What is the difference? >>> Too many things are called align w/o obvious to me why so many. :( >>> >>> commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca >>> Author: Rodney Bates >>> Date: ? Wed Aug 8 15:10:38 2018 -0500 >>> >>>? ? ? packedVars branch, initial commit. >>> ... >>> >>> diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 >>> index 77064cde0..301e88ccd 100644 >>> --- a/m3-sys/m3front/src/values/Variable.m3 >>> +++ b/m3-sys/m3front/src/values/Variable.m3 >>> >>> @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = >>>? ? ? ? ? ?CG.Load_addr_of (t.bss_var, 0, t.cg_align); >>>? ? ? ? ?ELSIF (t.cg_var = NIL) THEN (* => global *) >>>? ? ? ? ? ?Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); >>> - ? ? ? ?CG.Boost_alignment (t.align); >>> + ? ? ? ?CG.Boost_addr_alignment (t.cg_align); >>>? ? ? ? ?ELSIF (t.indirect) THEN >>> - ? ? ? ?CG.Load_addr (t.cg_var, t.offset); >>> - ? ? ? ?CG.Boost_alignment (t.align); >>> + ? ? ? ?CG.Load_addr (t.cg_var, t.offset, t.cg_align); >>>? ? ? ? ?ELSE >>>? ? ? ? ? ?CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); >>>? ? ? ? ?END; >>>? ? ? ?ELSE (* simple scalar *) >>> . >>> . >>> . >>> - ? ? ? ?CG.Boost_alignment (t.align); >>> - ? ? ? ?CG.Load_indirect (t.stk_type, 0, t.size); >>> + ? ? ? ?CG.Boost_addr_alignment (t.cg_align); >>> + ? ? ? ?CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >>>? ? ? ? ?ELSIF (t.indirect) THEN >>> - ? ? ? ?CG.Load_addr (t.cg_var, t.offset); >>> - ? ? ? ?CG.Boost_alignment (t.align); >>> - ? ? ? ?CG.Load_indirect (t.stk_type, 0, t.size); >>> + ? ? ? ?CG.Load_addr (t.cg_var, t.offset, t.cg_align); >>> + ? ? ? ?CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >>> . >>> . >>> . >>>? ? ?END Load; >>> @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = >>>? ? ? ? ? ?CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); >>>? ? ? ? ?END; >>>? ? ? ?ELSIF (t.indirect) THEN >>> . >>> . >>> . >>> - ? ?CG.Boost_alignment (t.align); >>> + ? ?CG.Boost_addr_alignment (t.cg_align); >>>? ? ?END LoadLValue; >>>? ?PROCEDURE SetLValue (t: T) = >>> @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = >>>? ? ? ? ?align := CG.Max_alignment; >>>? ? ? ?END; >>>? ? ? ?<*ASSERT t.indirect *> >>> - ? ?CG.Boost_alignment (align); >>> + ? ?CG.Boost_addr_alignment (t.cg_align); >>>? ? ? ?CG.Store_addr (v, t.offset); >>>? ? ?END SetLValue; >>> I think that is the problem. >>> >>> Alignment seems like a big mess in the compiler. >>> >>> Btw I'm wrong I think about the typing. >>> I think the parameter could be an indirect double, if m3front would say so. >>> But that is a separate point. >>> >>>? ?- Jay >>> >>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >>> *From:* M3devel on behalf of Jay K >>> *Sent:* Thursday, April 1, 2021 4:13 AM >>> *To:* m3devel at elegosoft.com >>> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >>> Hm, so the backend interface doesn't have a notion of pointers to types, does it? >>> Just untyped pointers? >>> So needs a lot of work, I suspect. >>> >>>? ?- Jay >>> >>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >>> *From:* Jay K >>> *Sent:* Thursday, April 1, 2021 4:13 AM >>> *To:* m3devel at elegosoft.com >>> *Subject:* INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >>> This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. >>> >>> PROCEDURE ToBinary ( >>>? ? ? READONLY source ? ? : Buffer; >>>? ? ? ? ? ? ? ?exp1, exp2 : CHAR; >>>? ? ? ? ? ?VAR tmp ? ? ? ?: Buffer; >>>? ? ? ? ? ?VAR used ? ? ? : INTEGER; >>>? ? ? ? ? ?VAR value ? ? ?: LONGREAL): BOOLEAN = >>>? ? VAR ch: CHAR; ?eptr: ADDRESS; ?nchars: INTEGER := NUMBER (source); >>>? ? BEGIN >>>? ? ? (* copy source to tmp, fix the exponent character and null terminate *) >>>? ? ? FOR i := 0 TO nchars -1 DO >>>? ? ? ? ch := source [i]; >>>? ? ? ? IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; >>>? ? ? ? tmp [i] := ch; >>>? ? ? END; >>>? ? ? tmp [nchars] := '\000'; >>> >>>? ? ? (* finally, do the conversion *) >>>? ? ? value := strtod (ADR (tmp [0]), eptr); ? ? ? ? ? ? ? ? ?line 824 >>>? ? ? IF eptr = LOOPHOLE (0, ADDRESS) >>>? ? ? ? THEN RETURN FALSE; >>>? ? ? ? ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; >>>? ? ? END; >>>? ? END ToBinary; >>> >>> value unfortunately is void* but that can be ok. >>> With all the casts. Just bad for debugging. >>> >>> /*nil pointer_define*/typedef void* T6B01CD09; >>> >>> UINT8 >>> __cdecl >>> Convert__ToBinary( >>>? ? ?/* Param_Type 1 */ T7632CB42 /* strong_type1 */ ?source_L_245, >>>? ? ?/* Param_Type 1 */ CHAR /* strong_type1 */ ?exp1_L_246, >>>? ? ?/* Param_Type 1 */ CHAR /* strong_type1 */ ?exp2_L_247, >>>? ? ?/* Param_Type 1 */ T7632CB42 /* strong_type1 */ ?tmp_L_248, >>>? ? ?/* Param_Type 1 */ TE6A3D58B /* strong_type1 */ ?used_L_249, >>>? ? ?/* Param_Type 1 */ T6B01CD09 /* strong_type1 */ ?value_L_250) >>> . >>> . >>> . >>> >>> #line 824 "../src/convert/Convert.m3" >>> (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( >>>? ? /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ ?/* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), >>>? ? /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ ?/* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); >>> #line 824 "../src/convert/Convert.m3" >>>? ?/* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ >>> #line 824 "../src/convert/Convert.m3" >>>? ?/* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ >>> #line 824 "../src/convert/Convert.m3" >>>? ?/* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel ?s/a=64/32 */ ?<== Why this? >>> #line 824 "../src/convert/Convert.m3" >>>? ?/* store_indirect ?offset:0 ztype:double mtype:double */ >>> #line 824 "../src/convert/Convert.m3" >>> (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); >>> #line 824 "../src/convert/Convert.m3" >>> #line 825 "../src/convert/Convert.m3" >>> >>> Because "address" (which really should be double*) has some implied insufficient alignment? >>> >>> I'll dig a bit more. I think I am close. >>> >>> Thank you, >>>? ?- Jay >>> >>> _______________________________________________ >>> M3devel mailing list >>> M3devel at elegosoft.com >>> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517639100%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=EJ4Nkpv7Gf4ZI7pW3KPsW9%2FPmJjr7vJtFCTdXkg6si8%3D&reserved=0 >>> >> >> -- >> Rodney Bates >> rodney.m.bates at acm.org >> >> _______________________________________________ >> M3devel mailing list >> M3devel at elegosoft.com >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C88fdff0d9bde4eb1a7f108d8f611c71f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529903517639100%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=EJ4Nkpv7Gf4ZI7pW3KPsW9%2FPmJjr7vJtFCTdXkg6si8%3D&reserved=0 >> > > -- > Rodney Bates > rodney.m.bates at acm.org > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://m3lists.elegosoft.com/mailman/listinfo/m3devel > -- Rodney Bates rodney.m.bates at acm.org From jayk123 at hotmail.com Fri Apr 2 23:13:41 2021 From: jayk123 at hotmail.com (Jay K) Date: Fri, 2 Apr 2021 21:13:41 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: , Message-ID: I don't believe there are any BITS for here. I mean, m3front is surely correctly aligning things within records, but it the request for that, that leads to these internal errors. I mean, I want to be able to give int64 and double, 64bit alignment, and successfully compile without internal errors. It is alignment within records that most of all I need to be 64 for the 64bit sized types, even on 32bit target. Can you try: cd scripts/python ./upgrade.py ./boot1.py i386_linux c keep commands Or if you are certain you have an up to date compiler, then just the last. For i386_linux you can substitute others like i386_nt. ./upgrade.py just rebuilds the compiler, and then rebuilds with itself. Overkill for this exercise. Alternatively: cd scripts/python ./do-pk.py m3middle m3back cm3 build && ./install-cm3-compiler.py When you are done, to cleanup: ./do-cm3-all i386_linux realclean rm -rf cm3-boot- - Jay ________________________________ From: Rodney M. Bates Sent: Friday, April 2, 2021 9:01 PM To: Jay K ; m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 On 4/2/21 3:21 PM, Jay K wrote: > Not exactly. > > The frontend should align record offsets to the stated alignment. > This is the most important thing and is currently broken. Not sure I understand. Do you mean each field should be aligned within the record according to the field's type's alignment? Or are you talking about alignment of the whole record? The only thing I can think of that would not be happening, is giving things alignment larger than the word size. Alignment of a whole record is max of alignment of its fields. There aren't any BITS FOR getting in the ointment are there? Per Modula 3, those never get padded to anything, just put at the next available bit. > If you ask it to do this, you get compilation problems. > This is where the known bugs are. > Everything else has seemed to be working, but we can/should double check. > > The runtime traced allocator should alway align to at least 64. > Maybe 128 on 64bit target. > That is for us to look into and fix if it is broken. > > "segments" are likely already properly aligned by the backend/linker. > But we can for example union them with an int64 and double and possibly int128, > in the m3cc backend. I think they already are strongly enough typed > that it already works though. From my experience debugging i386_cygwin. > > We can investigate the malloc behavior across systems. > However, notice that gcc has -malign-double for x86. > Notice gcc behavior on all the other systems. > Therefore malloc can be assumed to be at least 64-aligned, yes. > But we can check if you are skeptical. > On Windows, heap alignment is in the ABI and adequate. > mmap aligns to at least 4k bytes on all modern systems, often 8k or 64k. > > How do the 64bit targets work today? > Where is the code to ensure they get their 64bit alignment? > Where is the code to ensure even 32bit alignment? > I don't believe Linux/x86 stack has any such guarantee. > We just kinda assume it. > Except, again, we don't really care. > > Repeating: The most important factor is for m3front to layout records. > Again, malloc takes care of whatever the platform needs. > "segments" might need some attention, but this does not change that, really. > Stack can be ignored. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Rodney M. Bates > *Sent:* Friday, April 2, 2021 7:58 PM > *To:* Jay K ; m3devel at elegosoft.com ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > So, you just want the front end to assume that the existence of something in Target.i3 > with 64-bit alignment means those things we discussed will arrive 64-bit aligned and > go with that? > > > > On 4/2/21 2:21 AM, Jay K wrote: >> For what it is worth, I have gone back a few weeks, and things did work. >> >> I386_NT can build and run with the C backend, and the 64bit sized types have 64bit alignment. >> >> There was one semi suspicious change of mine, around unaligned accesses, but things worked either way. >> >> Which agrees with my recollection that x86 and sparc32 worked years ago, and maybe other 32bit targets (ppc32?) >> >> Of course the IR is not super interesting. >> It did change, the swap stuff on store_indirect for >> example, but I think the change is all in m3front >> new enforcements or changed calculations feeding >> into new or same enforcements. >> >> I'll keep digging. >> >> I think it comes down to the addresses of things having "address alignment", >> implied to mean "pointed to", instead of the alignment of the thing pointed to. >> >> For example Formal.m3 seems to confuse this. >> When mode # value, the parameter gets address alignment. >> >> But this is not enough to fix it all. >> >> This is the very confusion you mentioned and I think it persists. >> Like, before the code overloaded align and either got it right, though confusing, >> or enforcements were missing. Now you have tried to clarify it, but either >> got it wrong or added enforcements. Or maybe I am confused. >> >> I do wish I had setup CI long ago to catch this earlier. >> I hope to get to that soon. >> >> - Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* Jay K >> *Sent:* Thursday, April 1, 2021 10:49 PM >> *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org >> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> > But, no matter what M3 source code you feed it, INTERNAL CG ERROR >> > should be prevented by earlier compile errors. >> >> You should be able to see the errors on any host with: >> >> C:\s\cm3\m3-libs\m3core>cm3 -DTARGET=I386_LINUX -DM3_BACKEND_MODE=C -boot -keep -override -DROOT=/s/cm3 >> replace the last parameter as appropriate. >> >> "..\src\float\Common\TextToFloat.m3", line 351: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> "..\src\convert\Convert.m3", line 824: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> >> It isn't really the C backend, except I changed Target.m3 to keep the old alignments for it. >> >> If it doesn't repro there, then also try libm3 and m3middle and m3back (after building m3core), but m3core should suffice, at least to get started. >> >> - Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* M3devel on behalf of Jay K >> *Sent:* Thursday, April 1, 2021 10:38 PM >> *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org >> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> Some of the ABIs I refer to, not all: >> >> x86-32: >> >> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.sco.com%2Fdevelopers%2Fdevspecs%2Fabi386-4.pdf&data=04%7C01%7C%7C72a239ed56454877519e08d8f61a801f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529940967307323%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=0T1efwn2if%2B4E0IEDxp9YW2kjsgE9twRCD1u9HKUCUA%3D&reserved=0 >> The Intel386 architecture does not require doubleword alignment for doubleprecision values. >> Nevertheless, for data structure compatibility with other Intel >> architectures, compilers may provide a method to align double-precision >> values on doubleword boundaries. >> >> mips >> mipsabi32.pdf (sourceforge.net) >> double is 8 aligned >> no mention of int64/longlong. >> >> >> ppc32 >> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmath-atlas.sourceforge.net%2Fdevel%2Fassembly%2Felfspec_ppc.pdf&data=04%7C01%7C%7C72a239ed56454877519e08d8f61a801f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529940967317318%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=v4aseN52FqTAE1C%2F7nkN8MaTsauma2gR3wjm1EPEysc%3D&reserved=0 >> doubles are 8-aligned >> " >> long long (where implemented), and double arguments are considered to have 8-byte >> size and alignment >> " >> >> sparc32 >> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmath-atlas.sourceforge.net%2Fdevel%2Fassembly%2Fabi_sysV_sparc.pdf&data=04%7C01%7C%7C72a239ed56454877519e08d8f61a801f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529940967317318%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=owsLVeOKWk1irSVWeypNJCvkw7AEvhDHrs4fd1pL2yo%3D&reserved=0 >> double is 8-aligned >> no mention of 64bit integers >> >> sparc32 again >> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Ftemlib.org%2Fpub%2FSparcStation%2FStandards%2FV8plus.pdf&data=04%7C01%7C%7C72a239ed56454877519e08d8f61a801f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529940967317318%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=pGa8LARU0xnqgcOGdS5BC%2FIsy75noie0Hatb6XfXhJ8%3D&reserved=0 >> 2.1.3 C ?long long? >> Compare with SysV SPARC ABI, Figure 3-1, p.3-2. >> A C long long is an 8-byte quantity, aligned on an 8-byte boundary. It usually >> occupies the low-order halves of a register pair: LDD and STD (or two LDs and >> STs) are usually used to move a long long; not LDX/STX. If you use LDX/STX, >> you must use a global or out register. >> >> More than this I believe are similar. >> >> - Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* Jay K >> *Sent:* Thursday, April 1, 2021 10:14 PM >> *To:* m3devel at elegosoft.com ; rodney.m.bates at acm.org >> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> I've said it before. >> >> Many 32bit ABIs do align int64 and double to 64bits. >> Just not Linux/x86. I checked several. >> Linux/mips32, Linux/ppc32, etc. like everything except x86 and m68k. >> NT/x86 also 64-aligns the 64bit sized types. >> cm3 is violating many but not all ABIs. >> In terms of RECORD/struct interop. >> >> The underlying native heaps are aligned. They have to be. >> I will check on Linux/x86. >> Win32 heaps are aligned to two pointers. >> Tons of C code would break otherwise. >> The globals are also handled trivially. >> It is true the stack is not always aligned but that is ok. >> It seems wierd, I agree, but that is how C on Win32/x86 works. >> There is a vague idea that you tend not to do atomic operations against stack, just heap and globals. >> >> When we have C like: >> >> struct footype >> { >> int a; >> double d; // or int64 >> }; >> >> Most C compilers, 32bit and 64bit targets, will insert 4 bytes of padding between a and d. >> All Windows compilers will and many Linux ones will. >> >> For many years cm3 did too and it worked. It just recently broke. >> If that were not the case I could not generate portable C for it. >> There are gcc and Visual C++ extensions to break the alignment but I'd really rather not use them. >> >> On the other hand, if cm3 wants padding then it can say like: >> >> struct footype >> { >> int a; >> char padding[4]; >> double d; // or int64 >> }; >> >> and this does give the same layout on all systems. >> >> On the hardware side, perhaps, atomic operations care. >> We don't know which data will be operated on atomically, but it is not usually stack. >> So you use the alignment that atomics require. >> >> i.e. >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fwindows%2Fwin32%2Fapi%2Fwinnt%2Fnf-winnt-interlockedcompareexchange64&data=04%7C01%7C%7C72a239ed56454877519e08d8f61a801f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529940967317318%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=J26jtp%2B%2BR0GoSDn0IJlj1Hnm%2BkHBb8ODD8YjZuCqBrY%3D&reserved=0 >> " >> The variables for this function must be aligned on a 64-bit boundary; >> otherwise, this function will behave unpredictably on multiprocessor >> x86 systems and any non-x86 systems. >> >> See _aligned_malloc. >> " >> >> The last part "See _aligned_malloc" is bogus. There is no need for that. >> I'll try to get that fixed. The regular heap is already aligned enough. >> >> > But, no matter what M3 source code you feed it, INTERNAL CG ERROR >> > should be prevented by earlier compile errors. >> >> It doesn't. >> Pointers to double are considered to have 32bit alignment and storing a double through them does this. >> At least in a few places. >> >> I am not sure what is the point of attempting to track the alignment of what a pointer points to. >> Pointers in C and C++ do not really have this. They either point to a strongly specified type >> and are assumed to have its alignment, or they are void* or char* and you are on your own, >> usually either operating a byte at a time, or eventually casting back to the original type, >> that the pointer was already aligned to, so ok. >> You are also on your own if you cast a pointer amongst types with different alignment, or >> at least to a pointer to a type with greater alignment. >> Granted, I am mixing up IR and source. Perhaps C IR tends to look like this? >> >> Is cm3 going out of its way to track something that is already correct? >> >> - Jay >> >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* Rodney M. Bates >> *Sent:* Thursday, April 1, 2021 9:45 PM >> *To:* Jay K ; m3devel at elegosoft.com >> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >> The compiler can't provide larger alignment than is first provided by >> some other things. The heap allocator must give every heap object the >> maximum alignment of anything. 64-bit alignment on 32 could be pretty >> wasteful, depending on what the application is allocating. The heap >> allocator also would need the same from wherever it gets its heap >> space. The initial stack setup would have to do the same. Same for >> all the sections of object modules and executables, thus the linker >> and loader. The untraced heap is just implemented by using malloc and >> friends, so it would have to do it too. >> >> Then there's the business of aligning the stack on every call. For >> target machines that do runtime stack operands, this would have to be >> done in the back end. The front end could maybe do it at the abstract >> level of the IR, but whether/how that would match the machine >> instruction set is target-dependent. The abstract stack model of the >> IR does not view the operand stack as interspersed with activation >> records, so would have some record-keeping to do. >> >> Unless you can first ensure all target machines, OSs and their tool >> chains would do these things, it is vain to try to get the compiler to >> do it. Or do you want this introduce a new target-dependency? >> >> Tell us again why you want to do this? Is there a 32-bit hardware >> machine that puts a 64-bit alignment requirement on any value of any >> kind? If not, why go to this trouble. >> >> On the subject of cg_align, etc., here is a summary. The front end >> previously had lots of variables named "align" or such that failed to >> distinguish between the alignment of where a value was stored (call >> this "value alignment") and, in the case where the value was an >> address, the alignment of where it pointed, (call this the "address >> alignment"). There were no hints on any alignment field, which it >> meant, and I certainly couldn't confidently follow it all, the way it >> was coded. I attempted to unravel this, with, I believe, at least >> mostly success. >> >> In types/Type.i3.Info, "alignment" was once a mixture, but now is >> value alignment. New field "addr_align" is address alignment. >> >> In CG.m3, these are named "base_align" and "addr_align". I renamed >> the old "align" to "old_align" and maintained its value unchanged, but >> replaced all references to one of the others. Then there is also >> "base_value_align", which, rather confusingly, is the value alignment >> of where the base points, equals the address alignment of the base's >> contents. This intermediate alignment is needed to compute other >> things for some of the address modes of the ValRec. >> >> In values/Variable.m3, preexisting field "align" is value alignment >> and preexisting "cg_align" is address alignment. I believe this may >> have been the original intent, but there were places it was not >> complete. >> >> But, no matter what M3 source code you feed it, INTERNAL CG ERROR >> should be prevented by earlier compile errors. Note that the >> restrictions on packing are now less that before. But some of the >> preexisting ones were not being detected, making things now appear >> more restrictive at compile time. >> >> P.S. Yes, the low-level type system of the IR, like most, doesn't >> give a lot of info about the type of the referent of a pointer. >> However, the referent's address alignments do come through most/all of >> the operators, (always did, assuming they are correct) alongside the >> CG type. >> >> >> On 4/1/21 12:37 AM, Jay K wrote: >>> What are the three alignments here? >>> >>> ELSIF (t.indirect) THEN >>> CG.Comment(-1, TRUE, "Variable load_indirect:align:" & >>> Fmt.Int(t.align) & >>> " cg_align:" & >>> Fmt.Int(t.cg_align) & >>> " type_info.addr_align:" & >>> Fmt.Int(type_info.addr_align)); >>> CG.Load_addr (t.cg_var, t.offset, t.cg_align); >>> CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >>> >>> >>> /* Variable load_indirect:align:64 cg_align:32 type_info.addr_align:8 */ >>> >>> >>> addr_align: Alignment; (* when type=Addr, alignment of VALUE. *) >>> (* NOTE: Originally, field 'align' was highly inconsistent on whether it >>> was the alignment where a value is (or could be) stored, or, when >>> type=Addr, the alignment of where the value pointed. Most calls >>> outside of CG passed in the former, while most uses inside CG >>> expected the latter. This is quite complicated to unravel, so >>> to reduce breakage risk and facilitate fixes thereof, three values >>> are maintained. 'old_align' is as 'align' was. 'base_align' is >>> the former, and 'addr_align' is the latter. It should be possible >>> to eliminate 'old_align' altogether, after ample testing and >>> removal of all uses thereof. *) >>> >>> >>> align became cg_align a few places. Why? >>> What is the difference? >>> Too many things are called align w/o obvious to me why so many. :( >>> >>> commit 9343e3f917bc76672f1f9b9efda80e64ac3895ca >>> Author: Rodney Bates >>> Date: Wed Aug 8 15:10:38 2018 -0500 >>> >>> packedVars branch, initial commit. >>> ... >>> >>> diff --git a/m3-sys/m3front/src/values/Variable.m3 b/m3-sys/m3front/src/values/Variable.m3 >>> index 77064cde0..301e88ccd 100644 >>> --- a/m3-sys/m3front/src/values/Variable.m3 >>> +++ b/m3-sys/m3front/src/values/Variable.m3 >>> >>> @@ -371,29 +373,30 @@ PROCEDURE Load (t: T) = >>> CG.Load_addr_of (t.bss_var, 0, t.cg_align); >>> ELSIF (t.cg_var = NIL) THEN (* => global *) >>> Module.LoadGlobalAddr (Scope.ToUnit (t), t.offset, is_const := FALSE); >>> - CG.Boost_alignment (t.align); >>> + CG.Boost_addr_alignment (t.cg_align); >>> ELSIF (t.indirect) THEN >>> - CG.Load_addr (t.cg_var, t.offset); >>> - CG.Boost_alignment (t.align); >>> + CG.Load_addr (t.cg_var, t.offset, t.cg_align); >>> ELSE >>> CG.Load_addr_of (t.cg_var, t.offset, t.cg_align); >>> END; >>> ELSE (* simple scalar *) >>> . >>> . >>> . >>> - CG.Boost_alignment (t.align); >>> - CG.Load_indirect (t.stk_type, 0, t.size); >>> + CG.Boost_addr_alignment (t.cg_align); >>> + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >>> ELSIF (t.indirect) THEN >>> - CG.Load_addr (t.cg_var, t.offset); >>> - CG.Boost_alignment (t.align); >>> - CG.Load_indirect (t.stk_type, 0, t.size); >>> + CG.Load_addr (t.cg_var, t.offset, t.cg_align); >>> + CG.Load_indirect (t.stk_type, 0, t.size, type_info.addr_align); >>> . >>> . >>> . >>> END Load; >>> @@ -411,11 +414,11 @@ PROCEDURE LoadLValue (t: T) = >>> CG.Load_indirect (CG.Type.Addr, 0, Target.Address.size); >>> END; >>> ELSIF (t.indirect) THEN >>> . >>> . >>> . >>> - CG.Boost_alignment (t.align); >>> + CG.Boost_addr_alignment (t.cg_align); >>> END LoadLValue; >>> PROCEDURE SetLValue (t: T) = >>> @@ -431,7 +434,7 @@ PROCEDURE SetLValue (t: T) = >>> align := CG.Max_alignment; >>> END; >>> <*ASSERT t.indirect *> >>> - CG.Boost_alignment (align); >>> + CG.Boost_addr_alignment (t.cg_align); >>> CG.Store_addr (v, t.offset); >>> END SetLValue; >>> I think that is the problem. >>> >>> Alignment seems like a big mess in the compiler. >>> >>> Btw I'm wrong I think about the typing. >>> I think the parameter could be an indirect double, if m3front would say so. >>> But that is a separate point. >>> >>> - Jay >>> >>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >>> *From:* M3devel on behalf of Jay K >>> *Sent:* Thursday, April 1, 2021 4:13 AM >>> *To:* m3devel at elegosoft.com >>> *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >>> Hm, so the backend interface doesn't have a notion of pointers to types, does it? >>> Just untyped pointers? >>> So needs a lot of work, I suspect. >>> >>> - Jay >>> >>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >>> *From:* Jay K >>> *Sent:* Thursday, April 1, 2021 4:13 AM >>> *To:* m3devel at elegosoft.com >>> *Subject:* INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 >>> This is for I386_FREEBSD with the 64bit types changed to 64bit alignment. >>> >>> PROCEDURE ToBinary ( >>> READONLY source : Buffer; >>> exp1, exp2 : CHAR; >>> VAR tmp : Buffer; >>> VAR used : INTEGER; >>> VAR value : LONGREAL): BOOLEAN = >>> VAR ch: CHAR; eptr: ADDRESS; nchars: INTEGER := NUMBER (source); >>> BEGIN >>> (* copy source to tmp, fix the exponent character and null terminate *) >>> FOR i := 0 TO nchars -1 DO >>> ch := source [i]; >>> IF (ch = exp1) OR (ch = exp2) THEN ch := 'e' END; >>> tmp [i] := ch; >>> END; >>> tmp [nchars] := '\000'; >>> >>> (* finally, do the conversion *) >>> value := strtod (ADR (tmp [0]), eptr); line 824 >>> IF eptr = LOOPHOLE (0, ADDRESS) >>> THEN RETURN FALSE; >>> ELSE used := eptr - ADR (tmp [0]); RETURN TRUE; >>> END; >>> END ToBinary; >>> >>> value unfortunately is void* but that can be ok. >>> With all the casts. Just bad for debugging. >>> >>> /*nil pointer_define*/typedef void* T6B01CD09; >>> >>> UINT8 >>> __cdecl >>> Convert__ToBinary( >>> /* Param_Type 1 */ T7632CB42 /* strong_type1 */ source_L_245, >>> /* Param_Type 1 */ CHAR /* strong_type1 */ exp1_L_246, >>> /* Param_Type 1 */ CHAR /* strong_type1 */ exp2_L_247, >>> /* Param_Type 1 */ T7632CB42 /* strong_type1 */ tmp_L_248, >>> /* Param_Type 1 */ TE6A3D58B /* strong_type1 */ used_L_249, >>> /* Param_Type 1 */ T6B01CD09 /* strong_type1 */ value_L_250) >>> . >>> . >>> . >>> >>> #line 824 "../src/convert/Convert.m3" >>> (*(double*)(&L_600_L_601))=(double)(((double)(m3_strtod( >>> /* call_helper t1 */ ( /* call_helper t2 */ ADDRESS /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)((((ADDRESS)(*((ADDRESS*)(tmp_L_248))))+( /* cast_removed2: (INT32) */ L_598_L_599)))) /* call_helper t4 */ ), >>> /* call_helper t1 */ ( /* call_helper t2 */ TF7BFDF9C /* strong_type1 */ /* call_helper t3 */ )(((ADDRESS)(&eptr_L_242)) /* call_helper t4 */ ))))); >>> #line 824 "../src/convert/Convert.m3" >>> /* load var:value_L_250 offset:0 in_mtype:ADDRESS out_ztype:ADDRESS */ >>> #line 824 "../src/convert/Convert.m3" >>> /* load var:L_600_L_601 offset:0 in_mtype:double out_ztype:double */ >>> #line 824 "../src/convert/Convert.m3" >>> /* ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 */ <== Why this? >>> #line 824 "../src/convert/Convert.m3" >>> /* store_indirect offset:0 ztype:double mtype:double */ >>> #line 824 "../src/convert/Convert.m3" >>> (*(double*)(value_L_250))=(double)( /* cast_removed2: (double) */ L_600_L_601); >>> #line 824 "../src/convert/Convert.m3" >>> #line 825 "../src/convert/Convert.m3" >>> >>> Because "address" (which really should be double*) has some implied insufficient alignment? >>> >>> I'll dig a bit more. I think I am close. >>> >>> Thank you, >>> - Jay >>> >>> _______________________________________________ >>> M3devel mailing list >>> M3devel at elegosoft.com >>> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C72a239ed56454877519e08d8f61a801f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529940967317318%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=2hANRl8z%2F09A7Kbm6Rul1h%2BJ8x4fE6SnUpe382BXrmo%3D&reserved=0 >>> >> >> -- >> Rodney Bates >> rodney.m.bates at acm.org >> >> _______________________________________________ >> M3devel mailing list >> M3devel at elegosoft.com >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C72a239ed56454877519e08d8f61a801f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529940967327314%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=l1vRwq2w8tlfD6Y0T%2FkGB8yMPpoLpBWbUmG9CorviDc%3D&reserved=0 >> > > -- > Rodney Bates > rodney.m.bates at acm.org > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C72a239ed56454877519e08d8f61a801f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637529940967327314%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=l1vRwq2w8tlfD6Y0T%2FkGB8yMPpoLpBWbUmG9CorviDc%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Sat Apr 3 17:28:35 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 3 Apr 2021 10:28:35 -0500 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: Message-ID: On 4/2/21 2:21 AM, Jay K wrote: > For what it is worth, I have gone back a few weeks, and things did work. > > I386_NT can build and run with the C backend, and the 64bit sized types have 64bit alignment. > > There was one semi suspicious change of mine, around unaligned accesses, but things worked either way. > > Which agrees with my recollection that x86 and sparc32 worked years ago, and maybe other 32bit targets (ppc32?) > > Of course the IR is not super interesting. > It did change, the swap stuff on store_indirect for > example, but I think the change is all in m3front > new enforcements or changed calculations feeding > into new or same enforcements. > > I'll keep digging. > > I think it comes down to the addresses of things having "address alignment", > implied to mean "pointed to", instead of the alignment of the thing pointed to. > > For example Formal.m3 seems to confuse this. > When mode # value, the parameter gets address alignment. VAR and READONLY parameters are always passed by reference at the low level, so should always have value alignment of address. But the addr_align of the formal should be the type alignment of the formal's high-level declared type. Another distinction I added is between the alignment of a type, and that of an expression, which can sometimes be more generous than that of its type. I recall at the time thinking I was being rather magnanimous in giving A[0] an expression alignment of word, when A is a heap-allocated open array of, say, CHAR. In general, A[I] can only be depended-on to have 8-bit alignment. In looking at the case in Convert.m3, it appears I have done this for an open array formal, which is not necessarily true. Not apparently relevant to the Convert problem. > > But this is not enough to fix it all. > > This is the very confusion you mentioned and I think it persists. > Like, before the code overloaded align and either got it right, though confusing, > or enforcements were missing. Now you have tried to clarify it, but either > got it wrong or added enforcements. Or maybe I am confused. > > I do wish I had setup CI long ago to catch this earlier. > I hope to get to that soon. > > ?- Jay > > -- Rodney Bates rodney.m.bates at acm.org From rodney_bates at lcwb.coop Sat Apr 3 17:33:29 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 3 Apr 2021 10:33:29 -0500 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: Message-ID: On 4/2/21 4:13 PM, Jay K wrote: > I don't believe there are any BITS for here. > > I mean, m3front is surely correctly aligning > things within records, but it the request for that, > that leads to these internal errors. > > I mean, I want to be able to give int64 and double, > 64bit alignment, and successfully compile without internal > errors. > > It is alignment within records that most of all I need to be > 64 for the 64bit sized types, even on 32bit target. > > Can you try: > ?cd scripts/python > ?./upgrade.py > ?./boot1.py i386_linux c keep commands My build problem is not build procedure. It's manually repairing file damage after a disk fill-up. > > Or if you are certain you have an up to date compiler, then just the last. > For i386_linux you can substitute others like i386_nt. > > ./upgrade.py just rebuilds the compiler, and then rebuilds with itself. Overkill for this exercise. > > Alternatively: > ?cd scripts/python > ?./do-pk.py m3middle m3back cm3 build && ./install-cm3-compiler.py > > When you are done, to cleanup: > ?./do-cm3-all i386_linux realclean > ?rm -rf cm3-boot- > > ?- Jay > > --- Rodney Bates rodney.m.bates at acm.org From rodney_bates at lcwb.coop Sat Apr 3 17:55:28 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 3 Apr 2021 10:55:28 -0500 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: Message-ID: <75df8617-18b4-e5c5-30bd-0438bc1afe23@lcwb.coop> On 4/2/21 3:21 PM, Jay K wrote: > Not exactly. > > The frontend should align record offsets to the stated alignment. > This is the most important thing and is currently broken. > If you ask it to do this, you get compilation problems. > This is where the known bugs are. > Everything else has seemed to be working, but we can/should double check. > > The runtime traced allocator should alway align to at least 64. > Maybe 128 on 64bit target. > That is for us to look into and fix if it is broken. > > "segments" are likely already properly aligned by the backend/linker. > But we can for example union them with an int64 and double and possibly int128, > in the m3cc backend. I think they already are strongly enough typed > that it already works though. From my experience debugging i386_cygwin. > > We can investigate the malloc behavior across systems. > However, notice that gcc has -malign-double for x86. > Notice gcc behavior on all the other systems. > Therefore malloc can be assumed to be at least 64-aligned, yes. > But we can check if you are skeptical. > On Windows, heap alignment is in the ABI and adequate. > mmap aligns to at least 4k bytes on all modern systems, often 8k or 64k. So how about giving Target.i3 a new value, maybe "platformAlign", that is an alignment that the compiler can assume the surrounding environment will give to segments etc. It would be (perhaps a multiple of) 64 on 32-bit targets where that is true, and 32 otherwise. The front end and heap allocator could then over-align to 64 on 32-bit targets, only where platformAlign was a multiple of 64. As for the stack, the abstract operand stack of the IR really carries no implication that its operands are interspersed with activation records. Only a back end can really know what it has done to runtime stack alignment. Even if the IR were keeping track of this, there is no necessary correlation between its stack operands and those of a particular hardware instruction set. So that really has to be left up to the back ends. But it does need to be checked. > > How do the 64bit targets work today? > Where is the code to ensure they get their 64bit alignment? > Where is the code to ensure even 32bit alignment? > I don't believe Linux/x86 stack has any such guarantee. > We just kinda assume it. > Except, again, we don't really care. > > Repeating: The most important factor is for m3front to layout records. > Again, malloc takes care of whatever the platform needs. > "segments" might need some attention, but this does not change that, really. > Stack can be ignored. > > ?- Jay > > -- Rodney Bates rodney.m.bates at acm.org From rodney_bates at lcwb.coop Sat Apr 3 18:07:46 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 3 Apr 2021 11:07:46 -0500 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: Message-ID: On 4/2/21 3:21 PM, Jay K wrote: > Not exactly. > > The frontend should align record offsets to the stated alignment. > This is the most important thing and is currently broken. Do you have an example case? > If you ask it to do this, you get compilation problems. I don't understand what you mean by "ask it to do this". Without reproducing anything, just looking at some of the snippets of evidence and existing code, it appears the front end is picking up over-alignment (i.e., larger than target word) from scalar types in Target.i3, but not always propagating these through expressions when they exceed word size. The Convert.m3 case (which, BTW, I have not been able to reproduce, so far) looks like an internally-generated temp for a LONGREAL only got 32. > This is where the known bugs are. > Everything else has seemed to be working, but we can/should double check. > > The runtime traced allocator should alway align to at least 64. > Maybe 128 on 64bit target. > That is for us to look into and fix if it is broken. > > "segments" are likely already properly aligned by the backend/linker. > But we can for example union them with an int64 and double and possibly int128, > in the m3cc backend. I think they already are strongly enough typed > that it already works though. From my experience debugging i386_cygwin. > > We can investigate the malloc behavior across systems. > However, notice that gcc has -malign-double for x86. > Notice gcc behavior on all the other systems. > Therefore malloc can be assumed to be at least 64-aligned, yes. > But we can check if you are skeptical. > On Windows, heap alignment is in the ABI and adequate. > mmap aligns to at least 4k bytes on all modern systems, often 8k or 64k. > > How do the 64bit targets work today? > Where is the code to ensure they get their 64bit alignment? > Where is the code to ensure even 32bit alignment? > I don't believe Linux/x86 stack has any such guarantee. > We just kinda assume it. > Except, again, we don't really care. > > Repeating: The most important factor is for m3front to layout records. > Again, malloc takes care of whatever the platform needs. > "segments" might need some attention, but this does not change that, really. > Stack can be ignored. > > ?- Jay > > -- Rodney Bates rodney.m.bates at acm.org From rodney_bates at lcwb.coop Sat Apr 3 19:09:04 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 3 Apr 2021 12:09:04 -0500 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: <75df8617-18b4-e5c5-30bd-0438bc1afe23@lcwb.coop> References: <75df8617-18b4-e5c5-30bd-0438bc1afe23@lcwb.coop> Message-ID: On 4/3/21 10:55 AM, Rodney M. Bates wrote: > > > On 4/2/21 3:21 PM, Jay K wrote: >> Not exactly. >> >> The frontend should align record offsets to the stated alignment. >> This is the most important thing and is currently broken. >> If you ask it to do this, you get compilation problems. >> This is where the known bugs are. >> Everything else has seemed to be working, but we can/should double check. >> >> The runtime traced allocator should alway align to at least 64. >> Maybe 128 on 64bit target. >> That is for us to look into and fix if it is broken. >> >> "segments" are likely already properly aligned by the backend/linker. >> But we can for example union them with an int64 and double and possibly int128, >> in the m3cc backend. I think they already are strongly enough typed >> that it already works though. From my experience debugging i386_cygwin. >> >> We can investigate the malloc behavior across systems. >> However, notice that gcc has -malign-double for x86. >> Notice gcc behavior on all the other systems. >> Therefore malloc can be assumed to be at least 64-aligned, yes. >> But we can check if you are skeptical. >> On Windows, heap alignment is in the ABI and adequate. >> mmap aligns to at least 4k bytes on all modern systems, often 8k or 64k. > > So how about giving Target.i3 a new value, maybe "platformAlign", that is > an alignment that the compiler can assume the surrounding environment > will give to segments etc. It would be (perhaps a multiple of) 64 on > 32-bit targets where that is true, and 32 otherwise.? The front end and > heap allocator could then over-align to 64 on 32-bit targets, only where > platformAlign was a multiple of 64. Or is this just entirely redundant? Just compute the maximum alignment of any type in Target.m3 and use that? The RTS won't be able to access Target.i3. Does it have some kind of configuration mechanism available? > > As for the stack, the abstract operand stack of the IR really carries > no implication that its operands are interspersed with activation > records.? Only a back end can really know what it has done to runtime > stack alignment.? Even if the IR were keeping track of this, there is no > necessary correlation between its stack operands and those of a particular > hardware instruction set.? So that really has to be left up to the > back ends. But it does need to be checked. > >> >> How do the 64bit targets work today? >> Where is the code to ensure they get their 64bit alignment? >> Where is the code to ensure even 32bit alignment? >> I don't believe Linux/x86 stack has any such guarantee. >> We just kinda assume it. >> Except, again, we don't really care. >> >> Repeating: The most important factor is for m3front to layout records. >> Again, malloc takes care of whatever the platform needs. >> "segments" might need some attention, but this does not change that, really. >> Stack can be ignored. >> >> ??- Jay >> >> -- Rodney Bates rodney.m.bates at acm.org From jayk123 at hotmail.com Sat Apr 3 19:49:20 2021 From: jayk123 at hotmail.com (Jay K) Date: Sat, 3 Apr 2021 17:49:20 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: , Message-ID: > VAR and READONLY parameters are always passed by reference at the low Separate question: Always? READONLY by reference even if "small"? The code in Formal looks wrong to me, but I think it was always that way. You know, your changes are large and intertwined, which is ok, but then I cannot easily or at all pin the problem on a small bit of code or change. > Another distinction I added is between the alignment of a type, and that of > an expression, which can sometimes be more generous than that of its type. > I recall at the time thinking I was being rather magnanimous in giving A[0] > an expression alignment of word, when A is a heap-allocated open array > of, say, CHAR This makes sense to me, but is it valuable? Does it enable m3front to generate different code? Like, zero'ing of multiple char array elements at a time or such? - Jay ________________________________ From: Rodney M. Bates Sent: Saturday, April 3, 2021 3:28 PM To: Jay K ; m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 On 4/2/21 2:21 AM, Jay K wrote: > For what it is worth, I have gone back a few weeks, and things did work. > > I386_NT can build and run with the C backend, and the 64bit sized types have 64bit alignment. > > There was one semi suspicious change of mine, around unaligned accesses, but things worked either way. > > Which agrees with my recollection that x86 and sparc32 worked years ago, and maybe other 32bit targets (ppc32?) > > Of course the IR is not super interesting. > It did change, the swap stuff on store_indirect for > example, but I think the change is all in m3front > new enforcements or changed calculations feeding > into new or same enforcements. > > I'll keep digging. > > I think it comes down to the addresses of things having "address alignment", > implied to mean "pointed to", instead of the alignment of the thing pointed to. > > For example Formal.m3 seems to confuse this. > When mode # value, the parameter gets address alignment. VAR and READONLY parameters are always passed by reference at the low level, so should always have value alignment of address. But the addr_align of the formal should be the type alignment of the formal's high-level declared type. Another distinction I added is between the alignment of a type, and that of an expression, which can sometimes be more generous than that of its type. I recall at the time thinking I was being rather magnanimous in giving A[0] an expression alignment of word, when A is a heap-allocated open array of, say, CHAR. In general, A[I] can only be depended-on to have 8-bit alignment. In looking at the case in Convert.m3, it appears I have done this for an open array formal, which is not necessarily true. Not apparently relevant to the Convert problem. > > But this is not enough to fix it all. > > This is the very confusion you mentioned and I think it persists. > Like, before the code overloaded align and either got it right, though confusing, > or enforcements were missing. Now you have tried to clarify it, but either > got it wrong or added enforcements. Or maybe I am confused. > > I do wish I had setup CI long ago to catch this earlier. > I hope to get to that soon. > > - Jay > > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sat Apr 3 20:39:11 2021 From: jayk123 at hotmail.com (Jay K) Date: Sat, 3 Apr 2021 18:39:11 +0000 Subject: [M3devel] m3front ultimately to not do layout (optionally) Message-ID: Just to be clear, ultimately, I'd like m3front to issue references to array indices and record fields, not base + m3front-computed-offset + cast. m3front would also no longer know the sizes of aggregates (arrays & records) in this scheme. It'd be up to the backend. C backend could just say "sizeof(x)" and leave it to the C compiler to compute. That would moot present discussions of alignment mostly or entirely. But in order to get their incrementally and as insurance against large changes not actually happening, I'd like to get the old way back to working first. At the same time though, existing backends could work. That is, m3front would optionally work the new way. Like, every array element or record element reference would be something like: record_field_access(base, offset, name, type) array_element_access(base, offset, index, type) and backends would use either offset or name/index. The first or all versions might even assert an equivalence, which should be trivial. Type would be redundant in the new mode, or, again asserted. Read vs. write might be separate calls. Backends are "stackable". So maybe we'd "stack in" a backend that convert these to just base + offset + cast for the existing backends. Or each backend would advertise which calls it understands and m3front/CG would decide. Besides the C backend, I believe LLVM could use this. Ultimately I'd like m3front to not know word size or endian, and C backend output to be independnet of them, but this might not be achievable. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sat Apr 3 23:11:37 2021 From: jayk123 at hotmail.com (Jay K) Date: Sat, 3 Apr 2021 21:11:37 +0000 Subject: [M3devel] version.quake: In the LLVM9 copy, remove a bunch o... In-Reply-To: References: , <20210323174321.ah4mradi4mhyw6qx@topoi.pooq.com>, Message-ID: version:Add git info. by jaykrell ? Pull Request #300 ? modula3/cm3 (github.com) ________________________________ From: Jay K Sent: Tuesday, March 23, 2021 7:35 PM To: Hendrik Boom ; m3devel at elegosoft.com Subject: Re: [M3devel] version.quake: In the LLVM9 copy, remove a bunch o... Agreed & understood. Perhaps we should do the hash all the sources thing. We could stamp that into everything we link, hypothetically. But might be worth it and can just do the first -- nothing. Or could use git hash if we can detect git is there. We could also try to make a habit of updating scripts/version.quake "more often", which makes for an approximate but repeatable timestamp. - Jay ________________________________ From: M3devel on behalf of Hendrik Boom Sent: Tuesday, March 23, 2021 5:43 PM To: m3devel at elegosoft.com Subject: Re: [M3devel] version.quake: In the LLVM9 copy, remove a bunch o... On Tue, Mar 23, 2021 at 06:46:56AM +0000, Jay K wrote: > Fyi, in this change I accidentally removed the behavior where, every time you build, the source is always out of date, and it rebuilds. Every time. I think it worked that way, at least, because of the "now" invocation. > > But maybe not, since the result was not later used. > > I suppose that is ok, or even good, but there are tradeoffs. Some people like builds to be non-repeatable and always produce something "fresh". > cm3 is still that way..and we should probably undo it. > We should probably use the git hash instead. Except that doesn't work if you just have a .targz of source. > > - Jay So you want to mark the build uniquely and still be reproducible. The git hash won't do: I might not have a git repository at all. I usually don't when I program because I use a different revision management system. Time of day sounds good enough for normal use, but is not reproducible.. But You can have reproducible buids with a compiler option that specifies: either * absent altogether (reproducible) * computed deterministically by hashing * the source code being compiled (reproducible) * or the source code modification dates (less reproducible; dates may change without any change of contents; this might happen when unpacking an archive) * provided as a compile-time CLI parameter (very reproducible). -- hendrik _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C2b4a66f80a9b4253a49008d8ee2336bd%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637521182305875322%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=XuPPP7hBFJFbwA6Id%2BGO0Xo5zzCnZHjyBTQ%2Bgymv6SY%3D&reserved=0 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sat Apr 3 23:15:09 2021 From: jayk123 at hotmail.com (Jay K) Date: Sat, 3 Apr 2021 21:15:09 +0000 Subject: [M3devel] version.quake: In the LLVM9 copy, remove a bunch o... In-Reply-To: References: , <20210323174321.ah4mradi4mhyw6qx@topoi.pooq.com>, , Message-ID: If the git info is available, this no longer recompiles and relinks every time you build cm3. So it is deterministic or less non-deterministic, if the git info is available. Ideally the git info is kept up to date in a text file like version.quake. Or, far more work, a good hash of the inputs (including the compiler, linker, C runtime, etc....so much) - Jay ________________________________ From: Jay K Sent: Saturday, April 3, 2021 9:11 PM To: Hendrik Boom ; m3devel at elegosoft.com Subject: Re: [M3devel] version.quake: In the LLVM9 copy, remove a bunch o... version:Add git info. by jaykrell ? Pull Request #300 ? modula3/cm3 (github.com) ________________________________ From: Jay K Sent: Tuesday, March 23, 2021 7:35 PM To: Hendrik Boom ; m3devel at elegosoft.com Subject: Re: [M3devel] version.quake: In the LLVM9 copy, remove a bunch o... Agreed & understood. Perhaps we should do the hash all the sources thing. We could stamp that into everything we link, hypothetically. But might be worth it and can just do the first -- nothing. Or could use git hash if we can detect git is there. We could also try to make a habit of updating scripts/version.quake "more often", which makes for an approximate but repeatable timestamp. - Jay ________________________________ From: M3devel on behalf of Hendrik Boom Sent: Tuesday, March 23, 2021 5:43 PM To: m3devel at elegosoft.com Subject: Re: [M3devel] version.quake: In the LLVM9 copy, remove a bunch o... On Tue, Mar 23, 2021 at 06:46:56AM +0000, Jay K wrote: > Fyi, in this change I accidentally removed the behavior where, every time you build, the source is always out of date, and it rebuilds. Every time. I think it worked that way, at least, because of the "now" invocation. > > But maybe not, since the result was not later used. > > I suppose that is ok, or even good, but there are tradeoffs. Some people like builds to be non-repeatable and always produce something "fresh". > cm3 is still that way..and we should probably undo it. > We should probably use the git hash instead. Except that doesn't work if you just have a .targz of source. > > - Jay So you want to mark the build uniquely and still be reproducible. The git hash won't do: I might not have a git repository at all. I usually don't when I program because I use a different revision management system. Time of day sounds good enough for normal use, but is not reproducible.. But You can have reproducible buids with a compiler option that specifies: either * absent altogether (reproducible) * computed deterministically by hashing * the source code being compiled (reproducible) * or the source code modification dates (less reproducible; dates may change without any change of contents; this might happen when unpacking an archive) * provided as a compile-time CLI parameter (very reproducible). -- hendrik _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C2b4a66f80a9b4253a49008d8ee2336bd%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637521182305875322%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=XuPPP7hBFJFbwA6Id%2BGO0Xo5zzCnZHjyBTQ%2Bgymv6SY%3D&reserved=0 -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Sun Apr 4 19:12:01 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sun, 4 Apr 2021 12:12:01 -0500 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: Message-ID: <7afe431f-a0e8-682a-ed1b-c5b4d1a1de24@lcwb.coop> On 4/3/21 12:49 PM, Jay K wrote: > ?> VAR and READONLY parameters are always passed by reference at the low > > Separate question: Always? READONLY by reference even if "small"? From 2.3.2: "A READONLY formal is treated as a VAR formal if the actual is a designator and the type of the actual is the same as the type of the formal (or an array type that is assignable to the type of the formal); otherwise it is treated as a VALUE formal." Note no mention of size. Since the high-level mode is sometimes reference, sometimes value, depending on properties of the actual, the only reasonable implementation is that at the low level, it always passes a pointer. For an actual that requires pass-by-value, the code at the call site makes a copy and passes the pointer to that. Regardless of the size Also, from 2.3.2: "Implementations are allowed to forbid \verb|VAR| or \verb|READONLY| parameters of packed types." which the front end does. Otherwise would require a really messy implementation. > The code in Formal looks wrong to me, but I think it was always that way. It's been reworked. It had some flaws for various combinations of type, mode, packedness, kind of actual, runtime errors. Confusingly, though the module is named Formal, it is doing the compiling of actual parameters. > You know, your changes are large and intertwined, which is ok, but then I cannot easily or at all pin the problem on a small bit of code or change. > > ?> Another distinction I added is between the alignment of a type, and that of > ?> an expression, which can sometimes be more generous than that of its type. > ?> I recall at the time thinking I was being rather magnanimous in giving A[0] > ?> an expression alignment of word, when A is a heap-allocated open array > ?> of, say, CHAR > > ?This makes sense to me, but is it valuable? > ?Does it enable m3front to generate different code? Yes. Like simple fetch and store, if, as usual, it is normally sized and aligned. > ?Like, zero'ing of multiple char array elements at a time or such? > Not sure if this one happens, but the distinction would be necessary to do so. > ?- Jay > > - -- Rodney Bates rodney.m.bates at acm.org From jayk123 at hotmail.com Sun Apr 4 22:58:58 2021 From: jayk123 at hotmail.com (Jay K) Date: Sun, 4 Apr 2021 20:58:58 +0000 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: <7afe431f-a0e8-682a-ed1b-c5b4d1a1de24@lcwb.coop> References: , <7afe431f-a0e8-682a-ed1b-c5b4d1a1de24@lcwb.coop> Message-ID: So passing a READONLY INTEGER is by pointer, with the understanding that the callee won't write throug it, but passing a plain INTEGER is not? > "Implementations are allowed to forbid > \verb|VAR| or \verb|READONLY| parameters > of packed types." Good. So any pointer across a function call boundary can only be assumed to be well aligned. >> The code in Formal looks wrong to me, but I think it was always that way. > It's been reworked. Specifically this is suspicious: IF t.mode # Mode.mVALUE OR t.openArray THEN (* lo-level pass by reference. *) size := Target.Address.size; align := Target.Address.align; mtype := CG.Type.Addr; I understand the three alignments: where pointer value must be stored, i.e. word where pointer value is stored, i.e. possibly more than word what pointer points to But if there can only be one, then it should be the last, eh? I think this might be part of the problems but I am not sure. i.e. a pointer to longreal should have 64 alignment. > Yes. Like simple fetch and store, if, as usual, it is normally sized and aligned. Aha. So conceptually there is: struct { volatile a : 1; volatile b : 1; }; which to me is mostly a bad idea. Because accesses to a will access b. However it does have a possible use. It should maybe imply I think atomic. On x86 you can even use lock bts/btc. struct { volatile a : 8; volatile b : 8; }; isn't so bad. It means be sure to use byte accesses to a or b. I realize volatile is its own complex matter and should be avoided. - Jay ________________________________ From: Rodney M. Bates Sent: Sunday, April 4, 2021 5:12 PM To: Jay K ; m3devel at elegosoft.com ; rodney.m.bates at acm.org Subject: Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 On 4/3/21 12:49 PM, Jay K wrote: > > VAR and READONLY parameters are always passed by reference at the low > > Separate question: Always? READONLY by reference even if "small"? From 2.3.2: "A READONLY formal is treated as a VAR formal if the actual is a designator and the type of the actual is the same as the type of the formal (or an array type that is assignable to the type of the formal); otherwise it is treated as a VALUE formal." Note no mention of size. Since the high-level mode is sometimes reference, sometimes value, depending on properties of the actual, the only reasonable implementation is that at the low level, it always passes a pointer. For an actual that requires pass-by-value, the code at the call site makes a copy and passes the pointer to that. Regardless of the size Also, from 2.3.2: "Implementations are allowed to forbid \verb|VAR| or \verb|READONLY| parameters of packed types." which the front end does. Otherwise would require a really messy implementation. > The code in Formal looks wrong to me, but I think it was always that way. It's been reworked. It had some flaws for various combinations of type, mode, packedness, kind of actual, runtime errors. Confusingly, though the module is named Formal, it is doing the compiling of actual parameters. > You know, your changes are large and intertwined, which is ok, but then I cannot easily or at all pin the problem on a small bit of code or change. > > > Another distinction I added is between the alignment of a type, and that of > > an expression, which can sometimes be more generous than that of its type. > > I recall at the time thinking I was being rather magnanimous in giving A[0] > > an expression alignment of word, when A is a heap-allocated open array > > of, say, CHAR > > This makes sense to me, but is it valuable? > Does it enable m3front to generate different code? Yes. Like simple fetch and store, if, as usual, it is normally sized and aligned. > Like, zero'ing of multiple char array elements at a time or such? > Not sure if this one happens, but the distinction would be necessary to do so. > - Jay > > - -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Mon Apr 5 01:27:32 2021 From: jayk123 at hotmail.com (Jay K) Date: Sun, 4 Apr 2021 23:27:32 +0000 Subject: [M3devel] g++ -g undermines m3gdb In-Reply-To: References: , Message-ID: ok. I can build m3gdb on Ubuntu 1604 no problem and I can see the behavior w/ -g vs. -gstabs+ For example, run cm3, break on open, on the second call, go up or fin, and print the path name. Either works (-gstabs+) or fails an assert in m3gdb (-g). Presumably I can come up with some other fix, but depends, like, what symbols are preserved and what m3gdb looks for. Like, maybe just volatile char INTEGER? will work. I'll fiddle around. It'd probably also work to compile _m3main.c with -gstabus+. To be clear, m3gdb does not compile out of the box on Ubuntu 20.04. I didn't try others. - Jay ________________________________ From: Jay K Sent: Tuesday, March 30, 2021 6:24 PM To: m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb When I used gcc -gstabs I got incorrect symbols for C. I spent a while debugging the C thinking it was incorrect only to later realize the problem was the symbols. At least with the current Debian gcc, not with the current mainline gcc. Gcc developers would like to remove stabs support, as well. That was the response to the bug report (and that it no longer repros). 99457 ? gcc/gdb -gstabs+ is buggy. (gnu.org) If that ever happens, then what? So I don't know what to do. It is bad either way. Since I don't use m3cc or m3gdb, it could be dependent on backend mode?? That's a little gross but might keep everyone productive. - Jay ________________________________ From: M3devel on behalf of Rodney M. Bates Sent: Tuesday, March 30, 2021 6:16 PM To: m3devel Subject: [M3devel] g++ -g undermines m3gdb -> linking prog generate _m3main.c g++ -g -m64 -fPIC -g -c -xc++ _m3main.c -o _m3main.o This undermines m3gdb. m3gdb looks for certain stabs definitions that occur in every main program to ascertain what compiler (especially, pm3 vs. cm3) compiled it. With a mixture of dwarf for _m3main.c and stabs for everything else, it can't find what it needs. gcc -g -m64 -fPIC -fuse-ld=gold -Wl,-z,now -Wl,-z,origin -Bsymbolic -Wl,--fatal-warnings -Wl,-rpath,\$ORIGIN -Wl,-rpath,\$ORIGIN/../lib -Wl,--warn-common -Wl,-rpath,/usr/local/cm3/bin/../lib -o prog _m3main.o Main_m.o -L/usr/local/cm3/pkg/libm3/AMD64_LINUX -lm3 -L/usr/local/cm3/pkg/m3core/AMD64_LINUX -lm3core -lm -pthread -- Rodney Bates rodney.m.bates at acm.org _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C8f6cca20fd774c27b8a208d8f3a7fcb6%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637527250111222123%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=mMxC4P0yApuTpVLFfZtIhuQG%2FTBEETIlinS9eP9OhOE%3D&reserved=0 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Mon Apr 5 05:30:15 2021 From: jayk123 at hotmail.com (Jay K) Date: Mon, 5 Apr 2021 03:30:15 +0000 Subject: [M3devel] g++ -g undermines m3gdb In-Reply-To: References: , , Message-ID: Ugh, so the symbols are maybe there, but our gdb is too old to read Dwarf. commit c20a30f9de9bb90e16aac378cdca095e3372fe02 Author: Rodney Bates Date: Sat Jun 6 12:16:37 2015 -0500 Add some dwarf4 codes. gcc 4.8.1 emits these even when -gdwarf2 is supplied. This is a first attempt to get m3gdb to handle these. It is not complete. diff --git a/m3-sys/m3gdb/gdb/gdb/dwarf2read.c b/m3-sys/m3gdb/gdb/gdb/dwarf2read.c index 883fa43f7..5183322b0 100644 --- a/m3-sys/m3gdb/gdb/gdb/dwarf2read.c +++ b/m3-sys/m3gdb/gdb/gdb/dwarf2read.c @@ -53,6 +53,7 @@ #include "gdb_string.h" #include "gdb_assert.h" #include +#include /* A note on memory usage for this file. @@ -1168,6 +1169,9 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr) void dwarf2_build_psymtabs (struct objfile *objfile, int mainline) { + + return; /* Temporary. */ + Maybe I just give up and put m3main back as m3cc IR instead of C. I was just trying to reduce configurations/modes at the time. It also hypothetically skips C++ static constructors but probably not in reality. (On ancient systems, cfront would insert code in main to call them, I gather, I've never seen it.) I am trying to update the Dwarf handling..and it starts out easy..but doesn't clearly remain so. - Jay ________________________________ From: Jay K Sent: Sunday, April 4, 2021 11:27 PM To: m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb ok. I can build m3gdb on Ubuntu 1604 no problem and I can see the behavior w/ -g vs. -gstabs+ For example, run cm3, break on open, on the second call, go up or fin, and print the path name. Either works (-gstabs+) or fails an assert in m3gdb (-g). Presumably I can come up with some other fix, but depends, like, what symbols are preserved and what m3gdb looks for. Like, maybe just volatile char INTEGER? will work. I'll fiddle around. It'd probably also work to compile _m3main.c with -gstabus+. To be clear, m3gdb does not compile out of the box on Ubuntu 20.04. I didn't try others. - Jay ________________________________ From: Jay K Sent: Tuesday, March 30, 2021 6:24 PM To: m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb When I used gcc -gstabs I got incorrect symbols for C. I spent a while debugging the C thinking it was incorrect only to later realize the problem was the symbols. At least with the current Debian gcc, not with the current mainline gcc. Gcc developers would like to remove stabs support, as well. That was the response to the bug report (and that it no longer repros). 99457 ? gcc/gdb -gstabs+ is buggy. (gnu.org) If that ever happens, then what? So I don't know what to do. It is bad either way. Since I don't use m3cc or m3gdb, it could be dependent on backend mode?? That's a little gross but might keep everyone productive. - Jay ________________________________ From: M3devel on behalf of Rodney M. Bates Sent: Tuesday, March 30, 2021 6:16 PM To: m3devel Subject: [M3devel] g++ -g undermines m3gdb -> linking prog generate _m3main.c g++ -g -m64 -fPIC -g -c -xc++ _m3main.c -o _m3main.o This undermines m3gdb. m3gdb looks for certain stabs definitions that occur in every main program to ascertain what compiler (especially, pm3 vs. cm3) compiled it. With a mixture of dwarf for _m3main.c and stabs for everything else, it can't find what it needs. gcc -g -m64 -fPIC -fuse-ld=gold -Wl,-z,now -Wl,-z,origin -Bsymbolic -Wl,--fatal-warnings -Wl,-rpath,\$ORIGIN -Wl,-rpath,\$ORIGIN/../lib -Wl,--warn-common -Wl,-rpath,/usr/local/cm3/bin/../lib -o prog _m3main.o Main_m.o -L/usr/local/cm3/pkg/libm3/AMD64_LINUX -lm3 -L/usr/local/cm3/pkg/m3core/AMD64_LINUX -lm3core -lm -pthread -- Rodney Bates rodney.m.bates at acm.org _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C8f6cca20fd774c27b8a208d8f3a7fcb6%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637527250111222123%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=mMxC4P0yApuTpVLFfZtIhuQG%2FTBEETIlinS9eP9OhOE%3D&reserved=0 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Mon Apr 5 06:00:54 2021 From: jayk123 at hotmail.com (Jay K) Date: Mon, 5 Apr 2021 04:00:54 +0000 Subject: [M3devel] g++ -g undermines m3gdb In-Reply-To: References: , , , Message-ID: Good enough? m3gdb: Some reading of Dwarf symbols so that g++ -g _m3main.c works. by jaykrell ? Pull Request #317 ? modula3/cm3 (github.com) I realize it is a bit hazardous..would be better to make the reading really work, or to alway skip the locdesc. Or _m3main.c could go back through m3cg as I said. Heck, even through the C backend, it'd be nice to see how that compares. ? - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Monday, April 5, 2021 3:30 AM To: m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb Ugh, so the symbols are maybe there, but our gdb is too old to read Dwarf. commit c20a30f9de9bb90e16aac378cdca095e3372fe02 Author: Rodney Bates Date: Sat Jun 6 12:16:37 2015 -0500 Add some dwarf4 codes. gcc 4.8.1 emits these even when -gdwarf2 is supplied. This is a first attempt to get m3gdb to handle these. It is not complete. diff --git a/m3-sys/m3gdb/gdb/gdb/dwarf2read.c b/m3-sys/m3gdb/gdb/gdb/dwarf2read.c index 883fa43f7..5183322b0 100644 --- a/m3-sys/m3gdb/gdb/gdb/dwarf2read.c +++ b/m3-sys/m3gdb/gdb/gdb/dwarf2read.c @@ -53,6 +53,7 @@ #include "gdb_string.h" #include "gdb_assert.h" #include +#include /* A note on memory usage for this file. @@ -1168,6 +1169,9 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr) void dwarf2_build_psymtabs (struct objfile *objfile, int mainline) { + + return; /* Temporary. */ + Maybe I just give up and put m3main back as m3cc IR instead of C. I was just trying to reduce configurations/modes at the time. It also hypothetically skips C++ static constructors but probably not in reality. (On ancient systems, cfront would insert code in main to call them, I gather, I've never seen it.) I am trying to update the Dwarf handling..and it starts out easy..but doesn't clearly remain so. - Jay ________________________________ From: Jay K Sent: Sunday, April 4, 2021 11:27 PM To: m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb ok. I can build m3gdb on Ubuntu 1604 no problem and I can see the behavior w/ -g vs. -gstabs+ For example, run cm3, break on open, on the second call, go up or fin, and print the path name. Either works (-gstabs+) or fails an assert in m3gdb (-g). Presumably I can come up with some other fix, but depends, like, what symbols are preserved and what m3gdb looks for. Like, maybe just volatile char INTEGER? will work. I'll fiddle around. It'd probably also work to compile _m3main.c with -gstabus+. To be clear, m3gdb does not compile out of the box on Ubuntu 20.04. I didn't try others. - Jay ________________________________ From: Jay K Sent: Tuesday, March 30, 2021 6:24 PM To: m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb When I used gcc -gstabs I got incorrect symbols for C. I spent a while debugging the C thinking it was incorrect only to later realize the problem was the symbols. At least with the current Debian gcc, not with the current mainline gcc. Gcc developers would like to remove stabs support, as well. That was the response to the bug report (and that it no longer repros). 99457 ? gcc/gdb -gstabs+ is buggy. (gnu.org) If that ever happens, then what? So I don't know what to do. It is bad either way. Since I don't use m3cc or m3gdb, it could be dependent on backend mode?? That's a little gross but might keep everyone productive. - Jay ________________________________ From: M3devel on behalf of Rodney M. Bates Sent: Tuesday, March 30, 2021 6:16 PM To: m3devel Subject: [M3devel] g++ -g undermines m3gdb -> linking prog generate _m3main.c g++ -g -m64 -fPIC -g -c -xc++ _m3main.c -o _m3main.o This undermines m3gdb. m3gdb looks for certain stabs definitions that occur in every main program to ascertain what compiler (especially, pm3 vs. cm3) compiled it. With a mixture of dwarf for _m3main.c and stabs for everything else, it can't find what it needs. gcc -g -m64 -fPIC -fuse-ld=gold -Wl,-z,now -Wl,-z,origin -Bsymbolic -Wl,--fatal-warnings -Wl,-rpath,\$ORIGIN -Wl,-rpath,\$ORIGIN/../lib -Wl,--warn-common -Wl,-rpath,/usr/local/cm3/bin/../lib -o prog _m3main.o Main_m.o -L/usr/local/cm3/pkg/libm3/AMD64_LINUX -lm3 -L/usr/local/cm3/pkg/m3core/AMD64_LINUX -lm3core -lm -pthread -- Rodney Bates rodney.m.bates at acm.org _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C8f6cca20fd774c27b8a208d8f3a7fcb6%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637527250111222123%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=mMxC4P0yApuTpVLFfZtIhuQG%2FTBEETIlinS9eP9OhOE%3D&reserved=0 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Mon Apr 5 07:59:48 2021 From: jayk123 at hotmail.com (Jay K) Date: Mon, 5 Apr 2021 05:59:48 +0000 Subject: [M3devel] g++ -g undermines m3gdb In-Reply-To: References: , , , , Message-ID: It looks current gdb does not read locdesc there. The old gdb I guess is just wrong. I made the change "safer" and it just skips these entirely. Considering that we skipped Dwarf entirely before, as long as this reads some of the symbols, and the reader stays in sync and all, I guess it is only better, and good enough for m3gdb. ? Though I guess it is possible it will display incorrect data or crash. - Jay ________________________________ From: Jay K Sent: Monday, April 5, 2021 4:00 AM To: m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb Good enough? m3gdb: Some reading of Dwarf symbols so that g++ -g _m3main.c works. by jaykrell ? Pull Request #317 ? modula3/cm3 (github.com) I realize it is a bit hazardous..would be better to make the reading really work, or to alway skip the locdesc. Or _m3main.c could go back through m3cg as I said. Heck, even through the C backend, it'd be nice to see how that compares. ? - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Monday, April 5, 2021 3:30 AM To: m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb Ugh, so the symbols are maybe there, but our gdb is too old to read Dwarf. commit c20a30f9de9bb90e16aac378cdca095e3372fe02 Author: Rodney Bates Date: Sat Jun 6 12:16:37 2015 -0500 Add some dwarf4 codes. gcc 4.8.1 emits these even when -gdwarf2 is supplied. This is a first attempt to get m3gdb to handle these. It is not complete. diff --git a/m3-sys/m3gdb/gdb/gdb/dwarf2read.c b/m3-sys/m3gdb/gdb/gdb/dwarf2read.c index 883fa43f7..5183322b0 100644 --- a/m3-sys/m3gdb/gdb/gdb/dwarf2read.c +++ b/m3-sys/m3gdb/gdb/gdb/dwarf2read.c @@ -53,6 +53,7 @@ #include "gdb_string.h" #include "gdb_assert.h" #include +#include /* A note on memory usage for this file. @@ -1168,6 +1169,9 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr) void dwarf2_build_psymtabs (struct objfile *objfile, int mainline) { + + return; /* Temporary. */ + Maybe I just give up and put m3main back as m3cc IR instead of C. I was just trying to reduce configurations/modes at the time. It also hypothetically skips C++ static constructors but probably not in reality. (On ancient systems, cfront would insert code in main to call them, I gather, I've never seen it.) I am trying to update the Dwarf handling..and it starts out easy..but doesn't clearly remain so. - Jay ________________________________ From: Jay K Sent: Sunday, April 4, 2021 11:27 PM To: m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb ok. I can build m3gdb on Ubuntu 1604 no problem and I can see the behavior w/ -g vs. -gstabs+ For example, run cm3, break on open, on the second call, go up or fin, and print the path name. Either works (-gstabs+) or fails an assert in m3gdb (-g). Presumably I can come up with some other fix, but depends, like, what symbols are preserved and what m3gdb looks for. Like, maybe just volatile char INTEGER? will work. I'll fiddle around. It'd probably also work to compile _m3main.c with -gstabus+. To be clear, m3gdb does not compile out of the box on Ubuntu 20.04. I didn't try others. - Jay ________________________________ From: Jay K Sent: Tuesday, March 30, 2021 6:24 PM To: m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb When I used gcc -gstabs I got incorrect symbols for C. I spent a while debugging the C thinking it was incorrect only to later realize the problem was the symbols. At least with the current Debian gcc, not with the current mainline gcc. Gcc developers would like to remove stabs support, as well. That was the response to the bug report (and that it no longer repros). 99457 ? gcc/gdb -gstabs+ is buggy. (gnu.org) If that ever happens, then what? So I don't know what to do. It is bad either way. Since I don't use m3cc or m3gdb, it could be dependent on backend mode?? That's a little gross but might keep everyone productive. - Jay ________________________________ From: M3devel on behalf of Rodney M. Bates Sent: Tuesday, March 30, 2021 6:16 PM To: m3devel Subject: [M3devel] g++ -g undermines m3gdb -> linking prog generate _m3main.c g++ -g -m64 -fPIC -g -c -xc++ _m3main.c -o _m3main.o This undermines m3gdb. m3gdb looks for certain stabs definitions that occur in every main program to ascertain what compiler (especially, pm3 vs. cm3) compiled it. With a mixture of dwarf for _m3main.c and stabs for everything else, it can't find what it needs. gcc -g -m64 -fPIC -fuse-ld=gold -Wl,-z,now -Wl,-z,origin -Bsymbolic -Wl,--fatal-warnings -Wl,-rpath,\$ORIGIN -Wl,-rpath,\$ORIGIN/../lib -Wl,--warn-common -Wl,-rpath,/usr/local/cm3/bin/../lib -o prog _m3main.o Main_m.o -L/usr/local/cm3/pkg/libm3/AMD64_LINUX -lm3 -L/usr/local/cm3/pkg/m3core/AMD64_LINUX -lm3core -lm -pthread -- Rodney Bates rodney.m.bates at acm.org _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C8f6cca20fd774c27b8a208d8f3a7fcb6%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637527250111222123%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=mMxC4P0yApuTpVLFfZtIhuQG%2FTBEETIlinS9eP9OhOE%3D&reserved=0 -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Mon Apr 5 17:49:49 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Mon, 5 Apr 2021 10:49:49 -0500 Subject: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 In-Reply-To: References: <7afe431f-a0e8-682a-ed1b-c5b4d1a1de24@lcwb.coop> Message-ID: On 4/4/21 3:58 PM, Jay K wrote: > So passing a READONLY INTEGER is by pointer, > with the understanding that the callee won't > write throug it, but passing a plain INTEGER > is not? Yes, if by "plain" you mean passed VALUE, or no mode, which defaults to VALUE. > > ?> "Implementations are allowed to forbid > ?> \verb|VAR| or \verb|READONLY| parameters > ?> ?of packed types." > > Good. So any pointer across a function call boundary > can only be assumed to be well aligned. Yes. The pointer itself will be pointer aligned. Where it points to will be appropriate for the type of the high-level parameter. > > ?>> The code in Formal looks wrong to me, but I think it was always that way. > ?> It's been reworked. > > Specifically this is suspicious: > > ? ? ? IF t.mode # Mode.mVALUE OR t.openArray > ? ? ? THEN (* lo-level pass by reference. *) > ? ? ? ? size ?:= Target.Address.size; > ? ? ? ? align := Target.Address.align; > ? ? ? ? mtype := CG.Type.Addr; > > I understand the three alignments: > ? where pointer value must be stored, i.e. word > ? where pointer value is stored, i.e. possibly more than word > ? what pointer points to > > But if there can only be one, then it should be the last, eh? > I think this might be part of the problems but I am not sure. > i.e. a pointer to longreal should have 64 alignment. These values are going into the CG Declare_param operation, where they apply to what is being passed lo-level, i.e., the pointer. The alignment of what it points to isn't in this operator. That would be in something like a Load_indirect, which dereferences the pointer. I added some clarification to at least some of these in CG, e.g., in CG.i3: PROCEDURE Load_indirect (t: Type; o: Offset; s: Size; addr_align: Alignment := Target.Word8.align); (* s0.t := Mem [s0.A + o : s] *) (* if t=A, addr_align applies to where s0.t points, otherwise irrelevant. *) At the level of M3CG_Ops.i3, it's more subtle: load_indirect (o: ByteOffset; t: MType; u: ZType); (* s0.u := Mem [s0.A + o].t *) but the fact that the MType t applies to the fetched memory, implies that the alignment of the memory operand is that of t. > > ?> Yes. ?Like simple fetch and store, if, as usual, it is normally sized and aligned. > > Aha. So conceptually there is: > > ?struct { > ? ?volatile a : 1; > ? ?volatile b : 1; > ?}; > > which to me is mostly a bad idea. Because accesses to a will access b. > > However it does have a possible use. It should maybe imply I think atomic. > On x86 you can even use lock bts/btc. > > ?struct { > ? ?volatile a : 8; > ? ?volatile b : 8; > ?}; > > isn't so bad. It means be sure to use byte accesses to a or b. > > I realize volatile is its own complex matter and should be avoided. > > ?- Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Rodney M. Bates > *Sent:* Sunday, April 4, 2021 5:12 PM > *To:* Jay K ; m3devel at elegosoft.com ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 > > > On 4/3/21 12:49 PM, Jay K wrote: >>? ?> VAR and READONLY parameters are always passed by reference at the low >> >> Separate question: Always? READONLY by reference even if "small"? > > ?From 2.3.2: > > ?? "A READONLY formal is treated as a VAR formal if the > ?? actual is a designator and the type of the actual is the same as the type of > ?? the formal (or an array type that is assignable to the type of the formal); > ?? otherwise it is treated as a VALUE formal." > > Note no mention of size. > > Since the high-level mode is sometimes reference, sometimes value, depending > on properties of the actual, the only reasonable implementation is that at the > low level, it always passes a pointer.? For an actual that requires pass-by-value, > the code at the call site makes a copy and passes the pointer to that. > Regardless of the size > > Also, from 2.3.2: > > ?? "Implementations are allowed to forbid \verb|VAR| or \verb|READONLY| parameters > ?? of packed types." > > which the front end does.? Otherwise would require a really messy implementation. > > >> The code in Formal looks wrong to me, but I think it was always that way. > > It's been reworked.? It had some flaws for various combinations of type, mode, > packedness, kind of actual, runtime errors.? Confusingly, though the module > is named Formal, it is doing the compiling of actual parameters. > > >> You know, your changes are large and intertwined, which is ok, but then I cannot easily or at all pin the problem on a small bit of code or change. >> > > > >>? ?> Another distinction I added is between the alignment of a type, and that of >>? ?> an expression, which can sometimes be more generous than that of its type. >>? ?> I recall at the time thinking I was being rather magnanimous in giving A[0] >>? ?> an expression alignment of word, when A is a heap-allocated open array >>? ?> of, say, CHAR >> >>? ?This makes sense to me, but is it valuable? >>? ?Does it enable m3front to generate different code? > > Yes.? Like simple fetch and store, if, as usual, it is normally sized and aligned. > >>? ?Like, zero'ing of multiple char array elements at a time or such? >> > > Not sure if this one happens, but the distinction would be necessary to do so. > >>? ?- Jay >> >> - > -- > Rodney Bates > rodney.m.bates at acm.org > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://m3lists.elegosoft.com/mailman/listinfo/m3devel > -- Rodney Bates rodney.m.bates at acm.org From rodney_bates at lcwb.coop Mon Apr 5 18:07:01 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Mon, 5 Apr 2021 11:07:01 -0500 Subject: [M3devel] g++ -g undermines m3gdb In-Reply-To: References: Message-ID: <4d2b41eb-7c37-23c7-82ee-c5115e782986@lcwb.coop> On 4/4/21 10:30 PM, Jay K wrote: > Ugh, so the symbols are maybe there, but our gdb is too old to read Dwarf. I believe it reads only an older version of Dwarf, which has since had several updates with new operators. m3gdb doesn't actually use any Dwarf. it just has preexisting code to read it in. It uses only stabs. And the stabs between the front end and m3gdb is a mess. For one thing, official documentation on stabs is not very good, and different compilers produce various not-so-standard variations. In the case of m3front, it puts out some stuff that resembles some variation of "official" stabs, part of which is not actually used either. Much of the Modula-3 specific info is encoded in a couple of integers and a string inside of stabs lines, entirely independent of official stabs. It's a real mess, but it does contain much M3-specific info that is needed by a nice M3 debugger, and not available in any other way. I have glanced at some of the recent Dwarf specs, and they appear to have about everything that would be needed for good M3 debugging. Using it would be a significant job. Llvm claims to handle (a semantic equivalent of) Dwarf, but it turns out to be a small subset of all of Dwarf, sufficient for C and C++, but missing some things M3 needs. Peter has, as I understand, recently gotten some added Dwarf operators incorporated into official llvm distribution, and is working on some more. I would love to have a good M3 debugger using Dwarf. For now, I just want to be able to keep using what is there. > > commit c20a30f9de9bb90e16aac378cdca095e3372fe02 > Author: Rodney Bates > Date: ? Sat Jun 6 12:16:37 2015 -0500 > > ? ? Add some dwarf4 codes. > > ? ? gcc 4.8.1 emits these even when -gdwarf2 is supplied. ?This is a first > ? ? attempt to get m3gdb to handle these. ?It is not complete. > > diff --git a/m3-sys/m3gdb/gdb/gdb/dwarf2read.c b/m3-sys/m3gdb/gdb/gdb/dwarf2read.c > index 883fa43f7..5183322b0 100644 > --- a/m3-sys/m3gdb/gdb/gdb/dwarf2read.c > +++ b/m3-sys/m3gdb/gdb/gdb/dwarf2read.c > @@ -53,6 +53,7 @@ > ?#include "gdb_string.h" > ?#include "gdb_assert.h" > ?#include > +#include > > ?/* A note on memory usage for this file. > > @@ -1168,6 +1169,9 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr) > ?void > ?dwarf2_build_psymtabs (struct objfile *objfile, int mainline) > ?{ > + > + ?return; /* Temporary. */ > + > > Maybe I just give up and put m3main back as m3cc IR instead of C. > I was just trying to reduce configurations/modes at the time. > It also hypothetically skips C++ static constructors but probably not in reality. > (On ancient systems, cfront would insert code in main to call them, I gather, I've never seen it.) > > I am trying to update the Dwarf handling..and it starts out easy..but doesn't clearly remain so. > > ?- Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Sunday, April 4, 2021 11:27 PM > *To:* m3devel ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] g++ -g undermines m3gdb > ok. I can build m3gdb on Ubuntu 1604 no problem and I can see the behavior w/ -g vs. -gstabs+ > For example, run cm3, break on open, on the second call, go up or fin, and print the path name. > Either works (-gstabs+) or fails an assert in m3gdb (-g). > Presumably I can come up with some other fix, but depends, like, what symbols are preserved and what > m3gdb looks for. > Like, maybe just |volatile char INTEGER|?? will work. I'll fiddle around. > It'd probably also work to compile _m3main.c with -gstabus+. > > To be clear, m3gdb does not compile out of the box on Ubuntu 20.04. I didn't try others. > > ?- Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Tuesday, March 30, 2021 6:24 PM > *To:* m3devel ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] g++ -g undermines m3gdb > When I used gcc -gstabs I got incorrect symbols for C. > I spent a while debugging the C thinking it was incorrect only to later realize the problem was the symbols. > ? At least with the current Debian gcc, not with the current mainline gcc. > Gcc developers would like to remove stabs support, as well. > That was the response to the bug report (and that it no longer repros). > 99457 ? gcc/gdb -gstabs+ is buggy. (gnu.org) > > If that ever happens, then what? > > So I don't know what to do. It is bad either way. > Since I don't use m3cc or m3gdb, it could be dependent on backend mode?? > That's a little gross but might keep everyone productive. > > ?- Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* M3devel on behalf of Rodney M. Bates > *Sent:* Tuesday, March 30, 2021 6:16 PM > *To:* m3devel > *Subject:* [M3devel] g++ -g undermines m3gdb > > ? -> linking prog > generate _m3main.c > g++ -g -m64 -fPIC -g -c -xc++ _m3main.c -o _m3main.o > > This undermines m3gdb.? m3gdb looks for certain stabs definitions that > occur in every main program to ascertain what compiler (especially, pm3 > vs. cm3) compiled it.? With a mixture of dwarf for _m3main.c and stabs > for everything else, it can't find what it needs. > > gcc -g -m64 -fPIC -fuse-ld=gold -Wl,-z,now -Wl,-z,origin -Bsymbolic -Wl,--fatal-warnings -Wl,-rpath,\$ORIGIN -Wl,-rpath,\$ORIGIN/../lib -Wl,--warn-common -Wl,-rpath,/usr/local/cm3/bin/../lib? -o prog? _m3main.o Main_m.o -L/usr/local/cm3/pkg/libm3/AMD64_LINUX -lm3 -L/usr/local/cm3/pkg/m3core/AMD64_LINUX -lm3core -lm -pthread > > > -- > Rodney Bates > rodney.m.bates at acm.org > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C8f6cca20fd774c27b8a208d8f3a7fcb6%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637527250111222123%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=mMxC4P0yApuTpVLFfZtIhuQG%2FTBEETIlinS9eP9OhOE%3D&reserved=0 > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://m3lists.elegosoft.com/mailman/listinfo/m3devel > -- Rodney Bates rodney.m.bates at acm.org From jayk123 at hotmail.com Mon Apr 5 20:22:21 2021 From: jayk123 at hotmail.com (Jay K) Date: Mon, 5 Apr 2021 18:22:21 +0000 Subject: [M3devel] m3front ultimately to not do layout (optionally) In-Reply-To: References: , Message-ID: I agree that is probably unrealistic. I probably didn't send the longer version: Apple delivered a "holy grail" -- developers of Watch apps submit "portable" LLVM IR. By "portable" it has no setjmp/lonjmp or processor context (signal handling and make/get/set/swapcontext). And no "real" instructions. But it is 32bit little endian. Apple was able to switch the hardware from 32bit ARM to 64bit ARM (with 32bit address space per process) without developers updating anything. Similarly WebAssembly is little endian and initiallly 32bit. We probably cannot do better than them. On the other end of the spectrum is .NET and Java that generally distribute endian-neutral wordsize-neutral "binaries". But they are quite high level, and always were, and we probably cannot get there. Even then a lot of .NET IL is actually not wordsize-neutral or endian-neutral. - Jay ________________________________ From: Mika Nystrom Sent: Monday, April 5, 2021 4:32 PM To: Jay K Cc: m3devel at elegosoft.com Subject: Re: [M3devel] m3front ultimately to not do layout (optionally) Jay, this goal: Ultimately I'd like m3front to not know word size or endian, and C backend output to be independnet of them, but this might not be achievable. I think you can at least in theory make the output endian-agnostic, but since BITSIZE and BYTESIZE are allowed in constant expressions, Modula-3 types can be made to be dependent on the word size, e.g., TYPE X = ARRAY [ 0 .. BITSIZE(T)-1 ] OF U; Mika On Sat, Apr 3, 2021 at 11:39 AM Jay K > wrote: Just to be clear, ultimately, I'd like m3front to issue references to array indices and record fields, not base + m3front-computed-offset + cast. m3front would also no longer know the sizes of aggregates (arrays & records) in this scheme. It'd be up to the backend. C backend could just say "sizeof(x)" and leave it to the C compiler to compute. That would moot present discussions of alignment mostly or entirely. But in order to get their incrementally and as insurance against large changes not actually happening, I'd like to get the old way back to working first. At the same time though, existing backends could work. That is, m3front would optionally work the new way. Like, every array element or record element reference would be something like: record_field_access(base, offset, name, type) array_element_access(base, offset, index, type) and backends would use either offset or name/index. The first or all versions might even assert an equivalence, which should be trivial. Type would be redundant in the new mode, or, again asserted. Read vs. write might be separate calls. Backends are "stackable". So maybe we'd "stack in" a backend that convert these to just base + offset + cast for the existing backends. Or each backend would advertise which calls it understands and m3front/CG would decide. Besides the C backend, I believe LLVM could use this. Ultimately I'd like m3front to not know word size or endian, and C backend output to be independnet of them, but this might not be achievable. - Jay _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Mon Apr 5 21:44:38 2021 From: jayk123 at hotmail.com (Jay K) Date: Mon, 5 Apr 2021 19:44:38 +0000 Subject: [M3devel] g++ -g undermines m3gdb In-Reply-To: <4d2b41eb-7c37-23c7-82ee-c5115e782986@lcwb.coop> References: , <4d2b41eb-7c37-23c7-82ee-c5115e782986@lcwb.coop> Message-ID: > For now, I just want to be able to keep using what is there. It should work now in master. I let some of the Dwarf reading code run, that you had disabled, and it is enough to see the "INTEGER" symbol. And I added just enough Dwarf4 so it does not crash. > And the stabs between the front end and m3gdb is a mess. As I understand, m3cc basically uses stabs as a container for private communication to m3gdb. It is good and bad. > sufficient for C and C++, but missing some things M3 needs. In my view, the world should/can be viewed as integers, floats, structs/records, sized enums, bitfields, tagged unions, arrays, pointers, and compose all that (records of records, arrays of unions, etc.) What am I missing, that Dwarf needed extra stuff for, to describe Pascal, Ada, Modula-3? I'll try to read it later. In expressions, I don't find interesting the difference between = and ==, / and div, % and mod, etc. And yeah I understand % and mod are not the same, like with negative numbers. So then when faced with "objects" and "text", that are just composed of the above, but merit an implied "deeper default evaluation", you have a choice of changing the debugger, or extending the debugger. Even on the C++ side, while string constants might be builtin, there are things like gsl::span and std::string which a debugger might not understand w/o extension. m3gdb changes the debugger. This provides a nicer user experience but is far more expensive to build and maintain, and is less easily translated to other systems and debuggers. gdb was failing me on Solaris recently. I used dbx and found the problem (fork handlers have signals disabled/deferred, so fork and collect deadlock). I use cdb/windbg on Windows. So m3gdb basically does not exist to me. I believer callable functions are a likely common element that all the debuggers are extendable with. Or, barring that, gdb does have a plugin API. People use Python. Again, I grant the user experience will degrade, and there is work to do either way, but these are probably the way to go. - Jay ________________________________ From: Rodney M. Bates Sent: Monday, April 5, 2021 4:07 PM To: Jay K ; m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] g++ -g undermines m3gdb On 4/4/21 10:30 PM, Jay K wrote: > Ugh, so the symbols are maybe there, but our gdb is too old to read Dwarf. I believe it reads only an older version of Dwarf, which has since had several updates with new operators. m3gdb doesn't actually use any Dwarf. it just has preexisting code to read it in. It uses only stabs. And the stabs between the front end and m3gdb is a mess. For one thing, official documentation on stabs is not very good, and different compilers produce various not-so-standard variations. In the case of m3front, it puts out some stuff that resembles some variation of "official" stabs, part of which is not actually used either. Much of the Modula-3 specific info is encoded in a couple of integers and a string inside of stabs lines, entirely independent of official stabs. It's a real mess, but it does contain much M3-specific info that is needed by a nice M3 debugger, and not available in any other way. I have glanced at some of the recent Dwarf specs, and they appear to have about everything that would be needed for good M3 debugging. Using it would be a significant job. Llvm claims to handle (a semantic equivalent of) Dwarf, but it turns out to be a small subset of all of Dwarf, sufficient for C and C++, but missing some things M3 needs. Peter has, as I understand, recently gotten some added Dwarf operators incorporated into official llvm distribution, and is working on some more. I would love to have a good M3 debugger using Dwarf. For now, I just want to be able to keep using what is there. > > commit c20a30f9de9bb90e16aac378cdca095e3372fe02 > Author: Rodney Bates > Date: Sat Jun 6 12:16:37 2015 -0500 > > Add some dwarf4 codes. > > gcc 4.8.1 emits these even when -gdwarf2 is supplied. This is a first > attempt to get m3gdb to handle these. It is not complete. > > diff --git a/m3-sys/m3gdb/gdb/gdb/dwarf2read.c b/m3-sys/m3gdb/gdb/gdb/dwarf2read.c > index 883fa43f7..5183322b0 100644 > --- a/m3-sys/m3gdb/gdb/gdb/dwarf2read.c > +++ b/m3-sys/m3gdb/gdb/gdb/dwarf2read.c > @@ -53,6 +53,7 @@ > #include "gdb_string.h" > #include "gdb_assert.h" > #include > +#include > > /* A note on memory usage for this file. > > @@ -1168,6 +1169,9 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr) > void > dwarf2_build_psymtabs (struct objfile *objfile, int mainline) > { > + > + return; /* Temporary. */ > + > > Maybe I just give up and put m3main back as m3cc IR instead of C. > I was just trying to reduce configurations/modes at the time. > It also hypothetically skips C++ static constructors but probably not in reality. > (On ancient systems, cfront would insert code in main to call them, I gather, I've never seen it.) > > I am trying to update the Dwarf handling..and it starts out easy..but doesn't clearly remain so. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Sunday, April 4, 2021 11:27 PM > *To:* m3devel ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] g++ -g undermines m3gdb > ok. I can build m3gdb on Ubuntu 1604 no problem and I can see the behavior w/ -g vs. -gstabs+ > For example, run cm3, break on open, on the second call, go up or fin, and print the path name. > Either works (-gstabs+) or fails an assert in m3gdb (-g). > Presumably I can come up with some other fix, but depends, like, what symbols are preserved and what > m3gdb looks for. > Like, maybe just |volatile char INTEGER|? will work. I'll fiddle around. > It'd probably also work to compile _m3main.c with -gstabus+. > > To be clear, m3gdb does not compile out of the box on Ubuntu 20.04. I didn't try others. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Jay K > *Sent:* Tuesday, March 30, 2021 6:24 PM > *To:* m3devel ; rodney.m.bates at acm.org > *Subject:* Re: [M3devel] g++ -g undermines m3gdb > When I used gcc -gstabs I got incorrect symbols for C. > I spent a while debugging the C thinking it was incorrect only to later realize the problem was the symbols. > At least with the current Debian gcc, not with the current mainline gcc. > Gcc developers would like to remove stabs support, as well. > That was the response to the bug report (and that it no longer repros). > 99457 ? gcc/gdb -gstabs+ is buggy. (gnu.org) > > If that ever happens, then what? > > So I don't know what to do. It is bad either way. > Since I don't use m3cc or m3gdb, it could be dependent on backend mode?? > That's a little gross but might keep everyone productive. > > - Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* M3devel on behalf of Rodney M. Bates > *Sent:* Tuesday, March 30, 2021 6:16 PM > *To:* m3devel > *Subject:* [M3devel] g++ -g undermines m3gdb > > -> linking prog > generate _m3main.c > g++ -g -m64 -fPIC -g -c -xc++ _m3main.c -o _m3main.o > > This undermines m3gdb. m3gdb looks for certain stabs definitions that > occur in every main program to ascertain what compiler (especially, pm3 > vs. cm3) compiled it. With a mixture of dwarf for _m3main.c and stabs > for everything else, it can't find what it needs. > > gcc -g -m64 -fPIC -fuse-ld=gold -Wl,-z,now -Wl,-z,origin -Bsymbolic -Wl,--fatal-warnings -Wl,-rpath,\$ORIGIN -Wl,-rpath,\$ORIGIN/../lib -Wl,--warn-common -Wl,-rpath,/usr/local/cm3/bin/../lib -o prog _m3main.o Main_m.o -L/usr/local/cm3/pkg/libm3/AMD64_LINUX -lm3 -L/usr/local/cm3/pkg/m3core/AMD64_LINUX -lm3core -lm -pthread > > > -- > Rodney Bates > rodney.m.bates at acm.org > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Cbb0842e9f2524184422308d8f84ce64c%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637532356463497192%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=eH%2B9rVJWwPr8uD%2BgQ3vPdZBip9WaiBmyCFt8jolEa%2BA%3D&reserved=0 > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Cbb0842e9f2524184422308d8f84ce64c%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637532356463497192%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=eH%2B9rVJWwPr8uD%2BgQ3vPdZBip9WaiBmyCFt8jolEa%2BA%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Tue Apr 6 04:46:29 2021 From: jayk123 at hotmail.com (Jay K) Date: Tue, 6 Apr 2021 02:46:29 +0000 Subject: [M3devel] m3front ultimately to not do layout (optionally) In-Reply-To: References: , , Message-ID: > TYPE X = ARRAY [ 0 .. BITSIZE(T)-1 ] OF U; You "just" have to keep the text of expressions around, and translate them. Hypothetically this translates to: typedef struct { U elements[sizeof(T) * 8 - 1]; // or U replaced by U's typeid, T by T's typeid } X; // or X replaced with a typeid... And change type hashing to somehow be independent of the size too, but still factor it in..like fill in an arbitrary value..and worry about pickles.. Not easy though. - Jay ________________________________ From: Jay K Sent: Monday, April 5, 2021 6:22 PM To: Mika Nystrom Cc: m3devel at elegosoft.com Subject: Re: [M3devel] m3front ultimately to not do layout (optionally) I agree that is probably unrealistic. I probably didn't send the longer version: Apple delivered a "holy grail" -- developers of Watch apps submit "portable" LLVM IR. By "portable" it has no setjmp/lonjmp or processor context (signal handling and make/get/set/swapcontext). And no "real" instructions. But it is 32bit little endian. Apple was able to switch the hardware from 32bit ARM to 64bit ARM (with 32bit address space per process) without developers updating anything. Similarly WebAssembly is little endian and initiallly 32bit. We probably cannot do better than them. On the other end of the spectrum is .NET and Java that generally distribute endian-neutral wordsize-neutral "binaries". But they are quite high level, and always were, and we probably cannot get there. Even then a lot of .NET IL is actually not wordsize-neutral or endian-neutral. - Jay ________________________________ From: Mika Nystrom Sent: Monday, April 5, 2021 4:32 PM To: Jay K Cc: m3devel at elegosoft.com Subject: Re: [M3devel] m3front ultimately to not do layout (optionally) Jay, this goal: Ultimately I'd like m3front to not know word size or endian, and C backend output to be independnet of them, but this might not be achievable. I think you can at least in theory make the output endian-agnostic, but since BITSIZE and BYTESIZE are allowed in constant expressions, Modula-3 types can be made to be dependent on the word size, e.g., TYPE X = ARRAY [ 0 .. BITSIZE(T)-1 ] OF U; Mika On Sat, Apr 3, 2021 at 11:39 AM Jay K > wrote: Just to be clear, ultimately, I'd like m3front to issue references to array indices and record fields, not base + m3front-computed-offset + cast. m3front would also no longer know the sizes of aggregates (arrays & records) in this scheme. It'd be up to the backend. C backend could just say "sizeof(x)" and leave it to the C compiler to compute. That would moot present discussions of alignment mostly or entirely. But in order to get their incrementally and as insurance against large changes not actually happening, I'd like to get the old way back to working first. At the same time though, existing backends could work. That is, m3front would optionally work the new way. Like, every array element or record element reference would be something like: record_field_access(base, offset, name, type) array_element_access(base, offset, index, type) and backends would use either offset or name/index. The first or all versions might even assert an equivalence, which should be trivial. Type would be redundant in the new mode, or, again asserted. Read vs. write might be separate calls. Backends are "stackable". So maybe we'd "stack in" a backend that convert these to just base + offset + cast for the existing backends. Or each backend would advertise which calls it understands and m3front/CG would decide. Besides the C backend, I believe LLVM could use this. Ultimately I'd like m3front to not know word size or endian, and C backend output to be independnet of them, but this might not be achievable. - Jay _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Tue Apr 13 09:04:34 2021 From: jayk123 at hotmail.com (Jay K) Date: Tue, 13 Apr 2021 07:04:34 +0000 Subject: [M3devel] alignment problems Message-ID: Rodney, the system has not been buildable for quite some weeks now. Is it ok if I undo all your m3front changes and you can redo them when they work more completely? "..\src\maxflow\MFEdgeView.m3", line 17: ** INTERNAL CG ERROR *** stack not empty, depth (8) *** *** runtime error: *** <*ASSERT*> failed: top.depth = 0 *** file "../src/exprs/ArrayExpr.m3", line 2091 *** etc. I would also undo my workarounds related to arrays. I would also expect alignment of 64bit-sized types on 32bit targets to remain at 64bit, or at least for that to work, i.e. with the C backend. As it stands, the C backend can no longer target 32bit targets, which it was doing succcessfully for a long time. I hope to setup some CI before much longer so these regressions are not allowed or at least known ahead of time, but I have not gotten to it yet. Thank you, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Tue Apr 13 09:07:57 2021 From: jayk123 at hotmail.com (Jay K) Date: Tue, 13 Apr 2021 07:07:57 +0000 Subject: [M3devel] CI for cm3? Message-ID: Does anyone have thoughts on CI for cm3? Or time/interest/willingness to set something up? Any experience in the various free options? I do not love required significant hoops to jump through to commit. However we might as well at least have some optional tests, or many optional tests. Perhaps even some required. If nothing/nobody else I'll probably read up on GitHub Actions. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Wed Apr 14 01:45:14 2021 From: jayk123 at hotmail.com (Jay K) Date: Tue, 13 Apr 2021 23:45:14 +0000 Subject: [M3devel] declare const in interface? Message-ID: In C we can do this: foo.h struct Data { int a; ... more stuff, "large" }; extern const Data data[123]; // "large", 123 is max of an enum often foo.c extern const Data data[] = {...}; bar.c data[i].a; // i is integer or enum What is the equivalent in Modula-3? In particular: 1. I do not want the const in the .i3. If foo.m3/foo.c changes, bar only needs to relink, not recompile. .i3 files should be kinda smaller and more readable than .m3. 2. I'd rather avoid a function call. 3. I want the data to be constant, not var. I don't see how in Modula-3 to satisfy all those requirements. If I must I will likely give up on point 2. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Wed Apr 14 06:34:04 2021 From: jayk123 at hotmail.com (Jay K) Date: Wed, 14 Apr 2021 04:34:04 +0000 Subject: [M3devel] declare const in interface? In-Reply-To: References: , Message-ID: Readonly memory is significantly more efficient than writable memory. It can be shared across processes and incurs no copy on write faults. So const is better than var. - Jay ________________________________ From: Mika Nystrom Sent: Tuesday, April 13, 2021 9:16:36 PM To: Jay K Cc: m3devel Subject: Re: [M3devel] declare const in interface? Why not just make it VAR? What do you gain from not having it be VAR? But I think you are right, you cannot get what you want in M3. Conversely, I can't make types depend on consts in C (whereas making them depend on CONSTs works in M3)... On Tue, Apr 13, 2021 at 4:45 PM Jay K > wrote: In C we can do this: foo.h struct Data { int a; ... more stuff, "large" }; extern const Data data[123]; // "large", 123 is max of an enum often foo.c extern const Data data[] = {...}; bar.c data[i].a; // i is integer or enum What is the equivalent in Modula-3? In particular: 1. I do not want the const in the .i3. If foo.m3/foo.c changes, bar only needs to relink, not recompile. .i3 files should be kinda smaller and more readable than .m3. 2. I'd rather avoid a function call. 3. I want the data to be constant, not var. I don't see how in Modula-3 to satisfy all those requirements. If I must I will likely give up on point 2. - Jay _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From vvm at tut.by Wed Apr 14 09:01:26 2021 From: vvm at tut.by (vvm at tut.by) Date: Wed, 14 Apr 2021 10:01:26 +0300 Subject: [M3devel] AppVeyor CI Re: CI for cm3? In-Reply-To: References: Message-ID: <1015851618382582@mail.yandex.by> An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Wed Apr 14 09:23:03 2021 From: jayk123 at hotmail.com (Jay K) Date: Wed, 14 Apr 2021 07:23:03 +0000 Subject: [M3devel] typeid clash Message-ID: libm3\Formatter.m3: Int = REF INTEGER; ints: ARRAY [-256..256] OF Int; /* declare_subrange typeid:T69A2A904 domain_type:T195C2A74 min:-256 max:256 bit_size:16 */ libm3\Sx.m3 MinBoxedInt = -100; MaxBoxedInt = 100; BoxedInts := ARRAY [MinBoxedInt .. MaxBoxedInt] OF REF INTEGER {NIL, ..}; /* declare_subrange typeid:T69A2A904 domain_type:T195C2A74 min:-100 max:100 bit_size:8 */ Well that seems like a problem, eh? Two different types with the same type hash? They don't even have the same size (underlying representation). - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From antony.hosking at anu.edu.au Wed Apr 14 11:46:27 2021 From: antony.hosking at anu.edu.au (Tony Hosking) Date: Wed, 14 Apr 2021 09:46:27 +0000 Subject: [M3devel] typeid clash In-Reply-To: References: Message-ID: Something has clearly broken here. Get Outlook for iOS ________________________________ From: M3devel on behalf of Jay K Sent: Wednesday, April 14, 2021 5:23:03 PM To: m3devel Subject: [M3devel] typeid clash libm3\Formatter.m3: Int = REF INTEGER; ints: ARRAY [-256..256] OF Int; /* declare_subrange typeid:T69A2A904 domain_type:T195C2A74 min:-256 max:256 bit_size:16 */ libm3\Sx.m3 MinBoxedInt = -100; MaxBoxedInt = 100; BoxedInts := ARRAY [MinBoxedInt .. MaxBoxedInt] OF REF INTEGER {NIL, ..}; /* declare_subrange typeid:T69A2A904 domain_type:T195C2A74 min:-100 max:100 bit_size:8 */ Well that seems like a problem, eh? Two different types with the same type hash? They don't even have the same size (underlying representation). - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hendrik at topoi.pooq.com Wed Apr 14 15:26:59 2021 From: hendrik at topoi.pooq.com (Hendrik Boom) Date: Wed, 14 Apr 2021 09:26:59 -0400 Subject: [M3devel] typeid clash In-Reply-To: References: Message-ID: <20210414132658.k6ibuwwmdw5edh2u@topoi.pooq.com> On Wed, Apr 14, 2021 at 09:46:27AM +0000, Tony Hosking wrote: > Something has clearly broken here. > > Get Outlook for iOS > ________________________________ > From: M3devel on behalf of Jay K > Sent: Wednesday, April 14, 2021 5:23:03 PM > To: m3devel > Subject: [M3devel] typeid clash > > libm3\Formatter.m3: > Int = REF INTEGER; > ints: ARRAY [-256..256] OF Int; > > /* declare_subrange typeid:T69A2A904 domain_type:T195C2A74 min:-256 max:256 bit_size:16 */ > > libm3\Sx.m3 > > MinBoxedInt = -100; > MaxBoxedInt = 100; > BoxedInts := ARRAY [MinBoxedInt .. MaxBoxedInt] OF REF INTEGER {NIL, ..}; > > /* declare_subrange typeid:T69A2A904 domain_type:T195C2A74 min:-100 max:100 bit_size:8 */ > > Well that seems like a problem, eh? > > Two different types with the same type hash? > They don't even have the same size (underlying representation). Yes, a problem. It's either an amazing coincidence (in which case we should probably start using longer hashes to make it less likely to occur this millenium) or a bug in the hashing algorithm. -- hendrik > > - Jay > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://m3lists.elegosoft.com/mailman/listinfo/m3devel From jayk123 at hotmail.com Thu Apr 15 02:55:04 2021 From: jayk123 at hotmail.com (Jay K) Date: Thu, 15 Apr 2021 00:55:04 +0000 Subject: [M3devel] alignment problems In-Reply-To: References: Message-ID: Just keep waiting? ________________________________ From: Jay K Sent: Tuesday, April 13, 2021 7:04 AM To: rodney.m.bates at acm.org ; m3devel Subject: alignment problems Rodney, the system has not been buildable for quite some weeks now. Is it ok if I undo all your m3front changes and you can redo them when they work more completely? "..\src\maxflow\MFEdgeView.m3", line 17: ** INTERNAL CG ERROR *** stack not empty, depth (8) *** *** runtime error: *** <*ASSERT*> failed: top.depth = 0 *** file "../src/exprs/ArrayExpr.m3", line 2091 *** etc. I would also undo my workarounds related to arrays. I would also expect alignment of 64bit-sized types on 32bit targets to remain at 64bit, or at least for that to work, i.e. with the C backend. As it stands, the C backend can no longer target 32bit targets, which it was doing succcessfully for a long time. I hope to setup some CI before much longer so these regressions are not allowed or at least known ahead of time, but I have not gotten to it yet. Thank you, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Thu Apr 15 23:47:39 2021 From: jayk123 at hotmail.com (Jay K) Date: Thu, 15 Apr 2021 21:47:39 +0000 Subject: [M3devel] 8MB for tStamps? Message-ID: This usually unused large global array occupies 8MB of address space. Does it matter? Address space is fairly cheap and plentiful. It appears to be for benchmarking and by default is not used. Searching for 'tStamps'... C:\s\cm3\m3-libs\m3core\src\runtime\common\RTCollector.m3(676): tStamps[tsIndex] := t0; INC(tsIndex); C:\s\cm3\m3-libs\m3core\src\runtime\common\RTCollector.m3(677): tStamps[tsIndex] := t1; INC(tsIndex); C:\s\cm3\m3-libs\m3core\src\runtime\common\RTCollector.m3(2726): tStamps: ARRAY [0..1048575] OF Time.T; C:\s\cm3\m3-libs\m3core\src\runtime\common\RTCollector.m3(2748): RTIO.PutInt(TRUNC((tStamps[i+0] - tStart) * 1.0D6)); C:\s\cm3\m3-libs\m3core\src\runtime\common\RTCollector.m3(2750): RTIO.PutInt(TRUNC((tStamps[i+1] - tStart) * 1.0D6)); 5 occurrence(s) have been found. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Fri Apr 16 20:58:41 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 16 Apr 2021 13:58:41 -0500 Subject: [M3devel] alignment problems In-Reply-To: References: Message-ID: <4a454f98-aea2-d2aa-d068-3ad7a66a529d@lcwb.coop> The two failures compiling in the m3-demo group that I am aware of are now fixed in the truckee branch, a temporary one I created while travelling. I am back and will merge and retest. Are there any other compiler failures I haven't seen? On 4/13/21 2:04 AM, Jay K wrote: > Rodney, the system has not been buildable for quite some weeks now. > Is it ok if I undo all your m3front changes and you can redo them when they work more completely? > > "..\src\maxflow\MFEdgeView.m3", line 17: ** INTERNAL CG ERROR *** stack not empty, depth (8) > > *** > *** runtime error: > *** ? ?<*ASSERT*> failed: top.depth = 0 > *** ? ?file "../src/exprs/ArrayExpr.m3", line 2091 > *** > > etc. > > I would also undo my workarounds related to arrays. > I would also expect alignment of 64bit-sized types on 32bit targets to remain at 64bit, or at least for that to work, i.e. with the C backend. > As it stands, the C backend can no longer target 32bit targets, which it was doing succcessfully for a long time. > I hope to setup some CI before much longer so these regressions are not allowed or at least known ahead of time, but I have not gotten to it yet. > > Thank you, > ?- Jay > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://m3lists.elegosoft.com/mailman/listinfo/m3devel > -- Rodney Bates rodney.m.bates at acm.org From jayk123 at hotmail.com Fri Apr 16 21:08:02 2021 From: jayk123 at hotmail.com (Jay K) Date: Fri, 16 Apr 2021 19:08:02 +0000 Subject: [M3devel] alignment problems In-Reply-To: <4a454f98-aea2-d2aa-d068-3ad7a66a529d@lcwb.coop> References: , <4a454f98-aea2-d2aa-d068-3ad7a66a529d@lcwb.coop> Message-ID: Also the ability to have 64align of 64size on 32target? Also, maybe, the ?R2? thing I worked around? Was that code correct or not? Need to support it or not? - Jay ________________________________ From: Rodney M. Bates Sent: Friday, April 16, 2021 11:58:41 AM To: Jay K ; rodney.m.bates at acm.org ; m3devel Subject: Re: [M3devel] alignment problems The two failures compiling in the m3-demo group that I am aware of are now fixed in the truckee branch, a temporary one I created while travelling. I am back and will merge and retest. Are there any other compiler failures I haven't seen? On 4/13/21 2:04 AM, Jay K wrote: > Rodney, the system has not been buildable for quite some weeks now. > Is it ok if I undo all your m3front changes and you can redo them when they work more completely? > > "..\src\maxflow\MFEdgeView.m3", line 17: ** INTERNAL CG ERROR *** stack not empty, depth (8) > > *** > *** runtime error: > *** <*ASSERT*> failed: top.depth = 0 > *** file "../src/exprs/ArrayExpr.m3", line 2091 > *** > > etc. > > I would also undo my workarounds related to arrays. > I would also expect alignment of 64bit-sized types on 32bit targets to remain at 64bit, or at least for that to work, i.e. with the C backend. > As it stands, the C backend can no longer target 32bit targets, which it was doing succcessfully for a long time. > I hope to setup some CI before much longer so these regressions are not allowed or at least known ahead of time, but I have not gotten to it yet. > > Thank you, > - Jay > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Cc78db7a3af9e460f8ba508d90109b9ac%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637541963566243993%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=7ULhZPPfiC1heJ%2Bvv4JPvIg2QhZ1YG8CEh6zNtRM2aY%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Fri Apr 16 22:59:48 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 16 Apr 2021 15:59:48 -0500 Subject: [M3devel] m3core build failure Message-ID: <102454ac-e6d7-08cd-42b5-7d6c6e37ca79@lcwb.coop> rebuilding m3front, I get: new source -> compiling Umman.c In file included from ../src/unix/Common/Umman.c:6:0: ../src/unix/Common/Umman.c: In function ?char* Umman__mmap(caddr_t, WORD_T, int, int, int, m3_off_t)?: ../src/m3core.h:315:106: error: invalid conversion from ?void*? to ?ADDRESS {aka char*}? [-fpermissive] RAP6(ret, name, a, b, c, d, e, f) M3WRAP(ret, __##name, name, (a i, b j, c k, d m, e n, f o), (i, j, k, m ^ ../src/m3core.h:275:30: note: in definition of macro ?M3WRAP? return_value = cname out; \ ^ ../src/unix/Common/Umman.c:14:1: note: in expansion of macro ?M3WRAP6? M3WRAP6(ADDRESS, mmap, caddr_t, WORD_T, int, int, int, m3_off_t) ^ compile_c => 1 C compiler failed compiling: ../src/unix/Common/Umman.c -- Rodney Bates rodney.m.bates at acm.org From jayk123 at hotmail.com Sat Apr 17 00:07:45 2021 From: jayk123 at hotmail.com (Jay K) Date: Fri, 16 Apr 2021 22:07:45 +0000 Subject: [M3devel] m3core build failure In-Reply-To: <102454ac-e6d7-08cd-42b5-7d6c6e37ca79@lcwb.coop> References: <102454ac-e6d7-08cd-42b5-7d6c6e37ca79@lcwb.coop> Message-ID: Sorry, I thought I had fixed that already. It should be good now. - Jay ________________________________ From: M3devel on behalf of Rodney M. Bates Sent: Friday, April 16, 2021 8:59 PM To: m3devel Subject: [M3devel] m3core build failure rebuilding m3front, I get: new source -> compiling Umman.c In file included from ../src/unix/Common/Umman.c:6:0: ../src/unix/Common/Umman.c: In function ?char* Umman__mmap(caddr_t, WORD_T, int, int, int, m3_off_t)?: ../src/m3core.h:315:106: error: invalid conversion from ?void*? to ?ADDRESS {aka char*}? [-fpermissive] RAP6(ret, name, a, b, c, d, e, f) M3WRAP(ret, __##name, name, (a i, b j, c k, d m, e n, f o), (i, j, k, m ^ ../src/m3core.h:275:30: note: in definition of macro ?M3WRAP? return_value = cname out; \ ^ ../src/unix/Common/Umman.c:14:1: note: in expansion of macro ?M3WRAP6? M3WRAP6(ADDRESS, mmap, caddr_t, WORD_T, int, int, int, m3_off_t) ^ compile_c => 1 C compiler failed compiling: ../src/unix/Common/Umman.c -- Rodney Bates rodney.m.bates at acm.org _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C970d3f60990f46a0b90b08d9011ae54f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637542037299059612%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=VxPdjlkE9PxGjl8FxYBX4%2B1urx8LAxKDF8kV%2BN6mo6M%3D&reserved=0 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sat Apr 17 00:30:59 2021 From: jayk123 at hotmail.com (Jay K) Date: Fri, 16 Apr 2021 22:30:59 +0000 Subject: [M3devel] m3core build failure In-Reply-To: References: <102454ac-e6d7-08cd-42b5-7d6c6e37ca79@lcwb.coop>, Message-ID: oops it is still broken, I will fix ________________________________ From: Jay K Sent: Friday, April 16, 2021 10:07 PM To: m3devel ; rodney.m.bates at acm.org Subject: Re: [M3devel] m3core build failure Sorry, I thought I had fixed that already. It should be good now. - Jay ________________________________ From: M3devel on behalf of Rodney M. Bates Sent: Friday, April 16, 2021 8:59 PM To: m3devel Subject: [M3devel] m3core build failure rebuilding m3front, I get: new source -> compiling Umman.c In file included from ../src/unix/Common/Umman.c:6:0: ../src/unix/Common/Umman.c: In function ?char* Umman__mmap(caddr_t, WORD_T, int, int, int, m3_off_t)?: ../src/m3core.h:315:106: error: invalid conversion from ?void*? to ?ADDRESS {aka char*}? [-fpermissive] RAP6(ret, name, a, b, c, d, e, f) M3WRAP(ret, __##name, name, (a i, b j, c k, d m, e n, f o), (i, j, k, m ^ ../src/m3core.h:275:30: note: in definition of macro ?M3WRAP? return_value = cname out; \ ^ ../src/unix/Common/Umman.c:14:1: note: in expansion of macro ?M3WRAP6? M3WRAP6(ADDRESS, mmap, caddr_t, WORD_T, int, int, int, m3_off_t) ^ compile_c => 1 C compiler failed compiling: ../src/unix/Common/Umman.c -- Rodney Bates rodney.m.bates at acm.org _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7C970d3f60990f46a0b90b08d9011ae54f%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637542037299059612%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=VxPdjlkE9PxGjl8FxYBX4%2B1urx8LAxKDF8kV%2BN6mo6M%3D&reserved=0 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sat Apr 17 00:48:10 2021 From: jayk123 at hotmail.com (Jay K) Date: Fri, 16 Apr 2021 22:48:10 +0000 Subject: [M3devel] Scheduler.DisableSwitching? Message-ID: Can anyone remind us when/why Scheduler.DisableSwitching is needed? Obviously it is only for user threads. It does nothing for the others. I have a feeling, if it is needed, maybe we don't use it everywhere needed? Maybe it isn't really needed? We use it around some calls to C, but not all. Is it only for memory allocations? Or maybe only for functions that use errno or other globals? Well, errno is unfortunately widespread. Does anyone really use or care about user threads? The only hypotheticals in my mind or MS-DOS or any other system lacking native Win32/pthreads. User threads have "always" seemed like a bad idea to me, because I grew up after kernel threads were prevalent, and multi-processors were on the cusp of being widespread, and now are. Regarding multi-processors I understand there is the M:N model, which I still don't like, but I believe Modula-3 threads follow the 1:N model anyway -- one kernel thread, one CPU, N user threads, complete lack of actual concurrency, just a nice programming model. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sat Apr 17 02:32:00 2021 From: jayk123 at hotmail.com (Jay K) Date: Sat, 17 Apr 2021 00:32:00 +0000 Subject: [M3devel] alignment problems In-Reply-To: References: , <4a454f98-aea2-d2aa-d068-3ad7a66a529d@lcwb.coop>, Message-ID: Also this maybe? "../src/x-opengl/X_OpenGL_Base.m3", line 1157: actual not assignable to VALUE formal (2.3.2) (fn) "../src/x-opengl/X_OpenGL_Base.m3", line 1159: actual not assignable to VALUE formal (2.3.2) (fn) "../src/x-opengl/X_OpenGL_Base.m3", line 1161: actual not assignable to VALUE formal (2.3.2) (fn) 3 errors encountered Perhaps I broke that with the calling convention change? I'll check later. - Jay ________________________________ From: Jay K Sent: Friday, April 16, 2021 7:08 PM To: rodney.m.bates at acm.org ; m3devel Subject: Re: [M3devel] alignment problems Also the ability to have 64align of 64size on 32target? Also, maybe, the ?R2? thing I worked around? Was that code correct or not? Need to support it or not? - Jay ________________________________ From: Rodney M. Bates Sent: Friday, April 16, 2021 11:58:41 AM To: Jay K ; rodney.m.bates at acm.org ; m3devel Subject: Re: [M3devel] alignment problems The two failures compiling in the m3-demo group that I am aware of are now fixed in the truckee branch, a temporary one I created while travelling. I am back and will merge and retest. Are there any other compiler failures I haven't seen? On 4/13/21 2:04 AM, Jay K wrote: > Rodney, the system has not been buildable for quite some weeks now. > Is it ok if I undo all your m3front changes and you can redo them when they work more completely? > > "..\src\maxflow\MFEdgeView.m3", line 17: ** INTERNAL CG ERROR *** stack not empty, depth (8) > > *** > *** runtime error: > *** <*ASSERT*> failed: top.depth = 0 > *** file "../src/exprs/ArrayExpr.m3", line 2091 > *** > > etc. > > I would also undo my workarounds related to arrays. > I would also expect alignment of 64bit-sized types on 32bit targets to remain at 64bit, or at least for that to work, i.e. with the C backend. > As it stands, the C backend can no longer target 32bit targets, which it was doing succcessfully for a long time. > I hope to setup some CI before much longer so these regressions are not allowed or at least known ahead of time, but I have not gotten to it yet. > > Thank you, > - Jay > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Cc78db7a3af9e460f8ba508d90109b9ac%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637541963566243993%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=7ULhZPPfiC1heJ%2Bvv4JPvIg2QhZ1YG8CEh6zNtRM2aY%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Sat Apr 17 02:32:35 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 16 Apr 2021 19:32:35 -0500 Subject: [M3devel] alignment problems In-Reply-To: References: <4a454f98-aea2-d2aa-d068-3ad7a66a529d@lcwb.coop> Message-ID: On 4/16/21 2:08 PM, Jay K wrote: > Also the ability to have 64align of 64size on 32target? Well, if all those 32-bit targets do ensure segments, heap allocations, etc. are all 4-bit aligned, I would expect the front end would only need target descriptions of 64-bit scalar types to give 64-bit alignment to support those cases. There was a CG failure that I was unable to reproduce. Things were changing a lot then. From the symptom, I think it happened in the opposite situation when there is a 64-bit REAL with only 32-bit alignment, Is there such a target? I can look further if I can run a cross compiler for it. Or maybe see if I can find anything just looking at source code, without being able to test. Also, for all 64-bit types, the front end will produce IR operations giving 64-bit CG types (with whatever alignment), rather than lowering to multiple 32-bit operations. I presume the back ends handle this. > Also, maybe, the ?R2? thing I worked around? Was that code correct or not? Need to support it or not? The code was incorrect. It was trying to assign a 2 by 2, 2-dimensional array of REAL expression to a record constructor field of type R2, which is a 2-element, one-dimensional array of REAL. The rewrite you did fixed that, but also pulled the assignments out of the outer constructor, into separate assignment statements. The former is necessary, the latter not. I don't know how the original code should actually be changed to work correctly. It should now give a compile error, but not a CG failure. Just in passing, I observed there are two different interfaces with the same name and containing an R2. One is an array of 2 REALs, the other a record of 2 REALs. It turned out the failing case was the array, but not real easy to vet out. The array/record constructors for either meaning are syntactically identical, lacking either a '..' or a 'field:='. Syntactic explicitness sure simplifies understanding existing code, when you have it. > > - Jay > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Rodney M. Bates > *Sent:* Friday, April 16, 2021 11:58:41 AM > *To:* Jay K ; rodney.m.bates at acm.org ; m3devel > *Subject:* Re: [M3devel] alignment problems > The two failures compiling in the m3-demo group that I am aware of are > now fixed in the truckee branch, a temporary one I created while travelling. > I am back and will merge and retest. > > Are there any other compiler failures I haven't seen? > > On 4/13/21 2:04 AM, Jay K wrote: >> Rodney, the system has not been buildable for quite some weeks now. >> Is it ok if I undo all your m3front changes and you can redo them when they work more completely? >> >> "..\src\maxflow\MFEdgeView.m3", line 17: ** INTERNAL CG ERROR *** stack not empty, depth (8) >> >> *** >> *** runtime error: >> *** ? ?<*ASSERT*> failed: top.depth = 0 >> *** ? ?file "../src/exprs/ArrayExpr.m3", line 2091 >> *** >> >> etc. >> >> I would also undo my workarounds related to arrays. >> I would also expect alignment of 64bit-sized types on 32bit targets to remain at 64bit, or at least for that to work, i.e. with the C backend. >> As it stands, the C backend can no longer target 32bit targets, which it was doing succcessfully for a long time. >> I hope to setup some CI before much longer so these regressions are not allowed or at least known ahead of time, but I have not gotten to it yet. >> >> Thank you, >>? ?- Jay >> >> _______________________________________________ >> M3devel mailing list >> M3devel at elegosoft.com >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Cc78db7a3af9e460f8ba508d90109b9ac%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637541963566243993%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=7ULhZPPfiC1heJ%2Bvv4JPvIg2QhZ1YG8CEh6zNtRM2aY%3D&reserved=0 >> > > -- > Rodney Bates > rodney.m.bates at acm.org > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://m3lists.elegosoft.com/mailman/listinfo/m3devel > -- Rodney Bates rodney.m.bates at acm.org From jayk123 at hotmail.com Sat Apr 17 02:49:37 2021 From: jayk123 at hotmail.com (Jay K) Date: Sat, 17 Apr 2021 00:49:37 +0000 Subject: [M3devel] alignment problems In-Reply-To: References: <4a454f98-aea2-d2aa-d068-3ad7a66a529d@lcwb.coop> , Message-ID: As I have said, the globals and heap are generally handled. Locals maybe not, but that is good enough. You are conflating record layout with memory alignment. They are not quite the same thing. Granted, m3front only has one notion. ?REAL? is not the concern. The concern is LONGREAL and LONGINT. They always have size=64 and imho ought to have align=64. You don?t need a cross compiler to see this. Just try building m3core and/or libm3 with -DM3_BACKEND_MODE=C Or change Target.m3 back to what it was and build any 32bit target. The detailed codegen is not the problem. All the backends handled this for many years. The problem is that m3front now fails, since your recent changes. The backends all also handle 64bit operations. M3front should not split them up. Well sure this is fuzzy area as to division of labor. You could imagine either, or different backends having different requirements. But m3c, m3cc, m3x86 and presumably m3llvm all handle it. The IR is relatively high level in this respect. I added the support to m3x86 and it was not trivial. - Jay ________________________________ From: Rodney M. Bates Sent: Friday, April 16, 2021 5:33 PM To: Jay K; rodney.m.bates at acm.org; m3devel Subject: Re: [M3devel] alignment problems On 4/16/21 2:08 PM, Jay K wrote: > Also the ability to have 64align of 64size on 32target? Well, if all those 32-bit targets do ensure segments, heap allocations, etc. are all 4-bit aligned, I would expect the front end would only need target descriptions of 64-bit scalar types to give 64-bit alignment to support those cases. There was a CG failure that I was unable to reproduce. Things were changing a lot then. From the symptom, I think it happened in the opposite situation when there is a 64-bit REAL with only 32-bit alignment, Is there such a target? I can look further if I can run a cross compiler for it. Or maybe see if I can find anything just looking at source code, without being able to test. Also, for all 64-bit types, the front end will produce IR operations giving 64-bit CG types (with whatever alignment), rather than lowering to multiple 32-bit operations. I presume the back ends handle this. > Also, maybe, the ?R2? thing I worked around? Was that code correct or not? Need to support it or not? The code was incorrect. It was trying to assign a 2 by 2, 2-dimensional array of REAL expression to a record constructor field of type R2, which is a 2-element, one-dimensional array of REAL. The rewrite you did fixed that, but also pulled the assignments out of the outer constructor, into separate assignment statements. The former is necessary, the latter not. I don't know how the original code should actually be changed to work correctly. It should now give a compile error, but not a CG failure. Just in passing, I observed there are two different interfaces with the same name and containing an R2. One is an array of 2 REALs, the other a record of 2 REALs. It turned out the failing case was the array, but not real easy to vet out. The array/record constructors for either meaning are syntactically identical, lacking either a '..' or a 'field:='. Syntactic explicitness sure simplifies understanding existing code, when you have it. > > - Jay > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Rodney M. Bates > *Sent:* Friday, April 16, 2021 11:58:41 AM > *To:* Jay K ; rodney.m.bates at acm.org ; m3devel > *Subject:* Re: [M3devel] alignment problems > The two failures compiling in the m3-demo group that I am aware of are > now fixed in the truckee branch, a temporary one I created while travelling. > I am back and will merge and retest. > > Are there any other compiler failures I haven't seen? > > On 4/13/21 2:04 AM, Jay K wrote: >> Rodney, the system has not been buildable for quite some weeks now. >> Is it ok if I undo all your m3front changes and you can redo them when they work more completely? >> >> "..\src\maxflow\MFEdgeView.m3", line 17: ** INTERNAL CG ERROR *** stack not empty, depth (8) >> >> *** >> *** runtime error: >> *** <*ASSERT*> failed: top.depth = 0 >> *** file "../src/exprs/ArrayExpr.m3", line 2091 >> *** >> >> etc. >> >> I would also undo my workarounds related to arrays. >> I would also expect alignment of 64bit-sized types on 32bit targets to remain at 64bit, or at least for that to work, i.e. with the C backend. >> As it stands, the C backend can no longer target 32bit targets, which it was doing succcessfully for a long time. >> I hope to setup some CI before much longer so these regressions are not allowed or at least known ahead of time, but I have not gotten to it yet. >> >> Thank you, >> - Jay >> >> _______________________________________________ >> M3devel mailing list >> M3devel at elegosoft.com >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Ccc7c002cd93c4831df9208d901385bf3%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637542163832085225%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=0wEkXn9tSoHxPwtHtm1OXTDwo6or0OdGMliAIDO1V48%3D&reserved=0 >> > > -- > Rodney Bates > rodney.m.bates at acm.org > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Ccc7c002cd93c4831df9208d901385bf3%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637542163832085225%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=0wEkXn9tSoHxPwtHtm1OXTDwo6or0OdGMliAIDO1V48%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sat Apr 17 03:13:28 2021 From: jayk123 at hotmail.com (Jay K) Date: Sat, 17 Apr 2021 01:13:28 +0000 Subject: [M3devel] alignment problems In-Reply-To: References: <4a454f98-aea2-d2aa-d068-3ad7a66a529d@lcwb.coop> , , Message-ID: > You don?t need a cross compiler to see this. Just try building m3core and/or libm3 with -DM3_BACKEND_MODE=C ...m3core$ cm3 -DM3_BACKEND_MODE=C -DTARGET=I386_NT -boot --- building in I386_NT --- ignoring ../src/m3overrides new source -> compiling TextToFloat.m3 "../src/float/Common/TextToFloat.m3", line 345: ** INTERNAL CG ERROR *** unaligned partial-word load_indirect, type=LReel s/a=64/32 "../src/float/Common/TextToFloat.m3", line 351: ** INTERNAL CG ERROR *** unaligned partial-word load_indirect, type=LReel s/a=64/32 "../src/float/Common/TextToFloat.m3", line 351: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 3 errors encountered m3front failed compiling: ../src/float/Common/TextToFloat.m3 new source -> compiling Convert.m3 "../src/convert/Convert.m3", line 824: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 1 error encountered m3front failed compiling: ../src/convert/Convert.m3 **** PARALLEL BACK-END BUILD, M3_PARALLEL_BACK = 20 new exporters -> recompiling TextToFloat.i3 new exporters -> recompiling Convert.i3 compilation failed => not building library "m3core" Fatal Error: package build failed ...libm3$ cm3 -DM3_BACKEND_MODE=C -DTARGET=I386_NT -boot -x -DROOT=/mnt/c/s/cm3 --- building in I386_NT --- "../src/os/WIN32/FSWin32.m3", line 435: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 Addr ] "../src/os/WIN32/FSWin32.m3", line 436: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel s/a=64/32 "../src/os/WIN32/FSWin32.m3", line 447: ** INTERNAL CG ERROR *** unaligned partial-word load_indirect, type=LReel s/a=64/32 The reason for M3_BACKEND_MODE=C is a bit bogus and maybe temporary. I changed Target.m3 to put alignment back at 64 only for the C backend. I thought it worked. It is some sort of compromise with your desire for align=32. But Align=32 is still incorrect for "many" 32bit targets. Granted, it is also correct for many. It is correct for I386_LINUX and probably I386_UNIX in general. It is not correct for I386_NT nor most non-x86 32bit targets (ppc, sparc, mips). I'd really just like it to be 64 across all targets. As it was for a long time. - Jay ________________________________ From: M3devel on behalf of Jay K Sent: Saturday, April 17, 2021 12:49 AM To: rodney.m.bates at acm.org ; m3devel Subject: Re: [M3devel] alignment problems As I have said, the globals and heap are generally handled. Locals maybe not, but that is good enough. You are conflating record layout with memory alignment. They are not quite the same thing. Granted, m3front only has one notion. ?REAL? is not the concern. The concern is LONGREAL and LONGINT. They always have size=64 and imho ought to have align=64. You don?t need a cross compiler to see this. Just try building m3core and/or libm3 with -DM3_BACKEND_MODE=C Or change Target.m3 back to what it was and build any 32bit target. The detailed codegen is not the problem. All the backends handled this for many years. The problem is that m3front now fails, since your recent changes. The backends all also handle 64bit operations. M3front should not split them up. Well sure this is fuzzy area as to division of labor. You could imagine either, or different backends having different requirements. But m3c, m3cc, m3x86 and presumably m3llvm all handle it. The IR is relatively high level in this respect. I added the support to m3x86 and it was not trivial. - Jay ________________________________ From: Rodney M. Bates Sent: Friday, April 16, 2021 5:33 PM To: Jay K; rodney.m.bates at acm.org; m3devel Subject: Re: [M3devel] alignment problems On 4/16/21 2:08 PM, Jay K wrote: > Also the ability to have 64align of 64size on 32target? Well, if all those 32-bit targets do ensure segments, heap allocations, etc. are all 4-bit aligned, I would expect the front end would only need target descriptions of 64-bit scalar types to give 64-bit alignment to support those cases. There was a CG failure that I was unable to reproduce. Things were changing a lot then. From the symptom, I think it happened in the opposite situation when there is a 64-bit REAL with only 32-bit alignment, Is there such a target? I can look further if I can run a cross compiler for it. Or maybe see if I can find anything just looking at source code, without being able to test. Also, for all 64-bit types, the front end will produce IR operations giving 64-bit CG types (with whatever alignment), rather than lowering to multiple 32-bit operations. I presume the back ends handle this. > Also, maybe, the ?R2? thing I worked around? Was that code correct or not? Need to support it or not? The code was incorrect. It was trying to assign a 2 by 2, 2-dimensional array of REAL expression to a record constructor field of type R2, which is a 2-element, one-dimensional array of REAL. The rewrite you did fixed that, but also pulled the assignments out of the outer constructor, into separate assignment statements. The former is necessary, the latter not. I don't know how the original code should actually be changed to work correctly. It should now give a compile error, but not a CG failure. Just in passing, I observed there are two different interfaces with the same name and containing an R2. One is an array of 2 REALs, the other a record of 2 REALs. It turned out the failing case was the array, but not real easy to vet out. The array/record constructors for either meaning are syntactically identical, lacking either a '..' or a 'field:='. Syntactic explicitness sure simplifies understanding existing code, when you have it. > > - Jay > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Rodney M. Bates > *Sent:* Friday, April 16, 2021 11:58:41 AM > *To:* Jay K ; rodney.m.bates at acm.org ; m3devel > *Subject:* Re: [M3devel] alignment problems > The two failures compiling in the m3-demo group that I am aware of are > now fixed in the truckee branch, a temporary one I created while travelling. > I am back and will merge and retest. > > Are there any other compiler failures I haven't seen? > > On 4/13/21 2:04 AM, Jay K wrote: >> Rodney, the system has not been buildable for quite some weeks now. >> Is it ok if I undo all your m3front changes and you can redo them when they work more completely? >> >> "..\src\maxflow\MFEdgeView.m3", line 17: ** INTERNAL CG ERROR *** stack not empty, depth (8) >> >> *** >> *** runtime error: >> *** <*ASSERT*> failed: top.depth = 0 >> *** file "../src/exprs/ArrayExpr.m3", line 2091 >> *** >> >> etc. >> >> I would also undo my workarounds related to arrays. >> I would also expect alignment of 64bit-sized types on 32bit targets to remain at 64bit, or at least for that to work, i.e. with the C backend. >> As it stands, the C backend can no longer target 32bit targets, which it was doing succcessfully for a long time. >> I hope to setup some CI before much longer so these regressions are not allowed or at least known ahead of time, but I have not gotten to it yet. >> >> Thank you, >> - Jay >> >> _______________________________________________ >> M3devel mailing list >> M3devel at elegosoft.com >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Ccc7c002cd93c4831df9208d901385bf3%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637542163832085225%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=0wEkXn9tSoHxPwtHtm1OXTDwo6or0OdGMliAIDO1V48%3D&reserved=0 >> > > -- > Rodney Bates > rodney.m.bates at acm.org > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Ccc7c002cd93c4831df9208d901385bf3%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637542163832085225%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=0wEkXn9tSoHxPwtHtm1OXTDwo6or0OdGMliAIDO1V48%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sat Apr 17 03:18:14 2021 From: jayk123 at hotmail.com (Jay K) Date: Sat, 17 Apr 2021 01:18:14 +0000 Subject: [M3devel] Scheduler.DisableSwitching? In-Reply-To: References: , Message-ID: For an actual single processor (micro vm?) I imagine it is still quite close. But once you have multiple processors surely user threads lose handily. Granted, there are multi-process (process, not processor) workloads, which then have less sensitivity as to if each process needs threads or threads with concurrency. And then user threads have a sort of advantage, in that switching threads is cheaper. So then should we do anything? Part of me wants to simplify through deletion. But unused code isn't exactly complexity. But then, the original question: DisableSwitching more? Never? That is kinda the lurking problem. As to if we should care about DisableSwitching. - Jay ________________________________ From: Mika Nystrom Sent: Friday, April 16, 2021 11:28 PM To: Jay K Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? You said so yourself: just a nice programming model. User threads are nice when you have nothing else. It used to be that if you had only a single processor, or a few processors, and many threads, user threads were more efficient than kernel threads, but I think that is in the past now. Or at least the advantage is very small. Mika On Fri, Apr 16, 2021 at 3:49 PM Jay K > wrote: Can anyone remind us when/why Scheduler.DisableSwitching is needed? Obviously it is only for user threads. It does nothing for the others. I have a feeling, if it is needed, maybe we don't use it everywhere needed? Maybe it isn't really needed? We use it around some calls to C, but not all. Is it only for memory allocations? Or maybe only for functions that use errno or other globals? Well, errno is unfortunately widespread. Does anyone really use or care about user threads? The only hypotheticals in my mind or MS-DOS or any other system lacking native Win32/pthreads. User threads have "always" seemed like a bad idea to me, because I grew up after kernel threads were prevalent, and multi-processors were on the cusp of being widespread, and now are. Regarding multi-processors I understand there is the M:N model, which I still don't like, but I believe Modula-3 threads follow the 1:N model anyway -- one kernel thread, one CPU, N user threads, complete lack of actual concurrency, just a nice programming model. - Jay _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sat Apr 17 07:13:34 2021 From: jayk123 at hotmail.com (Jay K) Date: Sat, 17 Apr 2021 05:13:34 +0000 Subject: [M3devel] alignment problems In-Reply-To: References: , <4a454f98-aea2-d2aa-d068-3ad7a66a529d@lcwb.coop>, , Message-ID: This is mine. I'll fix. ________________________________ From: Jay K Sent: Saturday, April 17, 2021 12:32 AM To: rodney.m.bates at acm.org ; m3devel Subject: Re: [M3devel] alignment problems Also this maybe? "../src/x-opengl/X_OpenGL_Base.m3", line 1157: actual not assignable to VALUE formal (2.3.2) (fn) "../src/x-opengl/X_OpenGL_Base.m3", line 1159: actual not assignable to VALUE formal (2.3.2) (fn) "../src/x-opengl/X_OpenGL_Base.m3", line 1161: actual not assignable to VALUE formal (2.3.2) (fn) 3 errors encountered Perhaps I broke that with the calling convention change? I'll check later. - Jay ________________________________ From: Jay K Sent: Friday, April 16, 2021 7:08 PM To: rodney.m.bates at acm.org ; m3devel Subject: Re: [M3devel] alignment problems Also the ability to have 64align of 64size on 32target? Also, maybe, the ?R2? thing I worked around? Was that code correct or not? Need to support it or not? - Jay ________________________________ From: Rodney M. Bates Sent: Friday, April 16, 2021 11:58:41 AM To: Jay K ; rodney.m.bates at acm.org ; m3devel Subject: Re: [M3devel] alignment problems The two failures compiling in the m3-demo group that I am aware of are now fixed in the truckee branch, a temporary one I created while travelling. I am back and will merge and retest. Are there any other compiler failures I haven't seen? On 4/13/21 2:04 AM, Jay K wrote: > Rodney, the system has not been buildable for quite some weeks now. > Is it ok if I undo all your m3front changes and you can redo them when they work more completely? > > "..\src\maxflow\MFEdgeView.m3", line 17: ** INTERNAL CG ERROR *** stack not empty, depth (8) > > *** > *** runtime error: > *** <*ASSERT*> failed: top.depth = 0 > *** file "../src/exprs/ArrayExpr.m3", line 2091 > *** > > etc. > > I would also undo my workarounds related to arrays. > I would also expect alignment of 64bit-sized types on 32bit targets to remain at 64bit, or at least for that to work, i.e. with the C backend. > As it stands, the C backend can no longer target 32bit targets, which it was doing succcessfully for a long time. > I hope to setup some CI before much longer so these regressions are not allowed or at least known ahead of time, but I have not gotten to it yet. > > Thank you, > - Jay > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Cc78db7a3af9e460f8ba508d90109b9ac%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637541963566243993%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=7ULhZPPfiC1heJ%2Bvv4JPvIg2QhZ1YG8CEh6zNtRM2aY%3D&reserved=0 > -- Rodney Bates rodney.m.bates at acm.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Sun Apr 18 03:24:31 2021 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 17 Apr 2021 20:24:31 -0500 Subject: [M3devel] alignment problems In-Reply-To: References: <4a454f98-aea2-d2aa-d068-3ad7a66a529d@lcwb.coop> Message-ID: <91c1a7c9-d785-2793-4d0b-6b27d7cf3c10@lcwb.coop> On 4/16/21 8:13 PM, Jay K wrote: > ?> You don?t need a cross compiler to see this. Just try building m3core and/or libm3 with -DM3_BACKEND_MODE=C > > ...m3core$ cm3 -DM3_BACKEND_MODE=C -DTARGET=I386_NT -boot > --- building in I386_NT --- > > ignoring ../src/m3overrides OK, now I was able to reproduce the failures below. On Apr. 2, these did not fail for me. Commit 1effaa9 or maybe a merge predecessor has fixes. I was able to compile m3core and libm3 with cm3 -DM3_BACKEND_MODE=C -DTARGET=I386_NT > > new source -> compiling TextToFloat.m3 > "../src/float/Common/TextToFloat.m3", line 345: ** INTERNAL CG ERROR *** unaligned partial-word load_indirect, type=LReel ?s/a=64/32 > "../src/float/Common/TextToFloat.m3", line 351: ** INTERNAL CG ERROR *** unaligned partial-word load_indirect, type=LReel ?s/a=64/32 > "../src/float/Common/TextToFloat.m3", line 351: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel ?s/a=64/32 > 3 errors encountered > m3front failed compiling: ../src/float/Common/TextToFloat.m3 > new source -> compiling Convert.m3 > "../src/convert/Convert.m3", line 824: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel ?s/a=64/32 > 1 error encountered > m3front failed compiling: ../src/convert/Convert.m3 > **** ?PARALLEL BACK-END BUILD, M3_PARALLEL_BACK = 20 > new exporters -> recompiling TextToFloat.i3 > new exporters -> recompiling Convert.i3 > compilation failed => not building library "m3core" > Fatal Error: package build failed > > ...libm3$ cm3 -DM3_BACKEND_MODE=C -DTARGET=I386_NT -boot -x -DROOT=/mnt/c/s/cm3 > > --- building in I386_NT --- > > "../src/os/WIN32/FSWin32.m3", line 435: ********* M3CG_Check ERROR *********** bad stack: ?expected [ Int32 ? ? ? ?] got [ Int64 ?Addr ? ?] > "../src/os/WIN32/FSWin32.m3", line 436: ** INTERNAL CG ERROR *** unaligned partial-word store_indirect, type=LReel ?s/a=64/32 > "../src/os/WIN32/FSWin32.m3", line 447: ** INTERNAL CG ERROR *** unaligned partial-word load_indirect, type=LReel ?s/a=64/32 > > The reason for M3_BACKEND_MODE=C is a bit bogus and maybe temporary. > I changed Target.m3 to put alignment back at 64 only for the C backend. > I thought it worked. > It is some sort of compromise with your desire for align=32. > But Align=32 is still incorrect for "many" 32bit targets. > Granted, it is also correct for many. It is correct for I386_LINUX and probably I386_UNIX in general. > It is not correct for I386_NT nor most non-x86 32bit targets (ppc, sparc, mips). > I'd really just like it to be 64 across all targets. As it was for a long time. > > ?- Jay > > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* M3devel on behalf of Jay K > *Sent:* Saturday, April 17, 2021 12:49 AM > *To:* rodney.m.bates at acm.org ; m3devel > *Subject:* Re: [M3devel] alignment problems > As I have said, the globals and heap are generally handled. Locals maybe not, but that is good enough. You are conflating record layout with memory alignment. They are not quite the same thing. Granted, m3front only has one notion. > > ?REAL? is not the concern. > The concern is LONGREAL and LONGINT. > They always have size=64 and imho ought to have align=64. > You don?t need a cross compiler to see this. Just try building m3core and/or libm3 with -DM3_BACKEND_MODE=C > Or change Target.m3 back to what it was and build any 32bit target. > > The detailed codegen is not the problem. All the backends handled this for many years. The problem is that m3front now fails, since your recent changes. > > The backends all also handle 64bit operations. M3front should not split them up. Well sure this is fuzzy area as to division of labor. You could imagine either, or different backends having different requirements. But m3c, m3cc, m3x86 and presumably m3llvm all handle it. > The IR is relatively high level in this respect. > ?I added the support to m3x86 and it was not trivial. > > - Jay > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ > *From:* Rodney M. Bates > *Sent:* Friday, April 16, 2021 5:33 PM > *To:* Jay K; rodney.m.bates at acm.org; m3devel > *Subject:* Re: [M3devel] alignment problems > > > On 4/16/21 2:08 PM, Jay K wrote: >> Also the ability to have 64align of 64size on 32target? > > Well, if all those 32-bit targets do ensure segments, heap allocations, > etc. are all 4-bit aligned, I would expect the front end would only > need target descriptions of 64-bit scalar types to give 64-bit > alignment to support those cases. > > There was a CG failure that I was unable to reproduce.? Things > were changing a lot then.? From the symptom, I think it happened > in the opposite situation when there is a 64-bit REAL with only > 32-bit alignment,? Is there such a target?? I can look further > if I can run a cross compiler for it.? Or maybe see if I can find > anything just looking at source code, without being able to test. > > Also, for all 64-bit types, the front end will produce IR operations > giving 64-bit CG types (with whatever alignment), rather than lowering > to multiple 32-bit operations.? I presume the back ends handle this. > >> Also, maybe, the ?R2? thing I worked around? Was that code correct or not? Need to support it or not? > > The code was incorrect.? It was trying to assign a 2 by 2, 2-dimensional array > of REAL expression to a record constructor field of type R2, which is > a 2-element, one-dimensional array of REAL.? The rewrite you did > fixed that, but also pulled the assignments out of the > outer constructor, into separate assignment statements.? The former is > necessary, the latter not. > > I don't know how the original code should actually be changed to work > correctly.? It should now give a compile error, but not a CG failure. > > Just in passing, I observed there are two different interfaces with > the same name and containing an R2.? One is an array of 2 REALs, the > other a record of 2 REALs.? It turned out the failing case was the array, > but not real easy to vet out.? The array/record constructors for either > meaning are syntactically identical, lacking either a '..' or a 'field:='. > Syntactic explicitness sure simplifies understanding existing code, > when you have it. > >> >> - Jay >> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ >> *From:* Rodney M. Bates >> *Sent:* Friday, April 16, 2021 11:58:41 AM >> *To:* Jay K ; rodney.m.bates at acm.org ; m3devel >> *Subject:* Re: [M3devel] alignment problems >> The two failures compiling in the m3-demo group that I am aware of are >> now fixed in the truckee branch, a temporary one I created while travelling. >> I am back and will merge and retest. >> >> Are there any other compiler failures I haven't seen? >> >> On 4/13/21 2:04 AM, Jay K wrote: >>> Rodney, the system has not been buildable for quite some weeks now. >>> Is it ok if I undo all your m3front changes and you can redo them when they work more completely? >>> >>> "..\src\maxflow\MFEdgeView.m3", line 17: ** INTERNAL CG ERROR *** stack not empty, depth (8) >>> >>> *** >>> *** runtime error: >>> *** ? ?<*ASSERT*> failed: top.depth = 0 >>> *** ? ?file "../src/exprs/ArrayExpr.m3", line 2091 >>> *** >>> >>> etc. >>> >>> I would also undo my workarounds related to arrays. >>> I would also expect alignment of 64bit-sized types on 32bit targets to remain at 64bit, or at least for that to work, i.e. with the C backend. >>> As it stands, the C backend can no longer target 32bit targets, which it was doing succcessfully for a long time. >>> I hope to setup some CI before much longer so these regressions are not allowed or at least known ahead of time, but I have not gotten to it yet. >>> >>> Thank you, >>>? ?- Jay >>> >>> _______________________________________________ >>> M3devel mailing list >>> M3devel at elegosoft.com >>> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Ccc7c002cd93c4831df9208d901385bf3%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637542163832085225%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=0wEkXn9tSoHxPwtHtm1OXTDwo6or0OdGMliAIDO1V48%3D&reserved=0 >>> >> >> -- >> Rodney Bates >> rodney.m.bates at acm.org >> >> _______________________________________________ >> M3devel mailing list >> M3devel at elegosoft.com >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fm3lists.elegosoft.com%2Fmailman%2Flistinfo%2Fm3devel&data=04%7C01%7C%7Ccc7c002cd93c4831df9208d901385bf3%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637542163832085225%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=0wEkXn9tSoHxPwtHtm1OXTDwo6or0OdGMliAIDO1V48%3D&reserved=0 >> > > -- > Rodney Bates > rodney.m.bates at acm.org > > _______________________________________________ > M3devel mailing list > M3devel at elegosoft.com > https://m3lists.elegosoft.com/mailman/listinfo/m3devel > -- Rodney Bates rodney.m.bates at acm.org From antony.hosking at anu.edu.au Sun Apr 18 18:33:37 2021 From: antony.hosking at anu.edu.au (Tony Hosking) Date: Sun, 18 Apr 2021 16:33:37 +0000 Subject: [M3devel] Scheduler.DisableSwitching? In-Reply-To: References: , , Message-ID: Here be dragons. The user thread implementation effectively specified Modula-3 threading from its inception. The pthread and win32 thread implementations should remain faithful to that. In particular with respect to behavior of locks and condition variables. So, throwing out the user thread implementation erases the history. Regarding DisableSwitching, it is needed for libraries that are not thread-safe with respect to user level thread switching. Get Outlook for iOS ________________________________ From: M3devel on behalf of Jay K Sent: Saturday, April 17, 2021 11:18:14 AM To: Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? For an actual single processor (micro vm?) I imagine it is still quite close. But once you have multiple processors surely user threads lose handily. Granted, there are multi-process (process, not processor) workloads, which then have less sensitivity as to if each process needs threads or threads with concurrency. And then user threads have a sort of advantage, in that switching threads is cheaper. So then should we do anything? Part of me wants to simplify through deletion. But unused code isn't exactly complexity. But then, the original question: DisableSwitching more? Never? That is kinda the lurking problem. As to if we should care about DisableSwitching. - Jay ________________________________ From: Mika Nystrom Sent: Friday, April 16, 2021 11:28 PM To: Jay K Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? You said so yourself: just a nice programming model. User threads are nice when you have nothing else. It used to be that if you had only a single processor, or a few processors, and many threads, user threads were more efficient than kernel threads, but I think that is in the past now. Or at least the advantage is very small. Mika On Fri, Apr 16, 2021 at 3:49 PM Jay K > wrote: Can anyone remind us when/why Scheduler.DisableSwitching is needed? Obviously it is only for user threads. It does nothing for the others. I have a feeling, if it is needed, maybe we don't use it everywhere needed? Maybe it isn't really needed? We use it around some calls to C, but not all. Is it only for memory allocations? Or maybe only for functions that use errno or other globals? Well, errno is unfortunately widespread. Does anyone really use or care about user threads? The only hypotheticals in my mind or MS-DOS or any other system lacking native Win32/pthreads. User threads have "always" seemed like a bad idea to me, because I grew up after kernel threads were prevalent, and multi-processors were on the cusp of being widespread, and now are. Regarding multi-processors I understand there is the M:N model, which I still don't like, but I believe Modula-3 threads follow the 1:N model anyway -- one kernel thread, one CPU, N user threads, complete lack of actual concurrency, just a nice programming model. - Jay _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Fri Apr 23 08:42:43 2021 From: jayk123 at hotmail.com (Jay K) Date: Fri, 23 Apr 2021 06:42:43 +0000 Subject: [M3devel] Scheduler.DisableSwitching? In-Reply-To: References: , , , Message-ID: That is an interesting point. But at the same time, if Modula-3 threads are *approximately* pthreads and *approximately* Win32 threads (Vista and newer), it'd be really nice to thin out the implementations. They are kinda too large imho. Granted, I know even standard C++ library has a "thickness problem" on Win32. That Standard C++ threads almost line up with Win32 such that an implementation would just be a few one-liners, but not quite. How do they vary? As well, if we are commited to keeping user threads, I have long contended, they should be behind function pointers/vtable, switchable at startup, so pthreads and userthreads are always available in all executables, without a rebuild. (No change on systems that do not support userthreads, like current win32, though win32 surely could support them via fibers). A feature is not usable if it requires rebuilding the entire system. - Jay ________________________________ From: Tony Hosking Sent: Sunday, April 18, 2021 4:33 PM To: Jay K ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? Here be dragons. The user thread implementation effectively specified Modula-3 threading from its inception. The pthread and win32 thread implementations should remain faithful to that. In particular with respect to behavior of locks and condition variables. So, throwing out the user thread implementation erases the history. Regarding DisableSwitching, it is needed for libraries that are not thread-safe with respect to user level thread switching. Get Outlook for iOS ________________________________ From: M3devel on behalf of Jay K Sent: Saturday, April 17, 2021 11:18:14 AM To: Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? For an actual single processor (micro vm?) I imagine it is still quite close. But once you have multiple processors surely user threads lose handily. Granted, there are multi-process (process, not processor) workloads, which then have less sensitivity as to if each process needs threads or threads with concurrency. And then user threads have a sort of advantage, in that switching threads is cheaper. So then should we do anything? Part of me wants to simplify through deletion. But unused code isn't exactly complexity. But then, the original question: DisableSwitching more? Never? That is kinda the lurking problem. As to if we should care about DisableSwitching. - Jay ________________________________ From: Mika Nystrom Sent: Friday, April 16, 2021 11:28 PM To: Jay K Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? You said so yourself: just a nice programming model. User threads are nice when you have nothing else. It used to be that if you had only a single processor, or a few processors, and many threads, user threads were more efficient than kernel threads, but I think that is in the past now. Or at least the advantage is very small. Mika On Fri, Apr 16, 2021 at 3:49 PM Jay K > wrote: Can anyone remind us when/why Scheduler.DisableSwitching is needed? Obviously it is only for user threads. It does nothing for the others. I have a feeling, if it is needed, maybe we don't use it everywhere needed? Maybe it isn't really needed? We use it around some calls to C, but not all. Is it only for memory allocations? Or maybe only for functions that use errno or other globals? Well, errno is unfortunately widespread. Does anyone really use or care about user threads? The only hypotheticals in my mind or MS-DOS or any other system lacking native Win32/pthreads. User threads have "always" seemed like a bad idea to me, because I grew up after kernel threads were prevalent, and multi-processors were on the cusp of being widespread, and now are. Regarding multi-processors I understand there is the M:N model, which I still don't like, but I believe Modula-3 threads follow the 1:N model anyway -- one kernel thread, one CPU, N user threads, complete lack of actual concurrency, just a nice programming model. - Jay _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Fri Apr 23 09:20:26 2021 From: jayk123 at hotmail.com (Jay K) Date: Fri, 23 Apr 2021 07:20:26 +0000 Subject: [M3devel] .i3 files vs. actual C? Message-ID: Hi. So, I've been concatenating all the m3c output, with all the hand written .c/.h files, in the hopes of bootstrap being composed mainly of: cc cm3.c # just one large file or more likely: cc cm3.c -I. # just one large file ; but include dtoa.h and UerrorX.h. It does "almost" work already. Well, all the m3c output can be concatenated. But it turns out, the hand written C presents some problems. I kinda knew it. Specifically the .i3 files never really match C. They just come quite close. Integers have the right size and pointers line up with pointers. This is *not* to say the hand written C isn't quite good and useful. It has proven tremendously valuable to make the system tremendously easier to port and maintain. No more rewriting of each /usr/include. The tradeoff is clearly in favor of a small C layer. But when m3c declares extern functions, and the extern functions are actually seen, there are many mismatches. There are a few classes of mismatches. Modula-3 does not model C char's type. It ends up as signed char. C has three "char" types: plain, signed, unsigned, all different. Modula-3 does not have const. Modula-3 does not have void* per se. It has "address", which perhaps I messed up, and turned into char*. This could be my failing: Modula-3 typenames vs. Modula-3 typeids. TYPE Foo = record ... end; isn't Foo but a typeid. This might be m3c being incomplete, granted. So example(s) then: The .i3 leads to, on 64bit: typedef signed char INT8; typedef INT8 T66A2A904_8; typedef T66A2A904_8 * TAB374D58; INT64 Cstring__strlen(TAB374D58); but the function is actually: size_t Cstring__strlenstrlen(const char*); So neither the return type nor parameter type is correct. They are really very close, close enough for most purposes, but not quite matching, if you present the C compiler with both at the same time. There are problems with records. m3core.h duplicates anything from the .i3 files, like Date. The solution here is probably to make sure m3cg.typename works, and use ifndef so m3core.h dominates m3c output. Thoughts? Almost every function mismatches. An exception is empty parameter lists. I am skeptical that getting signatures to strictly agree is tenable. My inclination is: - Have m3cg know if a function is "external". - Wrap every external declaration in ifndef; so that m3core.h can come before. - When calling an external function, take its address, cast to C:() or C++:(...) like I already do for function pointers anyway (due to closures), and then pass the parameters we "know" to be correct, that we were already passing. Modula-3 calling Modula-3 is unaffected. Separate non-concatenated compilation is unaffected, but note that it is using incorrect prototypes too. The codebase is relatively unaffected, but that import_procedure is told if a function is exported. Alternatively I could teach m3c of all external functions in cm3 (not the entire system, just what makes up cm3). Non-option: Remove the C layer. It really is super valuable. I can try to revisit and make the m3c output match but it seems almost intractable. If I were to get the prototypes correct, then the parameters have to be cast. For example you cannot actually get a C char in Modula-3. Another way is to loosen the types of the C wrappers, like replace all char* with void* and then cast within the functions. This is almost the same casting to untyped function pointers. Thank you, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From antony.hosking at anu.edu.au Fri Apr 23 14:05:05 2021 From: antony.hosking at anu.edu.au (Tony Hosking) Date: Fri, 23 Apr 2021 12:05:05 +0000 Subject: [M3devel] Scheduler.DisableSwitching? In-Reply-To: References: , , , , Message-ID: You miss my point. Modula-3 threads have behavior that is more tightly specified than pthread or win32 threads. For example M3 threads on top of pthread are not simply a thin veneer. You can look through the history to see that initial attempts at a thin interface resulted in M3 failures. Get Outlook for iOS ________________________________ From: Jay K Sent: Friday, April 23, 2021 4:42:43 PM To: Tony Hosking ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? That is an interesting point. But at the same time, if Modula-3 threads are *approximately* pthreads and *approximately* Win32 threads (Vista and newer), it'd be really nice to thin out the implementations. They are kinda too large imho. Granted, I know even standard C++ library has a "thickness problem" on Win32. That Standard C++ threads almost line up with Win32 such that an implementation would just be a few one-liners, but not quite. How do they vary? As well, if we are commited to keeping user threads, I have long contended, they should be behind function pointers/vtable, switchable at startup, so pthreads and userthreads are always available in all executables, without a rebuild. (No change on systems that do not support userthreads, like current win32, though win32 surely could support them via fibers). A feature is not usable if it requires rebuilding the entire system. - Jay ________________________________ From: Tony Hosking Sent: Sunday, April 18, 2021 4:33 PM To: Jay K ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? Here be dragons. The user thread implementation effectively specified Modula-3 threading from its inception. The pthread and win32 thread implementations should remain faithful to that. In particular with respect to behavior of locks and condition variables. So, throwing out the user thread implementation erases the history. Regarding DisableSwitching, it is needed for libraries that are not thread-safe with respect to user level thread switching. Get Outlook for iOS ________________________________ From: M3devel on behalf of Jay K Sent: Saturday, April 17, 2021 11:18:14 AM To: Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? For an actual single processor (micro vm?) I imagine it is still quite close. But once you have multiple processors surely user threads lose handily. Granted, there are multi-process (process, not processor) workloads, which then have less sensitivity as to if each process needs threads or threads with concurrency. And then user threads have a sort of advantage, in that switching threads is cheaper. So then should we do anything? Part of me wants to simplify through deletion. But unused code isn't exactly complexity. But then, the original question: DisableSwitching more? Never? That is kinda the lurking problem. As to if we should care about DisableSwitching. - Jay ________________________________ From: Mika Nystrom Sent: Friday, April 16, 2021 11:28 PM To: Jay K Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? You said so yourself: just a nice programming model. User threads are nice when you have nothing else. It used to be that if you had only a single processor, or a few processors, and many threads, user threads were more efficient than kernel threads, but I think that is in the past now. Or at least the advantage is very small. Mika On Fri, Apr 16, 2021 at 3:49 PM Jay K > wrote: Can anyone remind us when/why Scheduler.DisableSwitching is needed? Obviously it is only for user threads. It does nothing for the others. I have a feeling, if it is needed, maybe we don't use it everywhere needed? Maybe it isn't really needed? We use it around some calls to C, but not all. Is it only for memory allocations? Or maybe only for functions that use errno or other globals? Well, errno is unfortunately widespread. Does anyone really use or care about user threads? The only hypotheticals in my mind or MS-DOS or any other system lacking native Win32/pthreads. User threads have "always" seemed like a bad idea to me, because I grew up after kernel threads were prevalent, and multi-processors were on the cusp of being widespread, and now are. Regarding multi-processors I understand there is the M:N model, which I still don't like, but I believe Modula-3 threads follow the 1:N model anyway -- one kernel thread, one CPU, N user threads, complete lack of actual concurrency, just a nice programming model. - Jay _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Fri Apr 23 23:48:45 2021 From: jayk123 at hotmail.com (Jay K) Date: Fri, 23 Apr 2021 21:48:45 +0000 Subject: [M3devel] Scheduler.DisableSwitching? In-Reply-To: References: , , , , , Message-ID: How so? Guaranteed ordering of unlock or signal? Probably a bad idea. Alert feature? Yeah, could be, at least on Pthreads, not Win32. - Jay ________________________________ From: Tony Hosking Sent: Friday, April 23, 2021 12:05 PM To: Jay K ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? You miss my point. Modula-3 threads have behavior that is more tightly specified than pthread or win32 threads. For example M3 threads on top of pthread are not simply a thin veneer. You can look through the history to see that initial attempts at a thin interface resulted in M3 failures. Get Outlook for iOS ________________________________ From: Jay K Sent: Friday, April 23, 2021 4:42:43 PM To: Tony Hosking ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? That is an interesting point. But at the same time, if Modula-3 threads are *approximately* pthreads and *approximately* Win32 threads (Vista and newer), it'd be really nice to thin out the implementations. They are kinda too large imho. Granted, I know even standard C++ library has a "thickness problem" on Win32. That Standard C++ threads almost line up with Win32 such that an implementation would just be a few one-liners, but not quite. How do they vary? As well, if we are commited to keeping user threads, I have long contended, they should be behind function pointers/vtable, switchable at startup, so pthreads and userthreads are always available in all executables, without a rebuild. (No change on systems that do not support userthreads, like current win32, though win32 surely could support them via fibers). A feature is not usable if it requires rebuilding the entire system. - Jay ________________________________ From: Tony Hosking Sent: Sunday, April 18, 2021 4:33 PM To: Jay K ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? Here be dragons. The user thread implementation effectively specified Modula-3 threading from its inception. The pthread and win32 thread implementations should remain faithful to that. In particular with respect to behavior of locks and condition variables. So, throwing out the user thread implementation erases the history. Regarding DisableSwitching, it is needed for libraries that are not thread-safe with respect to user level thread switching. Get Outlook for iOS ________________________________ From: M3devel on behalf of Jay K Sent: Saturday, April 17, 2021 11:18:14 AM To: Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? For an actual single processor (micro vm?) I imagine it is still quite close. But once you have multiple processors surely user threads lose handily. Granted, there are multi-process (process, not processor) workloads, which then have less sensitivity as to if each process needs threads or threads with concurrency. And then user threads have a sort of advantage, in that switching threads is cheaper. So then should we do anything? Part of me wants to simplify through deletion. But unused code isn't exactly complexity. But then, the original question: DisableSwitching more? Never? That is kinda the lurking problem. As to if we should care about DisableSwitching. - Jay ________________________________ From: Mika Nystrom Sent: Friday, April 16, 2021 11:28 PM To: Jay K Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? You said so yourself: just a nice programming model. User threads are nice when you have nothing else. It used to be that if you had only a single processor, or a few processors, and many threads, user threads were more efficient than kernel threads, but I think that is in the past now. Or at least the advantage is very small. Mika On Fri, Apr 16, 2021 at 3:49 PM Jay K > wrote: Can anyone remind us when/why Scheduler.DisableSwitching is needed? Obviously it is only for user threads. It does nothing for the others. I have a feeling, if it is needed, maybe we don't use it everywhere needed? Maybe it isn't really needed? We use it around some calls to C, but not all. Is it only for memory allocations? Or maybe only for functions that use errno or other globals? Well, errno is unfortunately widespread. Does anyone really use or care about user threads? The only hypotheticals in my mind or MS-DOS or any other system lacking native Win32/pthreads. User threads have "always" seemed like a bad idea to me, because I grew up after kernel threads were prevalent, and multi-processors were on the cusp of being widespread, and now are. Regarding multi-processors I understand there is the M:N model, which I still don't like, but I believe Modula-3 threads follow the 1:N model anyway -- one kernel thread, one CPU, N user threads, complete lack of actual concurrency, just a nice programming model. - Jay _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From antony.hosking at anu.edu.au Sat Apr 24 00:20:41 2021 From: antony.hosking at anu.edu.au (Tony Hosking) Date: Fri, 23 Apr 2021 22:20:41 +0000 Subject: [M3devel] Scheduler.DisableSwitching? In-Reply-To: References: , , , , , , Message-ID: Yes, I seem to recall conditions and alerts have interactions needing care. Get Outlook for iOS ________________________________ From: Jay K Sent: Saturday, April 24, 2021 7:48:45 AM To: Tony Hosking ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? How so? Guaranteed ordering of unlock or signal? Probably a bad idea. Alert feature? Yeah, could be, at least on Pthreads, not Win32. - Jay ________________________________ From: Tony Hosking Sent: Friday, April 23, 2021 12:05 PM To: Jay K ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? You miss my point. Modula-3 threads have behavior that is more tightly specified than pthread or win32 threads. For example M3 threads on top of pthread are not simply a thin veneer. You can look through the history to see that initial attempts at a thin interface resulted in M3 failures. Get Outlook for iOS ________________________________ From: Jay K Sent: Friday, April 23, 2021 4:42:43 PM To: Tony Hosking ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? That is an interesting point. But at the same time, if Modula-3 threads are *approximately* pthreads and *approximately* Win32 threads (Vista and newer), it'd be really nice to thin out the implementations. They are kinda too large imho. Granted, I know even standard C++ library has a "thickness problem" on Win32. That Standard C++ threads almost line up with Win32 such that an implementation would just be a few one-liners, but not quite. How do they vary? As well, if we are commited to keeping user threads, I have long contended, they should be behind function pointers/vtable, switchable at startup, so pthreads and userthreads are always available in all executables, without a rebuild. (No change on systems that do not support userthreads, like current win32, though win32 surely could support them via fibers). A feature is not usable if it requires rebuilding the entire system. - Jay ________________________________ From: Tony Hosking Sent: Sunday, April 18, 2021 4:33 PM To: Jay K ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? Here be dragons. The user thread implementation effectively specified Modula-3 threading from its inception. The pthread and win32 thread implementations should remain faithful to that. In particular with respect to behavior of locks and condition variables. So, throwing out the user thread implementation erases the history. Regarding DisableSwitching, it is needed for libraries that are not thread-safe with respect to user level thread switching. Get Outlook for iOS ________________________________ From: M3devel on behalf of Jay K Sent: Saturday, April 17, 2021 11:18:14 AM To: Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? For an actual single processor (micro vm?) I imagine it is still quite close. But once you have multiple processors surely user threads lose handily. Granted, there are multi-process (process, not processor) workloads, which then have less sensitivity as to if each process needs threads or threads with concurrency. And then user threads have a sort of advantage, in that switching threads is cheaper. So then should we do anything? Part of me wants to simplify through deletion. But unused code isn't exactly complexity. But then, the original question: DisableSwitching more? Never? That is kinda the lurking problem. As to if we should care about DisableSwitching. - Jay ________________________________ From: Mika Nystrom Sent: Friday, April 16, 2021 11:28 PM To: Jay K Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? You said so yourself: just a nice programming model. User threads are nice when you have nothing else. It used to be that if you had only a single processor, or a few processors, and many threads, user threads were more efficient than kernel threads, but I think that is in the past now. Or at least the advantage is very small. Mika On Fri, Apr 16, 2021 at 3:49 PM Jay K > wrote: Can anyone remind us when/why Scheduler.DisableSwitching is needed? Obviously it is only for user threads. It does nothing for the others. I have a feeling, if it is needed, maybe we don't use it everywhere needed? Maybe it isn't really needed? We use it around some calls to C, but not all. Is it only for memory allocations? Or maybe only for functions that use errno or other globals? Well, errno is unfortunately widespread. Does anyone really use or care about user threads? The only hypotheticals in my mind or MS-DOS or any other system lacking native Win32/pthreads. User threads have "always" seemed like a bad idea to me, because I grew up after kernel threads were prevalent, and multi-processors were on the cusp of being widespread, and now are. Regarding multi-processors I understand there is the M:N model, which I still don't like, but I believe Modula-3 threads follow the 1:N model anyway -- one kernel thread, one CPU, N user threads, complete lack of actual concurrency, just a nice programming model. - Jay _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From antony.hosking at anu.edu.au Sat Apr 24 04:39:42 2021 From: antony.hosking at anu.edu.au (Tony Hosking) Date: Sat, 24 Apr 2021 02:39:42 +0000 Subject: [M3devel] Scheduler.DisableSwitching? In-Reply-To: References: , Message-ID: I think so. But I took multiple attempts to get alerts right with as thin a layer over pthreads as I could. Get Outlook for iOS ________________________________ From: Mika Nystrom Sent: Saturday, April 24, 2021 8:22:46 AM To: Tony Hosking Cc: Jay K ; m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? Historically I think alerts were the biggest problem. Isn't that where they found the bug using ESC? On Fri, Apr 23, 2021 at 3:20 PM Tony Hosking > wrote: Yes, I seem to recall conditions and alerts have interactions needing care. Get Outlook for iOS ________________________________ From: Jay K > Sent: Saturday, April 24, 2021 7:48:45 AM To: Tony Hosking >; Mika Nystrom > Cc: m3devel > Subject: Re: [M3devel] Scheduler.DisableSwitching? How so? Guaranteed ordering of unlock or signal? Probably a bad idea. Alert feature? Yeah, could be, at least on Pthreads, not Win32. - Jay ________________________________ From: Tony Hosking > Sent: Friday, April 23, 2021 12:05 PM To: Jay K >; Mika Nystrom > Cc: m3devel > Subject: Re: [M3devel] Scheduler.DisableSwitching? You miss my point. Modula-3 threads have behavior that is more tightly specified than pthread or win32 threads. For example M3 threads on top of pthread are not simply a thin veneer. You can look through the history to see that initial attempts at a thin interface resulted in M3 failures. Get Outlook for iOS ________________________________ From: Jay K > Sent: Friday, April 23, 2021 4:42:43 PM To: Tony Hosking >; Mika Nystrom > Cc: m3devel > Subject: Re: [M3devel] Scheduler.DisableSwitching? That is an interesting point. But at the same time, if Modula-3 threads are *approximately* pthreads and *approximately* Win32 threads (Vista and newer), it'd be really nice to thin out the implementations. They are kinda too large imho. Granted, I know even standard C++ library has a "thickness problem" on Win32. That Standard C++ threads almost line up with Win32 such that an implementation would just be a few one-liners, but not quite. How do they vary? As well, if we are commited to keeping user threads, I have long contended, they should be behind function pointers/vtable, switchable at startup, so pthreads and userthreads are always available in all executables, without a rebuild. (No change on systems that do not support userthreads, like current win32, though win32 surely could support them via fibers). A feature is not usable if it requires rebuilding the entire system. - Jay ________________________________ From: Tony Hosking > Sent: Sunday, April 18, 2021 4:33 PM To: Jay K >; Mika Nystrom > Cc: m3devel > Subject: Re: [M3devel] Scheduler.DisableSwitching? Here be dragons. The user thread implementation effectively specified Modula-3 threading from its inception. The pthread and win32 thread implementations should remain faithful to that. In particular with respect to behavior of locks and condition variables. So, throwing out the user thread implementation erases the history. Regarding DisableSwitching, it is needed for libraries that are not thread-safe with respect to user level thread switching. Get Outlook for iOS ________________________________ From: M3devel > on behalf of Jay K > Sent: Saturday, April 17, 2021 11:18:14 AM To: Mika Nystrom > Cc: m3devel > Subject: Re: [M3devel] Scheduler.DisableSwitching? For an actual single processor (micro vm?) I imagine it is still quite close. But once you have multiple processors surely user threads lose handily. Granted, there are multi-process (process, not processor) workloads, which then have less sensitivity as to if each process needs threads or threads with concurrency. And then user threads have a sort of advantage, in that switching threads is cheaper. So then should we do anything? Part of me wants to simplify through deletion. But unused code isn't exactly complexity. But then, the original question: DisableSwitching more? Never? That is kinda the lurking problem. As to if we should care about DisableSwitching. - Jay ________________________________ From: Mika Nystrom > Sent: Friday, April 16, 2021 11:28 PM To: Jay K > Cc: m3devel > Subject: Re: [M3devel] Scheduler.DisableSwitching? You said so yourself: just a nice programming model. User threads are nice when you have nothing else. It used to be that if you had only a single processor, or a few processors, and many threads, user threads were more efficient than kernel threads, but I think that is in the past now. Or at least the advantage is very small. Mika On Fri, Apr 16, 2021 at 3:49 PM Jay K > wrote: Can anyone remind us when/why Scheduler.DisableSwitching is needed? Obviously it is only for user threads. It does nothing for the others. I have a feeling, if it is needed, maybe we don't use it everywhere needed? Maybe it isn't really needed? We use it around some calls to C, but not all. Is it only for memory allocations? Or maybe only for functions that use errno or other globals? Well, errno is unfortunately widespread. Does anyone really use or care about user threads? The only hypotheticals in my mind or MS-DOS or any other system lacking native Win32/pthreads. User threads have "always" seemed like a bad idea to me, because I grew up after kernel threads were prevalent, and multi-processors were on the cusp of being widespread, and now are. Regarding multi-processors I understand there is the M:N model, which I still don't like, but I believe Modula-3 threads follow the 1:N model anyway -- one kernel thread, one CPU, N user threads, complete lack of actual concurrency, just a nice programming model. - Jay _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sat Apr 24 06:09:27 2021 From: jayk123 at hotmail.com (Jay K) Date: Sat, 24 Apr 2021 04:09:27 +0000 Subject: [M3devel] Scheduler.DisableSwitching? In-Reply-To: References: , , , , , , , Message-ID: Alert is maybe maybe pthread_cancel? - Jay ________________________________ From: Tony Hosking Sent: Friday, April 23, 2021 3:20:41 PM To: Jay K ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? Yes, I seem to recall conditions and alerts have interactions needing care. Get Outlook for iOS ________________________________ From: Jay K Sent: Saturday, April 24, 2021 7:48:45 AM To: Tony Hosking ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? How so? Guaranteed ordering of unlock or signal? Probably a bad idea. Alert feature? Yeah, could be, at least on Pthreads, not Win32. - Jay ________________________________ From: Tony Hosking Sent: Friday, April 23, 2021 12:05 PM To: Jay K ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? You miss my point. Modula-3 threads have behavior that is more tightly specified than pthread or win32 threads. For example M3 threads on top of pthread are not simply a thin veneer. You can look through the history to see that initial attempts at a thin interface resulted in M3 failures. Get Outlook for iOS ________________________________ From: Jay K Sent: Friday, April 23, 2021 4:42:43 PM To: Tony Hosking ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? That is an interesting point. But at the same time, if Modula-3 threads are *approximately* pthreads and *approximately* Win32 threads (Vista and newer), it'd be really nice to thin out the implementations. They are kinda too large imho. Granted, I know even standard C++ library has a "thickness problem" on Win32. That Standard C++ threads almost line up with Win32 such that an implementation would just be a few one-liners, but not quite. How do they vary? As well, if we are commited to keeping user threads, I have long contended, they should be behind function pointers/vtable, switchable at startup, so pthreads and userthreads are always available in all executables, without a rebuild. (No change on systems that do not support userthreads, like current win32, though win32 surely could support them via fibers). A feature is not usable if it requires rebuilding the entire system. - Jay ________________________________ From: Tony Hosking Sent: Sunday, April 18, 2021 4:33 PM To: Jay K ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? Here be dragons. The user thread implementation effectively specified Modula-3 threading from its inception. The pthread and win32 thread implementations should remain faithful to that. In particular with respect to behavior of locks and condition variables. So, throwing out the user thread implementation erases the history. Regarding DisableSwitching, it is needed for libraries that are not thread-safe with respect to user level thread switching. Get Outlook for iOS ________________________________ From: M3devel on behalf of Jay K Sent: Saturday, April 17, 2021 11:18:14 AM To: Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? For an actual single processor (micro vm?) I imagine it is still quite close. But once you have multiple processors surely user threads lose handily. Granted, there are multi-process (process, not processor) workloads, which then have less sensitivity as to if each process needs threads or threads with concurrency. And then user threads have a sort of advantage, in that switching threads is cheaper. So then should we do anything? Part of me wants to simplify through deletion. But unused code isn't exactly complexity. But then, the original question: DisableSwitching more? Never? That is kinda the lurking problem. As to if we should care about DisableSwitching. - Jay ________________________________ From: Mika Nystrom Sent: Friday, April 16, 2021 11:28 PM To: Jay K Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? You said so yourself: just a nice programming model. User threads are nice when you have nothing else. It used to be that if you had only a single processor, or a few processors, and many threads, user threads were more efficient than kernel threads, but I think that is in the past now. Or at least the advantage is very small. Mika On Fri, Apr 16, 2021 at 3:49 PM Jay K > wrote: Can anyone remind us when/why Scheduler.DisableSwitching is needed? Obviously it is only for user threads. It does nothing for the others. I have a feeling, if it is needed, maybe we don't use it everywhere needed? Maybe it isn't really needed? We use it around some calls to C, but not all. Is it only for memory allocations? Or maybe only for functions that use errno or other globals? Well, errno is unfortunately widespread. Does anyone really use or care about user threads? The only hypotheticals in my mind or MS-DOS or any other system lacking native Win32/pthreads. User threads have "always" seemed like a bad idea to me, because I grew up after kernel threads were prevalent, and multi-processors were on the cusp of being widespread, and now are. Regarding multi-processors I understand there is the M:N model, which I still don't like, but I believe Modula-3 threads follow the 1:N model anyway -- one kernel thread, one CPU, N user threads, complete lack of actual concurrency, just a nice programming model. - Jay _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From antony.hosking at anu.edu.au Sat Apr 24 11:13:07 2021 From: antony.hosking at anu.edu.au (Tony Hosking) Date: Sat, 24 Apr 2021 09:13:07 +0000 Subject: [M3devel] Scheduler.DisableSwitching? In-Reply-To: References: , , , , , , , , Message-ID: Nope. That kills the thread. From: Jay K Date: Saturday, April 24, 2021 at 2:09 PM To: Tony Hosking , Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? Alert is maybe maybe pthread_cancel? - Jay ________________________________ From: Tony Hosking Sent: Friday, April 23, 2021 3:20:41 PM To: Jay K ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? Yes, I seem to recall conditions and alerts have interactions needing care. Get Outlook for iOS ________________________________ From: Jay K Sent: Saturday, April 24, 2021 7:48:45 AM To: Tony Hosking ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? How so? Guaranteed ordering of unlock or signal? Probably a bad idea. Alert feature? Yeah, could be, at least on Pthreads, not Win32. - Jay ________________________________ From: Tony Hosking Sent: Friday, April 23, 2021 12:05 PM To: Jay K ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? You miss my point. Modula-3 threads have behavior that is more tightly specified than pthread or win32 threads. For example M3 threads on top of pthread are not simply a thin veneer. You can look through the history to see that initial attempts at a thin interface resulted in M3 failures. Get Outlook for iOS ________________________________ From: Jay K Sent: Friday, April 23, 2021 4:42:43 PM To: Tony Hosking ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? That is an interesting point. But at the same time, if Modula-3 threads are *approximately* pthreads and *approximately* Win32 threads (Vista and newer), it'd be really nice to thin out the implementations. They are kinda too large imho. Granted, I know even standard C++ library has a "thickness problem" on Win32. That Standard C++ threads almost line up with Win32 such that an implementation would just be a few one-liners, but not quite. How do they vary? As well, if we are commited to keeping user threads, I have long contended, they should be behind function pointers/vtable, switchable at startup, so pthreads and userthreads are always available in all executables, without a rebuild. (No change on systems that do not support userthreads, like current win32, though win32 surely could support them via fibers). A feature is not usable if it requires rebuilding the entire system. - Jay ________________________________ From: Tony Hosking Sent: Sunday, April 18, 2021 4:33 PM To: Jay K ; Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? Here be dragons. The user thread implementation effectively specified Modula-3 threading from its inception. The pthread and win32 thread implementations should remain faithful to that. In particular with respect to behavior of locks and condition variables. So, throwing out the user thread implementation erases the history. Regarding DisableSwitching, it is needed for libraries that are not thread-safe with respect to user level thread switching. Get Outlook for iOS ________________________________ From: M3devel on behalf of Jay K Sent: Saturday, April 17, 2021 11:18:14 AM To: Mika Nystrom Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? For an actual single processor (micro vm?) I imagine it is still quite close. But once you have multiple processors surely user threads lose handily. Granted, there are multi-process (process, not processor) workloads, which then have less sensitivity as to if each process needs threads or threads with concurrency. And then user threads have a sort of advantage, in that switching threads is cheaper. So then should we do anything? Part of me wants to simplify through deletion. But unused code isn't exactly complexity. But then, the original question: DisableSwitching more? Never? That is kinda the lurking problem. As to if we should care about DisableSwitching. - Jay ________________________________ From: Mika Nystrom Sent: Friday, April 16, 2021 11:28 PM To: Jay K Cc: m3devel Subject: Re: [M3devel] Scheduler.DisableSwitching? You said so yourself: just a nice programming model. User threads are nice when you have nothing else. It used to be that if you had only a single processor, or a few processors, and many threads, user threads were more efficient than kernel threads, but I think that is in the past now. Or at least the advantage is very small. Mika On Fri, Apr 16, 2021 at 3:49 PM Jay K > wrote: Can anyone remind us when/why Scheduler.DisableSwitching is needed? Obviously it is only for user threads. It does nothing for the others. I have a feeling, if it is needed, maybe we don't use it everywhere needed? Maybe it isn't really needed? We use it around some calls to C, but not all. Is it only for memory allocations? Or maybe only for functions that use errno or other globals? Well, errno is unfortunately widespread. Does anyone really use or care about user threads? The only hypotheticals in my mind or MS-DOS or any other system lacking native Win32/pthreads. User threads have "always" seemed like a bad idea to me, because I grew up after kernel threads were prevalent, and multi-processors were on the cusp of being widespread, and now are. Regarding multi-processors I understand there is the M:N model, which I still don't like, but I believe Modula-3 threads follow the 1:N model anyway -- one kernel thread, one CPU, N user threads, complete lack of actual concurrency, just a nice programming model. - Jay _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sun Apr 25 08:18:18 2021 From: jayk123 at hotmail.com (Jay K) Date: Sun, 25 Apr 2021 06:18:18 +0000 Subject: [M3devel] .i3 files vs. actual C? In-Reply-To: References: Message-ID: Having just started that solution, of generating a bunch of casts and/or through macros, I didn't like it. I'll try to get the signatures to match. - Jay ________________________________ From: Jay K Sent: Friday, April 23, 2021 7:20 AM To: m3devel Subject: .i3 files vs. actual C? Hi. So, I've been concatenating all the m3c output, with all the hand written .c/.h files, in the hopes of bootstrap being composed mainly of: cc cm3.c # just one large file or more likely: cc cm3.c -I. # just one large file ; but include dtoa.h and UerrorX.h. It does "almost" work already. Well, all the m3c output can be concatenated. But it turns out, the hand written C presents some problems. I kinda knew it. Specifically the .i3 files never really match C. They just come quite close. Integers have the right size and pointers line up with pointers. This is *not* to say the hand written C isn't quite good and useful. It has proven tremendously valuable to make the system tremendously easier to port and maintain. No more rewriting of each /usr/include. The tradeoff is clearly in favor of a small C layer. But when m3c declares extern functions, and the extern functions are actually seen, there are many mismatches. There are a few classes of mismatches. Modula-3 does not model C char's type. It ends up as signed char. C has three "char" types: plain, signed, unsigned, all different. Modula-3 does not have const. Modula-3 does not have void* per se. It has "address", which perhaps I messed up, and turned into char*. This could be my failing: Modula-3 typenames vs. Modula-3 typeids. TYPE Foo = record ... end; isn't Foo but a typeid. This might be m3c being incomplete, granted. So example(s) then: The .i3 leads to, on 64bit: typedef signed char INT8; typedef INT8 T66A2A904_8; typedef T66A2A904_8 * TAB374D58; INT64 Cstring__strlen(TAB374D58); but the function is actually: size_t Cstring__strlenstrlen(const char*); So neither the return type nor parameter type is correct. They are really very close, close enough for most purposes, but not quite matching, if you present the C compiler with both at the same time. There are problems with records. m3core.h duplicates anything from the .i3 files, like Date. The solution here is probably to make sure m3cg.typename works, and use ifndef so m3core.h dominates m3c output. Thoughts? Almost every function mismatches. An exception is empty parameter lists. I am skeptical that getting signatures to strictly agree is tenable. My inclination is: - Have m3cg know if a function is "external". - Wrap every external declaration in ifndef; so that m3core.h can come before. - When calling an external function, take its address, cast to C:() or C++:(...) like I already do for function pointers anyway (due to closures), and then pass the parameters we "know" to be correct, that we were already passing. Modula-3 calling Modula-3 is unaffected. Separate non-concatenated compilation is unaffected, but note that it is using incorrect prototypes too. The codebase is relatively unaffected, but that import_procedure is told if a function is exported. Alternatively I could teach m3c of all external functions in cm3 (not the entire system, just what makes up cm3). Non-option: Remove the C layer. It really is super valuable. I can try to revisit and make the m3c output match but it seems almost intractable. If I were to get the prototypes correct, then the parameters have to be cast. For example you cannot actually get a C char in Modula-3. Another way is to loosen the types of the C wrappers, like replace all char* with void* and then cast within the functions. This is almost the same casting to untyped function pointers. Thank you, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sun Apr 25 18:41:09 2021 From: jayk123 at hotmail.com (Jay K) Date: Sun, 25 Apr 2021 16:41:09 +0000 Subject: [M3devel] duplicate unit TextUtils In-Reply-To: References: , Message-ID: You are right. I have it "fixed" it now. Sorry about that. The change was mostly very worthwhile but maybe a bit more than necessary. We should probably consolidate all of TextUtils/TextExtras into m3-libs/m3text or m3-libs/m3core. Setting up CI ought to occur soon. ? - Jay ________________________________ From: Mika Nystrom Sent: Sunday, April 25, 2021 4:22 PM To: Jay K ; m3devel Subject: Re: duplicate unit TextUtils OK, I believe the trouble is coming from recent changes to netobj. It's causing netobj to pull in m3middle, which pulls in sysutils, which then goes all over the place that netobj is used. Netobj now requires Target, which is from m3middle: c408284c5b (JayKrell 2021-03-18 20:36:33 -0700 291) IF IntVal > Target.WideChar16Max THEN IntVal := ReplacementWt; END; c408284c5b (JayKrell 2021-03-18 20:36:33 -0700 17) import("m3middle") This is unfortunately going to break a lot of code on our end. Hmm. What is the right way to solve this problem? I noticed another thing while debugging this... scynoble99> grep TextUtils /tmp/d5.10.0/pkg/*/AMD64_LINUX/.M3EXPORTS | wc 6515 6530 520287 scynoble99> grep TextUtils /tmp/d5.10.0/pkg/*/AMD64_LINUX/.M3EXPORTS | uniq | wc 79 94 6387 That seems a little bit odd, no? scynoble99> grep TextUtils /tmp/d5.10.0/pkg/webvbt/AMD64_LINUX/.M3EXPORTS | wc 521 521 15630 scynoble99> scynoble99> wc /tmp/d5.10.0/pkg/webvbt/AMD64_LINUX/.M3EXPORTS 6332 6492 184297 /tmp/d5.10.0/pkg/webvbt/AMD64_LINUX/.M3EXPORTS scynoble99> sort /tmp/d5.10.0/pkg/webvbt/AMD64_LINUX/.M3EXPORTS | uniq -c | sort -g | tail 521 export_interface("FastLex") 521 export_interface("MsgIF") 521 export_interface("MsgX") 521 export_interface("OSSpecials") 521 export_interface("PathRepr") 521 export_interface("ProcessEnv") 521 export_interface("SMsg") 521 export_interface("System") 521 export_interface("TextReadingUtils") 521 export_interface("TextUtils") scynoble99> Why is one file exporting each of these interfaces 521 times? Mika On Sun, Apr 25, 2021 at 8:20 AM Mika Nystrom > wrote: Hi Jay, others, I'm trying to build the head like so: ./boot1.py AMD64_LINUX ./boot2.py and all looks good until this happens: ignoring ../src/m3overrides Fatal Error: duplicate unit: /tmp/d5.10.0/pkg/sysutils/src/TextUtils.i3 ../src/TextUtils.i3 *** execution of [, ] failed *** ERROR: ./do-cm3-all.py buildship scynoble99> cd /nfs/sc/disks/mst_109/mnystroe/cm3-github-2/caltech-parser/cit_util scynoble99> /tmp/d5.10.0/bin/cm3 -DBUILD_DIR=AMD64_LINUX -build -DROOT=/nfs/sc/disks/mst_109/mnystroe/cm3-github-2 -DTARGET=AMD64_LINUX --- building in AMD64_LINUX --- ignoring ../src/m3overrides Fatal Error: duplicate unit: /tmp/d5.10.0/pkg/sysutils/src/TextUtils.i3 ../src/TextUtils.i3 Now I know sort of why this is happening. The cit_util directory has an interface with the same name as sysutils does. But what I'm not understanding is, cit_util doesn't import sysutils, does it? Not even indirectly. sysutils is part of the cm3 compiler, and not part of m3core or libm3 or anything else that cit_util imports. Why are the two clashing? How have others worked around the issue? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Sun Apr 25 20:23:55 2021 From: jayk123 at hotmail.com (Jay K) Date: Sun, 25 Apr 2021 18:23:55 +0000 Subject: [M3devel] CM3 diff In-Reply-To: References: , Message-ID: 1. Yeah lots of changes there. 2. Let me test my change. I though there'd be no duplicate. 3. You are stuck on such old gcc? Well, the config files I guess are somewhat site-specific, we just provide good suggestions..but then, maybe they should be differently factores, or we should have some sort of autoconf (I don't like the old cminstall though). - Jay ________________________________ From: Mika Nystrom Sent: Sunday, April 25, 2021 6:17 PM To: m3devel ; Jay K Subject: Fwd: CM3 diff With the attached diff it builds for me: 1. don't build csv/csvalign -- I assume compiler bug? 2. Target -> NetObjTarget -- clash resolution 3. -fuse-ld=gold -- my gcc doesn't recognize -fuse-ld (using v. 4.7.2) Mika ---------- Forwarded message --------- From: Nystroem, Mika > Date: Sun, Apr 25, 2021 at 11:15 AM Subject: CM3 diff To: Mika Nystrom > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vvm at tut.by Mon Apr 26 08:28:54 2021 From: vvm at tut.by (vvm at tut.by) Date: Mon, 26 Apr 2021 09:28:54 +0300 Subject: [M3devel] Fw: Fatal Error: duplicate unit: cm3\pkg\sysutils\src\TextUtils.i3 ..\src\TextUtils.i3 Re: duplicate unit TextUtils In-Reply-To: References: , Message-ID: <3594361619417269@mail.yandex.by> An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Mon Apr 26 08:36:49 2021 From: jayk123 at hotmail.com (Jay K) Date: Mon, 26 Apr 2021 06:36:49 +0000 Subject: [M3devel] Fatal Error: duplicate unit: cm3\pkg\sysutils\src\TextUtils.i3 ..\src\TextUtils.i3 Re: duplicate unit TextUtils In-Reply-To: <3594361619417269@mail.yandex.by> References: , , <3594361619417269@mail.yandex.by> Message-ID: vvm: It is understood and should be fixed. If it is not fixed, it is a minor thing. Don't worry much or at all. If you really want to worry about it: please setup CI. CI is on my proverbial/rhetorical list, but I have a few things I want to do first. Specifically I want cm3 buildable from one .c file, and approximately two .h files, at least for Unix. Win32 might require two .c files because of mklib, though that can/should be fixed in multiple ways -- merge it into cm3 or stop using it entirely. I want CI to start with this "one" file, and not bother supporting starting from earlier forms. The .h files could be reduced further (they are UerrorX.h and dtoa.h; UerrorX.h is barely worthwhile, and dtoa.h I would like to remove too, but it is presently needed). - Jay ________________________________ From: vvm at tut.by Sent: Monday, April 26, 2021 6:28 AM To: Jay K ; Mika Nystrom ; m3devel Subject: Fw: Fatal Error: duplicate unit: cm3\pkg\sysutils\src\TextUtils.i3 ..\src\TextUtils.i3 Re: [M3devel] duplicate unit TextUtils Hi! MN}}} MN}}} Now I know sort of why this is happening. MN}}} The cit_util directory has an interface with the same name as sysutils does. MN}}} MN}}} But what I'm not understanding is, cit_util doesn't import sysutils, does it? Not even indirectly. MN}}} sysutils is part of the cm3 compiler, and not part of m3core or libm3 or anything else that cit_util imports. MN}}} Why are the two clashing? MN}}} How have others worked around the issue? MN}}} JK}} JK}} You are right. I have it "fixed" it now. Sorry about that. JK}} The change was mostly very worthwhile but maybe a bit more than necessary. JK}} We should probably consolidate all of TextUtils/TextExtras into m3-libs/m3text or m3-libs/m3core. JK}} This is related? https://github.com/modula3/cm3/commit/1c23de8a6c2660e6cfd5414965cc2b685d54f5f2#commitcomment-49702324 == == == VictorMiasnikov replied 7 days ago === ERROR LOG SUMMARY: ----------------- WARNING: Errors in package "caltech-parser\cit_util" === === ------------------------------------------------------------------------------ --- processing package "caltech-parser\cit_util" --- --- purging derived files from AMD64_NT --- . . . --- building in AMD64_NT --- ignoring ..\src\m3overrides Fatal Error: duplicate unit: D:\cm3\pkg\sysutils\src\TextUtils.i3 ..\src\TextUtils.i3 WARNING: Encountered an error when processing package "caltech-parser\cit_util" for "-build". === == == == Best regards, Victor Miasnikov 25.04.2021, 19:41, "Jay K" : You are right. I have it "fixed" it now. Sorry about that. The change was mostly very worthwhile but maybe a bit more than necessary. We should probably consolidate all of TextUtils/TextExtras into m3-libs/m3text or m3-libs/m3core. Setting up CI ought to occur soon. ? - Jay ________________________________ From: Mika Nystrom > Sent: Sunday, April 25, 2021 4:22 PM To: Jay K >; m3devel > Subject: Re: duplicate unit TextUtils OK, I believe the trouble is coming from recent changes to netobj. It's causing netobj to pull in m3middle, which pulls in sysutils, which then goes all over the place that netobj is used. Netobj now requires Target, which is from m3middle: c408284c5b (JayKrell 2021-03-18 20:36:33 -0700 291) IF IntVal > Target.WideChar16Max THEN IntVal := ReplacementWt; END; c408284c5b (JayKrell 2021-03-18 20:36:33 -0700 17) import("m3middle") This is unfortunately going to break a lot of code on our end. Hmm. What is the right way to solve this problem? I noticed another thing while debugging this... scynoble99> grep TextUtils /tmp/d5.10.0/pkg/*/AMD64_LINUX/.M3EXPORTS | wc 6515 6530 520287 scynoble99> grep TextUtils /tmp/d5.10.0/pkg/*/AMD64_LINUX/.M3EXPORTS | uniq | wc 79 94 6387 That seems a little bit odd, no? scynoble99> grep TextUtils /tmp/d5.10.0/pkg/webvbt/AMD64_LINUX/.M3EXPORTS | wc 521 521 15630 scynoble99> scynoble99> wc /tmp/d5.10.0/pkg/webvbt/AMD64_LINUX/.M3EXPORTS 6332 6492 184297 /tmp/d5.10.0/pkg/webvbt/AMD64_LINUX/.M3EXPORTS scynoble99> sort /tmp/d5.10.0/pkg/webvbt/AMD64_LINUX/.M3EXPORTS | uniq -c | sort -g | tail 521 export_interface("FastLex") 521 export_interface("MsgIF") 521 export_interface("MsgX") 521 export_interface("OSSpecials") 521 export_interface("PathRepr") 521 export_interface("ProcessEnv") 521 export_interface("SMsg") 521 export_interface("System") 521 export_interface("TextReadingUtils") 521 export_interface("TextUtils") scynoble99> Why is one file exporting each of these interfaces 521 times? Mika On Sun, Apr 25, 2021 at 8:20 AM Mika Nystrom > wrote: Hi Jay, others, I'm trying to build the head like so: ./boot1.py AMD64_LINUX ./boot2.py and all looks good until this happens: ignoring ../src/m3overrides Fatal Error: duplicate unit: /tmp/d5.10.0/pkg/sysutils/src/TextUtils.i3 ../src/TextUtils.i3 *** execution of [, ] failed *** ERROR: ./do-cm3-all.py buildship scynoble99> cd /nfs/sc/disks/mst_109/mnystroe/cm3-github-2/caltech-parser/cit_util scynoble99> /tmp/d5.10.0/bin/cm3 -DBUILD_DIR=AMD64_LINUX -build -DROOT=/nfs/sc/disks/mst_109/mnystroe/cm3-github-2 -DTARGET=AMD64_LINUX --- building in AMD64_LINUX --- ignoring ../src/m3overrides Fatal Error: duplicate unit: /tmp/d5.10.0/pkg/sysutils/src/TextUtils.i3 ../src/TextUtils.i3 Now I know sort of why this is happening. The cit_util directory has an interface with the same name as sysutils does. But what I'm not understanding is, cit_util doesn't import sysutils, does it? Not even indirectly. sysutils is part of the cm3 compiler, and not part of m3core or libm3 or anything else that cit_util imports. Why are the two clashing? How have others worked around the issue? Mika , _______________________________________________ M3devel mailing list M3devel at elegosoft.com https://m3lists.elegosoft.com/mailman/listinfo/m3devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From vvm at tut.by Mon Apr 26 09:03:39 2021 From: vvm at tut.by (vvm at tut.by) Date: Mon, 26 Apr 2021 10:03:39 +0300 Subject: [M3devel] Fatal Error: duplicate unit: cm3\pkg\sysutils\src\TextUtils.i3 ..\src\TextUtils.i3 Re: duplicate unit TextUtils In-Reply-To: References: , , <3594361619417269@mail.yandex.by> Message-ID: <3512831619419800@mail.yandex.by> An HTML attachment was scrubbed... URL: From vvm at tut.by Tue Apr 27 09:06:54 2021 From: vvm at tut.by (vvm at tut.by) Date: Tue, 27 Apr 2021 10:06:54 +0300 Subject: [M3devel] Fw: <*ASSERT*> failed: top.shallowestDynDepth < 0 file "../src/exprs/ArrayExpr.m3", line 2103 Re: duplicate unit TextUtils In-Reply-To: <3512831619419800@mail.yandex.by> References: , , <3594361619417269@mail.yandex.by> <3512831619419800@mail.yandex.by> Message-ID: <85431619506577@mail.yandex.by> An HTML attachment was scrubbed... URL: From peter.mckinna at gmail.com Tue Apr 27 13:33:40 2021 From: peter.mckinna at gmail.com (Peter McKinna) Date: Tue, 27 Apr 2021 21:33:40 +1000 Subject: [M3devel] uid collision Message-ID: I was intrigued by Jay's discovery of a declare_subrange in the mc file with the same uid for two different types so I rigged a test program and got this via cm3 -debug -X-vsdebug SUBRANGE -256 256 FP ==> 16_40f43cb2295695b6 => 16_69a2a904 = 1772267780 FP ==> 16_40f43cb2295695b6 => 16_69a2a904 = 1772267780 --------------------------------------- SUBRANGE -100 100 FP ==> 16_46f13fb22f5396b6 => 16_69a2a904 = 1772267780 FP ==> 16_46f13fb22f5396b6 => 16_69a2a904 = 1772267780 The first thing was that there was only one declare_subrange so any debug info for the second type would be lost if both types are declared in the one CU. That may or may not matter. Probably doesn't And as can be seen, the fingerprints of the two types differ but not as much as one would expect. Altering a single bit in MD5 completely scrambles the result. However, the uid's are identical. And that is because M3FP.ToInt takes the 64 bit fingerprint and xor's the top and bottom 32 bits, which in this case produces identical 32 bit numbers. Very weird. Expanding to 64 bit uid's seems the logical solution but it would impact the entire compiler/runtime and all the magic uid's embedded. Using a better 32 bit hash might work (Fingerprint has a hash that may be useful) but that would change everything as well. If this only affects subranges its probably not such a problem but what if it affects more complex types? I'm suspicious of the -256..256 range (-512..512 has a similar problem) and it might point to a subtle problem with fingerprints. Peter -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Tue Apr 27 19:01:44 2021 From: jayk123 at hotmail.com (Jay K) Date: Tue, 27 Apr 2021 17:01:44 +0000 Subject: [M3devel] declare_param typenames Message-ID: Fyi declare_param lacks typenames. It only has typeid. So it is a bit lossy. C backend could use better fidelity here. I intend to add a M3.QID parameter. The reader/writer can ignore it, so m3cc completely unchanged. M3x86 and M3Llvm can also ignore it, requiring a few lines. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: