www.digitalmars.com         C & C++   DMDScript  

D.gnu - Recent changes to GDC.

reply "Iain Buclaw" <ibuclaw ubuntu.com> writes:
I've done a recent blitz of changes through the GDC codebase, 
some which change the way code is generated in a way which 
affects the current ABI.

* Dropped support for GCC 4.2, 4.3 and 4.4

* Merged in the work Walter has done for __vector type support.  
There are now newly available GCC builtins for vector operations 
via gcc.builtins module.

* GDC's default calling convention has now been switched back to 
that of the default for the target platform. The D_InlineAsm 
family of version identifiers are now turned off by default as we 
no longer pretend to follow DMD's calling convention. For those 
who want to turn on D_InlineAsm(_X86/_x86_64) there is a 
-fd-inline-asm compiler switch.

* GDC will emit the GNU_InlineAsm version identifier to tell user 
code that we support GNU Extended Inline Assembly.

* All patches to GCC proper have now been removed, GDC can now 
build applications without relying on changes to the backend, 
with the exception of naked functions.

* "naked" has now been implemented now as a function attribute of 
the x86 platform.  It is applied to all naked functions, and 
implies noinline and noclone.

* D version 2 is now the default compiler to build.


I will get round to putting up a roadmap to GCC-4.8 sometime this 
week, and I invite everyone interested in making this happen to 
get together and help progress this. :)



Regards
--
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
Jan 15 2012
next sibling parent reply Manu <turkeyman gmail.com> writes:
I had creeping problems building phobos (MinGW) last night stemming from
D_InlineAsm being removed. Didn't manage to get it working in the end, gave
up and went to bed :)


On 16 January 2012 00:34, Iain Buclaw <ibuclaw ubuntu.com> wrote:

 I've done a recent blitz of changes through the GDC codebase, some which
 change the way code is generated in a way which affects the current ABI.

 * Dropped support for GCC 4.2, 4.3 and 4.4

 * Merged in the work Walter has done for __vector type support.  There are
 now newly available GCC builtins for vector operations via gcc.builtins
 module.

 * GDC's default calling convention has now been switched back to that of
 the default for the target platform. The D_InlineAsm family of version
 identifiers are now turned off by default as we no longer pretend to follow
 DMD's calling convention. For those who want to turn on
 D_InlineAsm(_X86/_x86_64) there is a -fd-inline-asm compiler switch.

 * GDC will emit the GNU_InlineAsm version identifier to tell user code
 that we support GNU Extended Inline Assembly.

 * All patches to GCC proper have now been removed, GDC can now build
 applications without relying on changes to the backend, with the exception
 of naked functions.

 * "naked" has now been implemented now as a function attribute of the x86
 platform.  It is applied to all naked functions, and implies noinline and
 noclone.

 * D version 2 is now the default compiler to build.


 I will get round to putting up a roadmap to GCC-4.8 sometime this week,
 and I invite everyone interested in making this happen to get together and
 help progress this. :)



 Regards
 --
 Iain Buclaw

 *(p < e ? p++ : p) = (c & 0x0f) + '0';
Jan 16 2012
parent reply Daniel Green <venix1 gmail.com> writes:
On 1/16/2012 4:03 AM, Manu wrote:
 I had creeping problems building phobos (MinGW) last night stemming from
 D_InlineAsm being removed. Didn't manage to get it working in the end,
 gave up and went to bed :)
https://bitbucket.org/goshawk/gdc/changeset/dc87c7212d70 Some of the stack functions needed replacements. I don't recall anything else giving me problems.
Jan 16 2012
next sibling parent reply Iain Buclaw <ibuclaw ubuntu.com> writes:
On 16 January 2012 16:56, Daniel Green <venix1 gmail.com> wrote:
 On 1/16/2012 4:03 AM, Manu wrote:
 I had creeping problems building phobos (MinGW) last night stemming from
 D_InlineAsm being removed. Didn't manage to get it working in the end,
 gave up and went to bed :)
https://bitbucket.org/goshawk/gdc/changeset/dc87c7212d70 Some of the stack functions needed replacements. =A0I don't recall anythi=
ng
 else giving me problems.
Cool. Do you have anything in your MinGW patch queue that might be worth merging in? --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
Jan 16 2012
parent Daniel Green <venix1 gmail.com> writes:
On 1/16/2012 1:42 PM, Iain Buclaw wrote:
 Cool.  Do you have anything in your MinGW patch queue that might be
 worth merging in?
Maybe. I'm merging some of the trivial changes now. In addition there is TLS support but that requires patches to the runtime, bintutils and GCC. Support for C99 stdio which phobos requires but again that requires a runtime patch. I'm considering not merging them until the patches get accepted. There's also a collection of miscellaneous Win64 fixes. There is also issue 229 which removes dmain.o from libgphobos. Required to support -mwindows and -mdll. In addition there are 2 MinGW64 specific failures remaining with the testsuite. Any chance you can offer some insight into them? --- // ctfe.d import std.stdio; import std.math; import core.bitop; static assert({ int a = 0x80; int f = bsf(a); // Adding this line makes it fail. return true; }()); $ gdc ctfe.d ctfe.d:9: called from here: delegate pure nothrow system bool() { int a = 128; int f = bsf(cast(ulong)a); return true; } () ctfe.d:5: Error: static assert (delegate pure nothrow system bool() { int a = 128; int f = bsf(cast(ulong)a); return true; } ()) is not evaluatable at compile time --- $ gdc runnable/test8.d runnable/test8.d:795: Error: undefined identifier __va_argsave, did you mean alias __va_argsave_t?
Jan 16 2012
prev sibling parent reply Manu <turkeyman gmail.com> writes:
On 16 January 2012 18:56, Daniel Green <venix1 gmail.com> wrote:

 On 1/16/2012 4:03 AM, Manu wrote:

 I had creeping problems building phobos (MinGW) last night stemming from
 D_InlineAsm being removed. Didn't manage to get it working in the end,
 gave up and went to bed :)
