Jump to page: 1 2
Thread overview
Recent changes to GDC.
Jan 15, 2012
Iain Buclaw
Jan 16, 2012
Manu
Jan 16, 2012
Daniel Green
Jan 16, 2012
Iain Buclaw
Jan 16, 2012
Daniel Green
Jan 16, 2012
Manu
Jan 17, 2012
Daniel Green
Jan 17, 2012
Manu
Jan 16, 2012
Iain Buclaw
Jan 16, 2012
Artur Skawina
Jan 26, 2012
Kagamin
Jan 16, 2012
Manu
Jan 16, 2012
Iain Buclaw
Jan 16, 2012
Trass3r
Jan 16, 2012
Artur Skawina
Jan 16, 2012
Iain Buclaw
Jan 16, 2012
Artur Skawina
Jan 16, 2012
Iain Buclaw
Jan 27, 2012
Kagamin
January 15, 2012
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';
January 16, 2012
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';
>


January 16, 2012
On 16 January 2012 09:03, Manu <turkeyman@gmail.com> 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 :)
>
>

Please raise bug report with build logs, thanks.



-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
January 16, 2012
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
January 16, 2012
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... :/


January 16, 2012
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



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


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


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


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

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.



-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
January 16, 2012
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.

January 16, 2012
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.  I don't recall anything else giving me problems.
>

Cool.  Do you have anything in your MinGW patch queue that might be worth merging in?


-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
January 16, 2012
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
January 16, 2012
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?
« First   ‹ Prev
1 2