https://bitbucket.org/goshawk/**gdc/changeset/dc87c7212d70<https://bitbucket.org/goshawk/gdc/changeset/dc87c7212d70> Some of the stack functions needed replacements. I don't recall anything else giving me problems.
I went through that stuff you submitted the patch for, then I also ran into a conflict between linux sockets and windows sockets, and that's as far as I got when I stopped.
Jan 16 2012
parent reply Daniel Green <venix1 gmail.com> writes:
On 1/16/2012 3:34 PM, Manu wrote:
 I went through that stuff you submitted the patch for, then I also ran
 into a conflict between linux sockets and windows sockets, and that's as
 far as I got when I stopped.
The only posix file that gave me trouble was `core/sys/posix/sys/un.d`. GDC turns it into a header file. DMD doesn't for Windows. It's been corrected in tip.
Jan 16 2012
parent Manu <turkeyman gmail.com> writes:
On 17 January 2012 06:27, Daniel Green <venix1 gmail.com> wrote:

 On 1/16/2012 3:34 PM, Manu wrote:

 I went through that stuff you submitted the patch for, then I also ran
 into a conflict between linux sockets and windows sockets, and that's as
 far as I got when I stopped.
The only posix file that gave me trouble was `core/sys/posix/sys/un.d`. GDC turns it into a header file. DMD doesn't for Windows. It's been corrected in tip.
Maybe the fix I made to that file was wrong, and it then carried on into socket.d. Anyway, cheers for fixing it up. See if I can build it again this evening...
Jan 17 2012
prev sibling next sibling parent Iain Buclaw <ibuclaw ubuntu.com> writes:
On 16 January 2012 09:03, Manu <turkeyman gmail.com> wrote:
 I had creeping problems building phobos (MinGW) last night stemming
 from=A0D_InlineAsm=A0being removed. Didn't manage to get it working in th=
e end,
 gave up and went to bed :)
Please raise bug report with build logs, thanks. --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
Jan 16 2012
prev sibling next sibling parent reply Artur Skawina <art.08.09 gmail.com> writes:
On 01/15/12 23:34, Iain Buclaw wrote:
 * Merged in the work Walter has done for __vector type support.  There are now
newly available GCC builtins for vector operations via gcc.builtins module.
Allowing !=128 bits wide types would be just a matter of removing the frontend restrictions, right? (i didn't look at the latest commits, maybe you already did that) As the vector ops often will need to be wrapped, lack of cross module function inlining is a problem.
 * GDC's default calling convention has now been switched back to that of the
default for the target platform.
Hmm. You just invented a new ABI. "extern(D)" will mean different things to different compilers on the same platform. Only makes sense if you're sure to win the ABI war, and the other party to practically disappear. This new ABI still isn't compatible with the default "C/C++" one, because of name mangling. (could it be made, at least partially, C++ compatible?) As you still cannot easily call D code from C, without the equivalent of "extern(D)", why not default to a more sane calling conventions, such as regparm on 32-bit x86? GCC made a mistake years ago to not mangle the names when using a nonstd convention (eg by prepending ' ' like some other compilers did) which resulted in this feature being unusable, other than for application-internal functions, as calling the wrong version will silently build and link, only to blow up at runtime; you also cannot place both versions in a library etc. Hence "fixing" this had to wait for a new architecture (x86_64) and whole program optimizations/LTO, which can figure out automatically when it's safe to switch to a more efficient convention.
 The D_InlineAsm family of version identifiers are now turned off by default as
we no longer pretend to follow DMD's calling convention. For those who want to
turn on D_InlineAsm(_X86/_x86_64) there is a -fd-inline-asm compiler switch.
Why is it a compiler option? Ie is it safe to turn it on (why optional then?) or will it result in wrong code being generated (why have the option then?). D_InlineAsm allowed things like the cpuid code to work, will every asm{} now need to be rewritten, or could a safe subset of the "D" asms be reused?
 * GDC will emit the GNU_InlineAsm version identifier to tell user code that we
support GNU Extended Inline Assembly.
BTW, a identifier, which is set for *both* x86 and x86_64 would be good - because of how D's version() works and the fact that on those platforms the asm code will often be identical.
 * All patches to GCC proper have now been removed, GDC can now build
applications without relying on changes to the backend, with the exception of
naked functions.
 
 * "naked" has now been implemented now as a function attribute of the x86
platform.  It is applied to all naked functions, and implies noinline and
noclone.
I've never really understood the reason for "naked". Custom prologue and epilogue could be useful sometimes, but turning the compiler into an assembler?... You can already write "naked" asm functions in gcc - with asm()s outside of functions plus some as(1) section push/pop magic, iirc. Now you've removed the D builtin assembler, but decided to introduce "naked". Is it really necessary? There are no back-compat concerns... How does naked work will the various gcc features the modify prologue (profiling, stack usage checking, forced stack aligment etc)?
 * D version 2 is now the default compiler to build.
 
 
 I will get round to putting up a roadmap to GCC-4.8 sometime this week, and I
invite everyone interested in making this happen to get together and help
progress this. :)
What's the plan wrt druntime and phobos? It would be good if both could stay completely out of gcc, just like libc. Would make contributions significantly easier (no copyright assignment...) and maybe even a common version could emerge. artur
Jan 16 2012
parent "Kagamin" <spam here.lot> writes:
On Monday, 16 January 2012 at 14:42:08 UTC, Artur Skawina wrote:
 As you still cannot easily call D code from C, without the 
 equivalent of
 "extern(D)", why not default to a more sane calling 
 conventions, such as
 regparm on 32-bit x86?
The requirement for this kind of compatibility was simply a lie: they were saving their efforts of supporting an extra calling convention in the backend. Projects like gtkD prove there's no issue with compatibility to fix. And removal of inline asm actually lowered compatibility with existing D code itself. As a temporary measure, that's ok (and it manifests bugs in code which is supposed to work without inline asm), but when D is in GCC, one can push D calling convention to the backend for the *same* compatibility reasons "because we already have D" and get inline asm back too. Ahaha, just as planned.
Jan 26 2012
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
On 16 January 2012 16:41, Artur Skawina <art.08.09 gmail.com> wrote:

 On 01/15/12 23:34, Iain Buclaw wrote:
 * Merged in the work Walter has done for __vector type support.  There
are now newly available GCC builtins for vector operations via gcc.builtins module. Allowing !=128 bits wide types would be just a matter of removing the frontend restrictions, right? (i didn't look at the latest commits, maybe you already did that) As the vector ops often will need to be wrapped, lack of cross module function inlining is a problem.
No cross module function inlining? Really? This is a very serious problem... :/
Jan 16 2012
prev sibling next sibling parent reply Iain Buclaw <ibuclaw ubuntu.com> writes:
On 16 January 2012 14:41, Artur Skawina <art.08.09 gmail.com> wrote:
 On 01/15/12 23:34, Iain Buclaw wrote:
 * Merged in the work Walter has done for __vector type support. =A0There=
are now newly available GCC builtins for vector operations via gcc.builtin= s module.
 Allowing !=3D128 bits wide types would be just a matter of removing the f=
rontend
 restrictions, right? (i didn't look at the latest commits, maybe you alre=
ady did
 that)
 As the vector ops often will need to be wrapped, lack of cross module fun=
ction
 inlining is a problem.
If you want cross-module inlining, compile all sources in one command. gdc file1.d file2.d -o myapp
 * GDC's default calling convention has now been switched back to that of=
the default for the target platform.
 Hmm. You just invented a new ABI. "extern(D)" will mean different things =
to
 different compilers on the same platform. Only makes sense if you're sure=
to
 win the ABI war, and the other party to practically disappear.
I did not invent an ABI. extern(D) is only defined for the x86 platform - and it is no secret that only DMD adheres to it.
 This new ABI still isn't compatible with the default "C/C++" one, because=
of
 name mangling. (could it be made, at least partially, C++ compatible?)
 As you still cannot easily call D code from C, without the equivalent of
 "extern(D)", why not default to a more sane calling conventions, such as
 regparm on 32-bit x86?
The default calling convention is cdecl - this is directly ABI compatible with C and C++ code with the exception to name mangling requiring special treatment. eg: extern "C" int _Dmain(struct string args);
 GCC made a mistake years ago to not mangle the names when using a nonstd
 convention (eg by prepending ' ' like some other compilers did) which
 resulted in this feature being unusable, other than for application-inter=
nal
 functions, as calling the wrong version will silently build and link, onl=
y to
 blow up at runtime; you also cannot place both versions in a library etc.
 Hence "fixing" this had to wait for a new architecture (x86_64) and whole
 program optimizations/LTO, which can figure out automatically when it's s=
afe
 to switch to a more efficient convention.
What makes you think changing the calling convention will turn off name mangling?
 The D_InlineAsm family of version identifiers are now turned off by defa=
ult as we no longer pretend to follow DMD's calling convention. For those w= ho want to turn on D_InlineAsm(_X86/_x86_64) there is a -fd-inline-asm comp= iler switch.
 Why is it a compiler option? Ie is it safe to turn it on (why optional th=
en?)
 or will it result in wrong code being generated (why have the option then=
?).
 D_InlineAsm allowed things like the cpuid code to work, will every asm{} =
now
 need to be rewritten, or could a safe subset of the "D" asms be reused?
All Inline Asm code in Druntime and Phobos is written with the DMD calling convention in mind, so ie: when one of the naked functions in std.math pops the stack when returning a float, the caller won't clean this in GDC generated code. Other than that, it works perfectly well (tm).
 * GDC will emit the GNU_InlineAsm version identifier to tell user code t=
hat we support GNU Extended Inline Assembly.
 BTW, a identifier, which is set for *both* x86 and x86_64 would be good -=
because
 of how D's version() works and the fact that on those platforms the asm c=
ode will
 often be identical.

 * All patches to GCC proper have now been removed, GDC can now build app=
lications without relying on changes to the backend, with the exception of = naked functions.
 * "naked" has now been implemented now as a function attribute of the x8=
6 platform. =A0It is applied to all naked functions, and implies noinline a= nd noclone.
 I've never really understood the reason for "naked". Custom prologue and =
epilogue
 could be useful sometimes, but turning the compiler into an assembler?...=
You can
 already write "naked" asm functions in gcc - with asm()s outside of funct=
ions
 plus some as(1) section push/pop magic, iirc.
 Now you've removed the D builtin assembler, but decided to introduce "nak=
ed".
 Is it really necessary? There are no back-compat concerns...
 How does naked work will the various gcc features the modify prologue (pr=
ofiling,
 stack usage checking, forced stack aligment etc)?
I have not removed the D builtin assembler. I have just removed D_InlineAsm version identifers. GDC's "naked" function support was originally a (pretty bad) hack in GCC. It is now implemented cleanly as a function attribute, and does not affect the code generation of other frontends.
 * D version 2 is now the default compiler to build.


 I will get round to putting up a roadmap to GCC-4.8 sometime this week, =
and I invite everyone interested in making this happen to get together and = help progress this. :)
 What's the plan wrt druntime and phobos? It would be good if both could s=
tay
 completely out of gcc, just like libc. Would make contributions significa=
ntly
 easier (no copyright assignment...) and maybe even a common version could
 emerge.

 artur
I have no plans to remove libphobos or druntime from the compiler. I will check licensing, but there should be no issues with including it. --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
Jan 16 2012
parent Trass3r <un known.com> writes:
 If you want cross-module inlining, compile all sources in one command.

 gdc file1.d file2.d -o myapp
So 'gdc -c file1.d' won't inline small functions from file2? Why?
Jan 16 2012
prev sibling next sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 01/16/12 17:43, Iain Buclaw wrote:
 On 16 January 2012 14:41, Artur Skawina <art.08.09 gmail.com> wrote:
 On 01/15/12 23:34, Iain Buclaw wrote:
 * Merged in the work Walter has done for __vector type support.  There are now
newly available GCC builtins for vector operations via gcc.builtins module.
Allowing !=128 bits wide types would be just a matter of removing the frontend restrictions, right? (i didn't look at the latest commits, maybe you already did that) As the vector ops often will need to be wrapped, lack of cross module function inlining is a problem.
If you want cross-module inlining, compile all sources in one command. gdc file1.d file2.d -o myapp
Does this work for '-c' too? For building libs, like eg phobos? Hmm, '-fonly" seems like it could work, together with '-c' -- I have never used that option, will have to try it later - but if it works, shouldn't it be on by default (for '-[cS]' invocations)? It's not that "i want cross-module inlining" - in a language like D it's practically required, for anything bigger than a single module. There are even cases in runtime where "{return 1;}" functions are not inlined (eg the malloc/mmap wrappers). When i did the gcbits asms it was prompted by this profile: 37.62% uint gc.gcx.Gcx.fullcollect(void*) 20.47% uint gc.gcbits.GCBits.test(uint) 13.80% uint gc.gcbits.GCBits.testSet(uint) 10.15% pure nothrow safe bool std.uni.isGraphical(dchar) 3.33% _D3std5array17__T8AppenderTAyaZ8Appender10__T3putTwZ3putMF 2.78% 0x11025a 2.13% _D3std6format65__T13formatElementTS3std5array17__T8Appende 1.64% _D3std6format56__T10formatCharTS3std5array17__T8AppenderTA 1.37% pure safe uint std.utf.encode(ref char[4], dchar) 0.88% void* gc.gcx.GC.malloc(uint, uint, uint*) 0.50% pure nothrow safe bool std.uni.binarySearch2(dchar, immutable(dchar[2][])) 0.45% void gc.gcbits.GCBits.set(uint) 0.37% void gc.gcbits.GCBits.clear(uint) 0.34% __divdi3 Clearly the garbage collector needs some love, but the 33%+ of the total app runtime (!) spent in those two trivial functions makes judging any GC improvements much harder. Even when inlined, the gcbits.* methods are still the hottest parts of the whole app, and while in this case it's the GC that needs fixing, that's not going to always be the case. A hack that can often be used to get cross module inlining working is adding a pair of parentheses - GDC will not throw away the function (well, now template) bodies and will happily inline them. But that's not really a good solution...
 * GDC's default calling convention has now been switched back to that of the
default for the target platform.
Hmm. You just invented a new ABI. "extern(D)" will mean different things to different compilers on the same platform. Only makes sense if you're sure to win the ABI war, and the other party to practically disappear.
I did not invent an ABI. extern(D) is only defined for the x86 platform - and it is no secret that only DMD adheres to it.
But what GDC emits for "extern(D)" is different both from what other D compilers do (what does LDC do on x86, BTW?) *and* it's different from the C/C++ convention...
 This new ABI still isn't compatible with the default "C/C++" one, because of
 name mangling. (could it be made, at least partially, C++ compatible?)
 As you still cannot easily call D code from C, without the equivalent of
 "extern(D)", why not default to a more sane calling conventions, such as
 regparm on 32-bit x86?
The default calling convention is cdecl - this is directly ABI compatible with C and C++ code with the exception to name mangling requiring special treatment. eg: extern "C" int _Dmain(struct string args);
That one exception makes a difference - it's still not directly callable from C/C++ w/o some kind of "extern(D)" declaration. (the _Dmain identifier is not the best example, other functions will not have similarly simple names...) And, yes, in theory, it could be done, but do you really expect C/C++ modules to directly use the demangled names?... Things like: pragma(attribute, ifunc("_D5ifunc6pick_fFZPFiZv")) void f(int i); is about the only time i had to do it (and this is actually a bug - ifunc should demangle the name). BTW, is the GDC exception handling compatible with C++?
 GCC made a mistake years ago to not mangle the names when using a nonstd
 convention (eg by prepending ' ' like some other compilers did) which
 resulted in this feature being unusable, other than for application-internal
 functions, as calling the wrong version will silently build and link, only to
 blow up at runtime; you also cannot place both versions in a library etc.
 Hence "fixing" this had to wait for a new architecture (x86_64) and whole
 program optimizations/LTO, which can figure out automatically when it's safe
 to switch to a more efficient convention.
What makes you think changing the calling convention will turn off name mangling?
My point is that modifying the ABI has a significant cost and can't easily be undone. I don't see much gain from switching from one nonstd convention to a different nonstd convention, which is /similar/ to the C one, but still not directly accessible from C. What does your change mean? Programs now use a worse calling convention (not even one arg gets passed in a register), object files and libraries generated by different D compilers are incompatible (by design, not just because of some implementation quirk), worse, mixing libs produced by different toolchains may seem to work, only to fail at runtime. Where's the gain?
 The D_InlineAsm family of version identifiers are now turned off by default as
we no longer pretend to follow DMD's calling convention. For those who want to
turn on D_InlineAsm(_X86/_x86_64) there is a -fd-inline-asm compiler switch.
Why is it a compiler option? Ie is it safe to turn it on (why optional then?) or will it result in wrong code being generated (why have the option then?). D_InlineAsm allowed things like the cpuid code to work, will every asm{} now need to be rewritten, or could a safe subset of the "D" asms be reused?
All Inline Asm code in Druntime and Phobos is written with the DMD calling convention in mind, so ie: when one of the naked functions in std.math pops the stack when returning a float, the caller won't clean this in GDC generated code. Other than that, it works perfectly well (tm).
Ah, ok, thank you for clarifying that. It would then be possible to keep D_InlineAsm working and only fail (or warn) when "naked" is used in "D" asm, right?
 * GDC will emit the GNU_InlineAsm version identifier to tell user code that we
support GNU Extended Inline Assembly.
BTW, a identifier, which is set for *both* x86 and x86_64 would be good - because of how D's version() works and the fact that on those platforms the asm code will often be identical.
 * All patches to GCC proper have now been removed, GDC can now build
applications without relying on changes to the backend, with the exception of
naked functions.

 * "naked" has now been implemented now as a function attribute of the x86
platform.  It is applied to all naked functions, and implies noinline and
noclone.
I've never really understood the reason for "naked". Custom prologue and epilogue could be useful sometimes, but turning the compiler into an assembler?... You can already write "naked" asm functions in gcc - with asm()s outside of functions plus some as(1) section push/pop magic, iirc. Now you've removed the D builtin assembler, but decided to introduce "naked". Is it really necessary? There are no back-compat concerns... How does naked work will the various gcc features the modify prologue (profiling, stack usage checking, forced stack aligment etc)?
I have not removed the D builtin assembler. I have just removed D_InlineAsm version identifers. GDC's "naked" function support was originally a (pretty bad) hack in GCC. It is now implemented cleanly as a function attribute, and does not affect the code generation of other frontends.
I meant something like "practically removed the availability of D builtin assembler by removing the guarding version identifiers", sorry. But doesn't this mean that, right now, there are exactly zero users of this feature (gcc naked functions)?.. artur
Jan 16 2012
prev sibling next sibling parent Iain Buclaw <ibuclaw ubuntu.com> writes:
On 16 January 2012 19:14, Artur Skawina <art.08.09 gmail.com> wrote:
 On 01/16/12 17:43, Iain Buclaw wrote:
 On 16 January 2012 14:41, Artur Skawina <art.08.09 gmail.com> wrote:
 On 01/15/12 23:34, Iain Buclaw wrote:
 * Merged in the work Walter has done for __vector type support. =A0The=
re are now newly available GCC builtins for vector operations via gcc.built= ins module.
 Allowing !=3D128 bits wide types would be just a matter of removing the=
frontend
 restrictions, right? (i didn't look at the latest commits, maybe you al=
ready did
 that)
 As the vector ops often will need to be wrapped, lack of cross module f=
unction
 inlining is a problem.
If you want cross-module inlining, compile all sources in one command. gdc file1.d file2.d -o myapp
Does this work for '-c' too? For building libs, like eg phobos? Hmm, '-fonly" seems like it could work, together with '-c' -- I have neve=
r
 used that option, will have to try it later - but if it works, shouldn't =
it
 be on by default (for '-[cS]' invocations)?
It won't. For inlining to work, the function body (that is available at compile-time in DMDFE AST) needs to be converted into GCC trees for the backend to inline. -fonly, whilst it processes the semantic analysis on the other modules, does not generate any codegen for them. For cross module inlining to properly work in the one-file-at-a-time compilation method, there needs to be an intermediate routine that says 'build this body now, but don't add the function to the global to output list'.
 It's not that "i want cross-module inlining" - in a language like D it's
 practically required, for anything bigger than a single module. There are
 even cases in runtime where "{return 1;}" functions are not inlined (eg t=
he
 malloc/mmap wrappers).

 When i did the gcbits asms it was prompted by this profile:

 37.62% =A0uint gc.gcx.Gcx.fullcollect(void*)
 20.47% =A0uint gc.gcbits.GCBits.test(uint)
 13.80% =A0uint gc.gcbits.GCBits.testSet(uint)
 10.15% =A0pure nothrow  safe bool std.uni.isGraphical(dchar)
 =A03.33% =A0_D3std5array17__T8AppenderTAyaZ8Appender10__T3putTwZ3putMF
 =A02.78% =A00x11025a
 =A02.13% =A0_D3std6format65__T13formatElementTS3std5array17__T8Appende
 =A01.64% =A0_D3std6format56__T10formatCharTS3std5array17__T8AppenderTA
 =A01.37% =A0pure  safe uint std.utf.encode(ref char[4], dchar)
 =A00.88% =A0void* gc.gcx.GC.malloc(uint, uint, uint*)
 =A00.50% =A0pure nothrow  safe bool std.uni.binarySearch2(dchar, immutabl=
e(dchar[2][]))
 =A00.45% =A0void gc.gcbits.GCBits.set(uint)
 =A00.37% =A0void gc.gcbits.GCBits.clear(uint)
 =A00.34% =A0__divdi3

 Clearly the garbage collector needs some love, but the 33%+ of the total
 app runtime (!) spent in those two trivial functions makes judging any
 GC improvements much harder. Even when inlined, the gcbits.* methods are
 still the hottest parts of the whole app, and while in this case it's the
 GC that needs fixing, that's not going to always be the case.

 A hack that can often be used to get cross module inlining working is
 adding a pair of parentheses - GDC will not throw away the function
 (well, now template) bodies and will happily inline them. But that's not
 really a good solution...
It's not a priority, but you will not be ignored. A solution I'm happy with needs to be drafted first though.
 * GDC's default calling convention has now been switched back to that =
of the default for the target platform.
 Hmm. You just invented a new ABI. "extern(D)" will mean different thing=
s to
 different compilers on the same platform. Only makes sense if you're su=
re to
 win the ABI war, and the other party to practically disappear.
I did not invent an ABI. =A0extern(D) is only defined for the x86 platform - and it is no secret that only DMD adheres to it.
But what GDC emits for "extern(D)" is different both from what other D compilers do (what does LDC do on x86, BTW?) *and* it's different from the C/C++ convention...
I think LDC uses some fancy LLVM hook to control how structs are returned, but that's about it.
 This new ABI still isn't compatible with the default "C/C++" one, becau=
se of
 name mangling. (could it be made, at least partially, C++ compatible?)
 As you still cannot easily call D code from C, without the equivalent o=
f
 "extern(D)", why not default to a more sane calling conventions, such a=
s
 regparm on 32-bit x86?
The default calling convention is cdecl - this is directly ABI compatible with C and C++ code with the exception to name mangling requiring special treatment. eg: extern "C" int _Dmain(struct string args);
That one exception makes a difference - it's still not directly callable from C/C++ w/o some kind of "extern(D)" declaration. (the _Dmain identifier is not the best example, other functions will not have similarly simple names...) And, yes, in theory, it could be done, but do you really expect C/C++ modules to directly use the demangled names?... Things like: pragma(attribute, ifunc("_D5ifunc6pick_fFZPFiZv")) void f(int i); is about the only time i had to do it (and this is actually a bug - ifunc should demangle the name). BTW, is the GDC exception handling compatible with C++?
It's practically rewrite of the C++ exception routine in D. But don't quote me on it being directly compatible.
 GCC made a mistake years ago to not mangle the names when using a nonst=
d
 convention (eg by prepending ' ' like some other compilers did) which
 resulted in this feature being unusable, other than for application-int=
ernal
 functions, as calling the wrong version will silently build and link, o=
nly to
 blow up at runtime; you also cannot place both versions in a library et=
c.
 Hence "fixing" this had to wait for a new architecture (x86_64) and who=
le
 program optimizations/LTO, which can figure out automatically when it's=
safe
 to switch to a more efficient convention.
What makes you think changing the calling convention will turn off name mangling?
My point is that modifying the ABI has a significant cost and can't easil=
y
 be undone. I don't see much gain from switching from one nonstd conventio=
n
 to a different nonstd convention, which is /similar/ to the C one, but st=
ill
 not directly accessible from C.
 What does your change mean? Programs now use a worse calling convention (=
not
 even one arg gets passed in a register), object files and libraries gener=
ated
 by different D compilers are incompatible (by design, not just because of=
some
 implementation quirk), worse, mixing libs produced by different toolchain=
s may
 seem to work, only to fail at runtime. Where's the gain?
1. My point is that modifying the ABI has a significant cost and can't easily be undone. I don't see much gain from switching from one nonstd convention to a different nonstd convention, which is /similar/ to the C one, but still not directly accessible from C. A calling convention that is used by the target platform is better than a calling convention that is used by no one but yourself. Also, I don't see how name mangling is part of the calling convention, but maybe that's just me (I am aware that name mangling is part of various Windows calling conventions, but not in *nix. :-) 2. What does your change mean? Programs now use a worse calling convention (not even one arg gets passed in a register), *cough* for x86 *cough* I can't see how you can use this as an argument. Parameter passing hasn't changed for x86, only the way certain values are returned. So it is *still* as bad as it was *before* the change. 3. object files and libraries generated by different D compilers are incompatible (by design, not just because of some implementation quirk), worse, mixing libs produced by different toolchains may seem to work, only to fail at runtime. Where's the gain? It has always been this way. I've never known people to frequently mix compilers when building code.
 The D_InlineAsm family of version identifiers are now turned off by de=
fault as we no longer pretend to follow DMD's calling convention. For those= who want to turn on D_InlineAsm(_X86/_x86_64) there is a -fd-inline-asm co= mpiler switch.
 Why is it a compiler option? Ie is it safe to turn it on (why optional =
then?)
 or will it result in wrong code being generated (why have the option th=
en?).
 D_InlineAsm allowed things like the cpuid code to work, will every asm{=
} now
 need to be rewritten, or could a safe subset of the "D" asms be reused?
All Inline Asm code in Druntime and Phobos is written with the DMD calling convention in mind, so ie: when one of the naked functions in std.math pops the stack when returning a float, the caller won't clean this in GDC generated code. =A0Other than that, it works perfectly well (tm).
Ah, ok, thank you for clarifying that. It would then be possible to keep D_InlineAsm working and only fail (or warn) when "naked" is used in "D" a=
sm,
 right?
The only patch to the calling convention that I've needed to do to get D Naked Functions working is to tell the caller that the callee will pop the stack if is returning a float, double or real (or their complex equivalents). A better solution would be to implement this "quirk" as another attribute, ie: callee_pop_float_return, which is then handled in ix86_return_pops_args. If that could be accepted in GCC, then we'd be flying again.
 * GDC will emit the GNU_InlineAsm version identifier to tell user code=
that we support GNU Extended Inline Assembly.
 BTW, a identifier, which is set for *both* x86 and x86_64 would be good=
- because
 of how D's version() works and the fact that on those platforms the asm=
code will
 often be identical.

 * All patches to GCC proper have now been removed, GDC can now build a=
pplications without relying on changes to the backend, with the exception o= f naked functions.
 * "naked" has now been implemented now as a function attribute of the =
x86 platform. =A0It is applied to all naked functions, and implies noinline= and noclone.
 I've never really understood the reason for "naked". Custom prologue an=
d epilogue
 could be useful sometimes, but turning the compiler into an assembler?.=
.. You can
 already write "naked" asm functions in gcc - with asm()s outside of fun=
ctions
 plus some as(1) section push/pop magic, iirc.
 Now you've removed the D builtin assembler, but decided to introduce "n=
aked".
 Is it really necessary? There are no back-compat concerns...
 How does naked work will the various gcc features the modify prologue (=
profiling,
 stack usage checking, forced stack aligment etc)?
I have not removed the D builtin assembler. I have just removed D_InlineAsm version identifers. =A0GDC's "naked" function support was originally a (pretty bad) hack in GCC. =A0It is now implemented cleanly as a function attribute, and does not affect the code generation of other frontends.
I meant something like "practically removed the availability of D builtin assembler by removing the guarding version identifiers", sorry. But doesn't this mean that, right now, there are exactly zero users of th=
is
 feature (gcc naked functions)?..

 artur
There is naked support for other architectures that have been accepted in GCC (arm, avr, m68k, mcore, rx, spu) - yes I had to look them up. :-) --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
Jan 16 2012
prev sibling next sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 01/16/12 21:49, Iain Buclaw wrote:
 On 16 January 2012 19:14, Artur Skawina <art.08.09 gmail.com> wrote:
 On 01/16/12 17:43, Iain Buclaw wrote:
 On 16 January 2012 14:41, Artur Skawina <art.08.09 gmail.com> wrote:
 On 01/15/12 23:34, Iain Buclaw wrote:
 * Merged in the work Walter has done for __vector type support.  There are now
newly available GCC builtins for vector operations via gcc.builtins module.
Allowing !=128 bits wide types would be just a matter of removing the frontend restrictions, right? (i didn't look at the latest commits, maybe you already did that) As the vector ops often will need to be wrapped, lack of cross module function inlining is a problem.
If you want cross-module inlining, compile all sources in one command. gdc file1.d file2.d -o myapp
Does this work for '-c' too? For building libs, like eg phobos? Hmm, '-fonly" seems like it could work, together with '-c' -- I have never used that option, will have to try it later - but if it works, shouldn't it be on by default (for '-[cS]' invocations)?
It won't. For inlining to work, the function body (that is available at compile-time in DMDFE AST) needs to be converted into GCC trees for the backend to inline. -fonly, whilst it processes the semantic analysis on the other modules, does not generate any codegen for them. For cross module inlining to properly work in the one-file-at-a-time compilation method, there needs to be an intermediate routine that says 'build this body now, but don't add the function to the global to output list'.
I guess treating the functions like C "extern inline"'s isn't possible?
 BTW, is the GDC exception handling compatible with C++?
It's practically rewrite of the C++ exception routine in D. But don't quote me on it being directly compatible.
Hmm, i was looking for more incompatibilities, but i guess expecting to directly throw/catch D exceptions from C++ (and v/v) is a bit too much. :)
 What makes you think changing the calling convention will turn off
 name mangling?
My point is that modifying the ABI has a significant cost and can't easily be undone. I don't see much gain from switching from one nonstd convention to a different nonstd convention, which is /similar/ to the C one, but still not directly accessible from C. What does your change mean? Programs now use a worse calling convention (not even one arg gets passed in a register), object files and libraries generated by different D compilers are incompatible (by design, not just because of some implementation quirk), worse, mixing libs produced by different toolchains may seem to work, only to fail at runtime. Where's the gain?
1. My point is that modifying the ABI has a significant cost and can't easily be undone. I don't see much gain from switching from one nonstd convention to a different nonstd convention, which is /similar/ to the C one, but still not directly accessible from C. A calling convention that is used by the target platform is better than a calling convention that is used by no one but yourself. Also, I don't see how name mangling is part of the calling convention, but maybe that's just me (I am aware that name mangling is part of various Windows calling conventions, but not in *nix. :-)
It isn't, but if you can't (easily) call the "D" code from C/C++ it might as well be. If you need proper annotations at every language border crossing, what advantage does using the same calling convention give you?..
 2. What does your change mean? Programs now use a worse calling
 convention (not even one arg gets passed in a register),
 
 *cough* for x86 *cough*
 
 I can't see how you can use this as an argument. Parameter passing
 hasn't changed for x86, only the way certain values are returned. So
 it is *still* as bad as it was *before* the change.
So gdc didn't implement the official (dlang.org) convention, and i was fooled by LTO? :)
 3. object files and libraries generated by different D compilers are
 incompatible (by design, not just because of some implementation
 quirk), worse, mixing libs produced by different toolchains may seem
 to work, only to fail at runtime. Where's the gain?
 
 It has always been this way. I've never known people to frequently mix
 compilers when building code.
Shared libraries. Distributions, such as Ubuntu. Does every OS vendor have to provide different packages for different D "stacks"? Every D library will come in a DMD version, GDC version and a LDC version? Or will just one compiler be picked, because the alternative isn't really acceptable? Note the former also means packaging every application using *any* D shared library (and i guess this can include phobos) N times. Let's hope nobody else decides to make a D compiler. :)
 * "naked" has now been implemented now as a function attribute of the x86
platform.  It is applied to all naked functions, and implies noinline and
noclone.
I've never really understood the reason for "naked". Custom prologue and epilogue could be useful sometimes, but turning the compiler into an assembler?... You can already write "naked" asm functions in gcc - with asm()s outside of functions plus some as(1) section push/pop magic, iirc. Now you've removed the D builtin assembler, but decided to introduce "naked". Is it really necessary? There are no back-compat concerns... How does naked work will the various gcc features the modify prologue (profiling, stack usage checking, forced stack aligment etc)?
I have not removed the D builtin assembler. I have just removed D_InlineAsm version identifers. GDC's "naked" function support was originally a (pretty bad) hack in GCC. It is now implemented cleanly as a function attribute, and does not affect the code generation of other frontends.
I meant something like "practically removed the availability of D builtin assembler by removing the guarding version identifiers", sorry. But doesn't this mean that, right now, there are exactly zero users of this feature (gcc naked functions)?..
 There is naked support for other architectures that have been accepted
 in GCC (arm, avr, m68k, mcore, rx, spu) - yes I had to  look them up.
 :-)
I meant "zero D users". :^) And was wondering if introducing something D-related that nobody was using made sense. I admit to *not* checking if some arch already had it. :) artur
Jan 16 2012
prev sibling next sibling parent Iain Buclaw <ibuclaw ubuntu.com> writes:
On 16 January 2012 23:08, Artur Skawina <art.08.09 gmail.com> wrote:
 On 01/16/12 21:49, Iain Buclaw wrote:
 On 16 January 2012 19:14, Artur Skawina <art.08.09 gmail.com> wrote:
 On 01/16/12 17:43, Iain Buclaw wrote:
 On 16 January 2012 14:41, Artur Skawina <art.08.09 gmail.com> wrote:
 On 01/15/12 23:34, Iain Buclaw wrote:
 * Merged in the work Walter has done for __vector type support. =A0T=
here are now newly available GCC builtins for vector operations via gcc.bui= ltins module.
 Allowing !=3D128 bits wide types would be just a matter of removing t=
he frontend
 restrictions, right? (i didn't look at the latest commits, maybe you =
already did
 that)
 As the vector ops often will need to be wrapped, lack of cross module=
function
 inlining is a problem.
If you want cross-module inlining, compile all sources in one command. gdc file1.d file2.d -o myapp
Does this work for '-c' too? For building libs, like eg phobos? Hmm, '-fonly" seems like it could work, together with '-c' -- I have ne=
ver
 used that option, will have to try it later - but if it works, shouldn'=
t it
 be on by default (for '-[cS]' invocations)?
It won't. =A0For inlining to work, the function body (that is available at compile-time in DMDFE AST) needs to be converted into GCC trees for the backend to inline. =A0-fonly, whilst it processes the semantic analysis on the other modules, does not generate any codegen for them. =A0For cross module inlining to properly work in the one-file-at-a-time compilation method, there needs to be an intermediate routine that says 'build this body now, but don't add the function to the global to output list'.
I guess treating the functions like C "extern inline"'s isn't possible?
Like gnu_inline? It will have to be implemented.
 BTW, is the GDC exception handling compatible with C++?
It's practically rewrite of the C++ exception routine in D. But don't quote me on it being directly compatible.
Hmm, i was looking for more incompatibilities, but i guess expecting to directly throw/catch D exceptions from C++ (and v/v) is a bit too much. :=
)

Yes, that is.  I can't find the file at the moment, but if you were to
compare the two (C++ exception handling and D exception handling) -
you can easily point two fingers between which functions correlate to
which.


 What makes you think changing the calling convention will turn off
 name mangling?
My point is that modifying the ABI has a significant cost and can't eas=
ily
 be undone. I don't see much gain from switching from one nonstd convent=
ion
 to a different nonstd convention, which is /similar/ to the C one, but =
still
 not directly accessible from C.
 What does your change mean? Programs now use a worse calling convention=
(not
 even one arg gets passed in a register), object files and libraries gen=
erated
 by different D compilers are incompatible (by design, not just because =
of some
 implementation quirk), worse, mixing libs produced by different toolcha=
ins may
 seem to work, only to fail at runtime. Where's the gain?
1. =A0My point is that modifying the ABI has a significant cost and can't easily be undone. I don't see much gain from switching from one nonstd convention to a different nonstd convention, which is /similar/ to the C one, but still not directly accessible from C. A calling convention that is used by the target platform is better than a calling convention that is used by no one but yourself. =A0Also, I don't see how name mangling is part of the calling convention, but maybe that's just me (I am aware that name mangling is part of various Windows calling conventions, but not in *nix. :-)
It isn't, but if you can't (easily) call the "D" code from C/C++ it might as well be. If you need proper annotations at every language border crossing, what advantage does using the same calling convention give you?..
 2. What does your change mean? Programs now use a worse calling
 convention (not even one arg gets passed in a register),

 *cough* for x86 *cough*

 I can't see how you can use this as an argument. Parameter passing
 hasn't changed for x86, only the way certain values are returned. So
 it is *still* as bad as it was *before* the change.
So gdc didn't implement the official (dlang.org) convention, and i was fooled by LTO? :)
x86 does implicitly turn on regparm when compiling with -O for local functions only.
 3. object files and libraries generated by different D compilers are
 incompatible (by design, not just because of some implementation
 quirk), worse, mixing libs produced by different toolchains may seem
 to work, only to fail at runtime. Where's the gain?

 It has always been this way. I've never known people to frequently mix
 compilers when building code.
Shared libraries. Distributions, such as Ubuntu. Does every OS vendor have to provide different packages for different D "stacks"? Every D library will come in a DMD version, GDC version and a LDC version? Or will just one compiler be picked, because the alternative isn't really acceptable? Note the former also means packaging every application using *any* D shared library (and i guess this can include phobos) N times. Let's hope nobody else decides to make a D compiler. :)
 * "naked" has now been implemented now as a function attribute of th=
e x86 platform. =A0It is applied to all naked functions, and implies noinli= ne and noclone.
 I've never really understood the reason for "naked". Custom prologue =
and epilogue
 could be useful sometimes, but turning the compiler into an assembler=
?... You can
 already write "naked" asm functions in gcc - with asm()s outside of f=
unctions
 plus some as(1) section push/pop magic, iirc.
 Now you've removed the D builtin assembler, but decided to introduce =
"naked".
 Is it really necessary? There are no back-compat concerns...
 How does naked work will the various gcc features the modify prologue=
(profiling,
 stack usage checking, forced stack aligment etc)?
I have not removed the D builtin assembler. I have just removed D_InlineAsm version identifers. =A0GDC's "naked" function support was originally a (pretty bad) hack in GCC. =A0It is now implemented cleanl=
y
 as a function attribute, and does not affect the code generation of
 other frontends.
I meant something like "practically removed the availability of D built=
in
 assembler by removing the guarding version identifiers", sorry.
 But doesn't this mean that, right now, there are exactly zero users of =
this
 feature (gcc naked functions)?..
 There is naked support for other architectures that have been accepted
 in GCC (arm, avr, m68k, mcore, rx, spu) - yes I had to =A0look them up.
 :-)
I meant "zero D users". :^) And was wondering if introducing something D-related that nobody was using made sense. I admit to *not* checking if some arch already had it. =
:)
 artur
naked functions are used by D programmers. Last example I can think of off the top of my head I aided were two OS developers writing a kernel in D. --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
Jan 16 2012
prev sibling parent "Kagamin" <spam here.lot> writes:
On Sunday, 15 January 2012 at 22:34:28 UTC, Iain Buclaw wrote:
 * GDC's default calling convention has now been switched back 
 to that of the default for the target platform. The D_InlineAsm 
 family of version identifiers are now turned off by default as 
 we no longer pretend to follow DMD's calling convention. For 
 those who want to turn on D_InlineAsm(_X86/_x86_64) there is a 
 -fd-inline-asm compiler switch.
BTW, why does it affect 64-bit code? Doesn't 64-bit already has one calling convention for all?
Jan 27 2012