www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - For the lulz: ddmd vs libdparse lexer timings

reply "Brian Schott" <briancschott gmail.com> writes:
Looks like it's time to spend some more time with perf:

http://i.imgur.com/k50dFbU.png

X-axis: Meaningless (Phobos module file names)
Y-axis: Time in "hnsecs" (Lower is better)

I had to hack the ddmd code to get it compile (more "1337 h4x" 
were required to compile with LDC than with DMD), so I haven't 
uploaded the code for the benchmark to Github yet.

Both tests were in the same binary and thus had the same compiler 
flags.
Jan 04 2015
next sibling parent "Brian Schott" <briancschott gmail.com> writes:
On Monday, 5 January 2015 at 00:50:57 UTC, Brian Schott wrote:
 http://i.imgur.com/k50dFbU.png
Some notes: 1) If you use D-Scanner or DCD on a regular basis, you really should compile it with gdc or ldc. 2) Everybody can guess which module 14 is.
Jan 04 2015
prev sibling next sibling parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Brian Schott"  wrote in message 
news:phwlklufefyocyuliima forum.dlang.org...

 Looks like it's time to spend some more time with perf:

 http://i.imgur.com/k50dFbU.png
Nice!
 I had to hack the ddmd code to get it compile (more "1337 h4x" were 
 required to compile with LDC than with DMD), so I haven't uploaded the 
 code for the benchmark to Github yet.
Were you compiling it with 2.066.1 or master? I'd be interested to see the changes you needed.
Jan 04 2015
parent reply "Brian Schott" <briancschott gmail.com> writes:
On Monday, 5 January 2015 at 03:01:11 UTC, Daniel Murphy wrote:
 "Brian Schott"  wrote in message 
 news:phwlklufefyocyuliima forum.dlang.org...

 Looks like it's time to spend some more time with perf:

 http://i.imgur.com/k50dFbU.png
Nice!
 I had to hack the ddmd code to get it compile (more "1337 h4x" 
 were required to compile with LDC than with DMD), so I haven't 
 uploaded the code for the benchmark to Github yet.
Were you compiling it with 2.066.1 or master? I'd be interested to see the changes you needed.
DMD 2.066.1 and LDC 0.15.1. Most of it involved adding some ulong -> uint casts and commenting out _d_newclass and everything involving __va_argsave.
Jan 04 2015
next sibling parent reply "Brian Schott" <briancschott gmail.com> writes:
Also, DMD didn't like the body of the halt() function.
Jan 04 2015
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Brian Schott"  wrote in message 
news:cmqleuoppesrhchnnacx forum.dlang.org...

 Also, DMD didn't like the body of the halt() function.
Only if you compile with with -O and -debug together.
Jan 04 2015
parent reply "Brian Schott" <briancschott gmail.com> writes:
On Monday, 5 January 2015 at 03:46:00 UTC, Daniel Murphy wrote:
 "Brian Schott"  wrote in message 
 news:cmqleuoppesrhchnnacx forum.dlang.org...

 Also, DMD didn't like the body of the halt() function.
Only if you compile with with -O and -debug together.
Getting dub to turn on optimizations is easier than getting it to turn off debugging.
Jan 04 2015
parent Jacob Carlborg <doob me.com> writes:
On 2015-01-05 05:04, Brian Schott wrote:

 Getting dub to turn on optimizations is easier than getting it to turn
 off debugging.
dub build --build=release ? -- /Jacob Carlborg
Jan 05 2015
prev sibling parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Brian Schott"  wrote in message 
news:erlwjgsltofsjmscpmop forum.dlang.org...

 DMD 2.066.1 and LDC 0.15.1.
Ah ok, I've only tested it with master.
 Most of it involved adding some ulong -> uint casts and
Looks like I forgot to test it on linux and 64-bit https://github.com/D-Programming-Language/dmd/pull/4251
 commenting out _d_newclass and everything involving __va_argsave.
Hmm, __va_argsave might be a dmd-specific hack. It should work fine with or without _d_newclass though.
Jan 04 2015
parent reply "David Nadlinger" <code klickverbot.at> writes:
On Monday, 5 January 2015 at 03:41:17 UTC, Daniel Murphy wrote:
 Hmm, __va_argsave might be a dmd-specific hack.
It is. It breaks vararg cross-platform compatibility (e.g. Linux x86 vs. Linux x86_64) and GDC/LDC will never need it. It's something that we really to be fixed sooner than later. The only reason why the current situation is bearable is that C varargs are rarely ever used in D-only code. David
Jan 04 2015
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"David Nadlinger"  wrote in message 
news:qlzdmlnzlklofmlkqpby forum.dlang.org...

 It is. It breaks vararg cross-platform compatibility (e.g. Linux x86 vs. 
 Linux x86_64) and GDC/LDC will never need it. It's something that we 
 really to be fixed sooner than later. The only reason why the current 
 situation is bearable is that C varargs are rarely ever used in D-only 
 code.
Do you know how to fix it in dmd? I don't know why it's there in the first place.
Jan 05 2015
parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 5 January 2015 at 08:28, Daniel Murphy via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 "David Nadlinger"  wrote in message
 news:qlzdmlnzlklofmlkqpby forum.dlang.org...

 It is. It breaks vararg cross-platform compatibility (e.g. Linux x86 vs.
 Linux x86_64) and GDC/LDC will never need it. It's something that we really
 to be fixed sooner than later. The only reason why the current situation is
 bearable is that C varargs are rarely ever used in D-only code.
Do you know how to fix it in dmd? I don't know why it's there in the first place.
It is there because you still use a synthetic pointer for C varargs on x86_64. This synthetic pointer needs to be initialised to point to a static array otherwise bad things happen when you pass on to C. Enter __va_argsave to the rescue. void foo(int bar, ...) { va_list* va = void; va_list[1] __va_argsave; va = &__va_argsave; ... } The above being compiler generated by DMD.
Jan 05 2015
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw via Digitalmars-d"  wrote in message 
news:mailman.4141.1420448690.9932.digitalmars-d puremagic.com...

 void foo(int bar, ...)
 {
   va_list* va = void;
   va_list[1] __va_argsave;
   va = &__va_argsave;

   ...
 }

 The above being compiler generated by DMD.
Should that be va = &__va_argsave[0] ? So what _should_ DMD be generating?
Jan 05 2015
parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 5 January 2015 at 09:23, Daniel Murphy via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 "Iain Buclaw via Digitalmars-d"  wrote in message
 news:mailman.4141.1420448690.9932.digitalmars-d puremagic.com...

 void foo(int bar, ...)
 {
   va_list* va = void;
   va_list[1] __va_argsave;
   va = &__va_argsave;

   ...
 }

 The above being compiler generated by DMD.
Should that be va = &__va_argsave[0] ?
Yes. More or less, both should do the same. :-)
  So what _should_ DMD be generating?
That depends on how we agree to go forward with this. From memory, we each do / did things differently. I have no doubt that the way I've done it is a kludge at best, but I'll explain it anyway. GDC *always* uses the real va_list type, our type-strict backend demands at least that from us. So when it comes down to the problem of passing around va_list when it's a static array (extern C expects a ref), I rely on people using core.vararg/gcc.builtins to get the proper __builtin_va_list before importing modules such as core.stdc.stdio (printf and friends) - as these declarations are then rewritten by the compiler from: int vprintf(__builtin_va_list[1] va, in char* fmt, ...) to: int vprintf(ref __builtin_va_list[1] va, in char* fmt, ...) This is an *esper* workaround, and ideally, I shouldn't be doing this...
Jan 05 2015
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw via Digitalmars-d"  wrote in message 
news:mailman.4143.1420452193.9932.digitalmars-d puremagic.com...

 That depends on how we agree to go forward with this.  From memory, we
 each do / did things differently.

 I have no doubt that the way I've done it is a kludge at best, but
 I'll explain it anyway.

 GDC *always* uses the real va_list type, our type-strict backend
 demands at least that from us.  So when it comes down to the problem
 of passing around va_list when it's a static array (extern C expects a
 ref), I rely on people using core.vararg/gcc.builtins to get the
 proper __builtin_va_list before importing modules such as
 core.stdc.stdio (printf and friends) - as these declarations are then
 rewritten by the compiler from:

 int vprintf(__builtin_va_list[1] va, in char* fmt, ...)

 to:

 int vprintf(ref __builtin_va_list[1] va, in char* fmt, ...)


 This is an *esper* workaround, and ideally, I shouldn't be doing this...
I just read the discussion in https://github.com/D-Programming-Language/dmd/pull/3568 and I think I finally get it, lol. AIUI your solution won't work for user C++ functions that take va_list, because either type or mangling will be correct, but never both. Is that correct? Can gdc compile the tests in 3568? I'm going to have a look at turning va_list into a magic type that the compiler will pass by reference when necessary and always mangle correctly.
Jan 05 2015
parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 5 January 2015 at 11:21, Daniel Murphy via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 "Iain Buclaw via Digitalmars-d"  wrote in message
 news:mailman.4143.1420452193.9932.digitalmars-d puremagic.com...

 That depends on how we agree to go forward with this.  From memory, we
 each do / did things differently.

 I have no doubt that the way I've done it is a kludge at best, but
 I'll explain it anyway.

 GDC *always* uses the real va_list type, our type-strict backend
 demands at least that from us.  So when it comes down to the problem
 of passing around va_list when it's a static array (extern C expects a
 ref), I rely on people using core.vararg/gcc.builtins to get the
 proper __builtin_va_list before importing modules such as
 core.stdc.stdio (printf and friends) - as these declarations are then
 rewritten by the compiler from:

 int vprintf(__builtin_va_list[1] va, in char* fmt, ...)

 to:

 int vprintf(ref __builtin_va_list[1] va, in char* fmt, ...)


 This is an *esper* workaround, and ideally, I shouldn't be doing this...
I just read the discussion in https://github.com/D-Programming-Language/dmd/pull/3568 and I think I finally get it, lol. AIUI your solution won't work for user C++ functions that take va_list, because either type or mangling will be correct, but never both. Is that correct? Can gdc compile the tests in 3568?
That is correct for user code, but not druntime C bindings. GDC can compile the test in 3568 thanks to the GCC backend providing the va_list struct a name (__va_list_tag). However it for sure cannot run the program though. Only body-less declarations in core.stdc.* are rewritten to ref va_list.
Jan 05 2015
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw via Digitalmars-d"  wrote in message 
news:mailman.4146.1420457999.9932.digitalmars-d puremagic.com...

 That is correct for user code, but not druntime C bindings.

 GDC can compile the test in 3568 thanks to the GCC backend providing
 the va_list struct a name (__va_list_tag).

 However it for sure cannot run the program though.  Only body-less
 declarations in core.stdc.* are rewritten to ref va_list.
Druntime and phobos rely on va_list converting to void*. Should this a) be allowed on platforms where va_list is a pointer b) always be allowed c) never be allowed ???
Jan 05 2015
next sibling parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Daniel Murphy"  wrote in message news:m8dv1g$1cg4$1 digitalmars.com... 

 Druntime and phobos rely on va_list converting to void*.  Should this
 a) be allowed on platforms where va_list is a pointer
 b) always be allowed
 c) never be allowed
 ??? 
And what about explicit casts?
Jan 05 2015
next sibling parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Daniel Murphy"  wrote in message news:m8dv49$1cgs$1 digitalmars.com...

 And what about explicit casts?
Oh yeah, and how does __va_argsave work, why do we need it? Looking at the druntime and phobos code, I'm not sure which stuff is correct, which stuff needs to have the X86_64 version deleted, and which should be moved to va_arg.
Jan 05 2015
parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 5 January 2015 at 13:37, Daniel Murphy via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 "Daniel Murphy"  wrote in message news:m8dv49$1cgs$1 digitalmars.com...

 And what about explicit casts?
Oh yeah, and how does __va_argsave work, why do we need it? Looking at the druntime and phobos code, I'm not sure which stuff is correct, which stuff needs to have the X86_64 version deleted, and which should be moved to va_arg.
IIRC, there is some minor duplication between std.format and core.stdc.stdarg, but I think that we really should be able to get things working without changing druntime or phobos.
Jan 05 2015
prev sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 5 January 2015 at 12:13, Daniel Murphy via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 "Daniel Murphy"  wrote in message news:m8dv1g$1cg4$1 digitalmars.com...
 Druntime and phobos rely on va_list converting to void*.  Should this
 a) be allowed on platforms where va_list is a pointer
 b) always be allowed
 c) never be allowed
 ???
And what about explicit casts?
Casts should always be explicit. I think it would be best if va_list is treated as a distinct type to others, even if the underlying type is a char* (x86) or void* (ARM OABI).
Jan 05 2015
prev sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 5 January 2015 at 12:11, Daniel Murphy via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 "Iain Buclaw via Digitalmars-d"  wrote in message
 news:mailman.4146.1420457999.9932.digitalmars-d puremagic.com...

 That is correct for user code, but not druntime C bindings.

 GDC can compile the test in 3568 thanks to the GCC backend providing
 the va_list struct a name (__va_list_tag).

 However it for sure cannot run the program though.  Only body-less
 declarations in core.stdc.* are rewritten to ref va_list.
Druntime and phobos rely on va_list converting to void*. Should this a) be allowed on platforms where va_list is a pointer b) always be allowed c) never be allowed ???
For consistency? I would go with (c) as va_list could be anything, even a struct (PPC). That and people shouldn't (*!*) be manipulating va_list directly, though unfortunately we do for std.format, etc. The only realistic option would be (a).
Jan 05 2015
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw via Digitalmars-d"  wrote in message 
news:mailman.4157.1420479008.9932.digitalmars-d puremagic.com...

 For consistency? I would go with (c) as va_list could be anything,
 even a struct (PPC). That and people shouldn't (*!*) be manipulating
 va_list directly, though unfortunately we do for std.format, etc.

 The only realistic option would be (a).
I think the only code that needs to manipulate va_list directly is low-level enough that forcing use of a union or *cast(void**)&va is reasonable. I think I've got a handle on this, sort of. I've moved the declaration of __va_argsave into the glue layer, and added intrinsic detection for va_start/va_end/va_arg (the two-arg form). I've implemented them in the backend for win32 and they have passed a simple test! I'll run some more extensive tests tomorrow, and then have a look at some other platforms. Do you think we can change _all_ the druntime and phobos code to just use va_arg directly? It would be nice to have it all portable like that.
Jan 05 2015
next sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 5 January 2015 at 17:44, Daniel Murphy via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 "Iain Buclaw via Digitalmars-d"  wrote in message
 news:mailman.4157.1420479008.9932.digitalmars-d puremagic.com...

 For consistency? I would go with (c) as va_list could be anything,
 even a struct (PPC). That and people shouldn't (*!*) be manipulating
 va_list directly, though unfortunately we do for std.format, etc.

 The only realistic option would be (a).
I think the only code that needs to manipulate va_list directly is low-level enough that forcing use of a union or *cast(void**)&va is reasonable. I think I've got a handle on this, sort of. I've moved the declaration of __va_argsave into the glue layer, and added intrinsic detection for va_start/va_end/va_arg (the two-arg form). I've implemented them in the backend for win32 and they have passed a simple test! I'll run some more extensive tests tomorrow, and then have a look at some other platforms. Do you think we can change _all_ the druntime and phobos code to just use va_arg directly? It would be nice to have it all portable like that.
Oh, yeah, do it! You have references to __va_argsave in phobos, don't you?
Jan 05 2015
next sibling parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw via Digitalmars-d"  wrote in message 
news:mailman.4161.1420481405.9932.digitalmars-d puremagic.com...

 I think I've got a handle on this, sort of.  I've moved the declaration 
 of
 __va_argsave into the glue layer, and added intrinsic detection for
 va_start/va_end/va_arg (the two-arg form).

 I've implemented them in the backend for win32 and they have passed a 
 simple
 test!
I now have it working (and tested) for win32/linux32/linux64. va_start and va_copy will probably both need intrinsics, but druntime's va_arg is fine. On x86_64 all I do is completely ignore the second parameter to va_start and memcpy the fields in. I haven't done va_copy yet, but it should be fairly simple.
 Do you think we can change _all_ the druntime and phobos code to just 
 use
 va_arg directly?  It would be nice to have it all portable like that.
Oh, yeah, do it! You have references to __va_argsave in phobos, don't you?
There are a _lot_ in lifetime.d. These should have been replaced with non-variadic versions years ago, so I'm going to do that instead of trying to un-hack them. https://github.com/D-Programming-Language/dmd/pull/4303 https://github.com/D-Programming-Language/druntime/pull/1102
Jan 16 2015
prev sibling parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw via Digitalmars-d"  wrote in message 
news:mailman.4161.1420481405.9932.digitalmars-d puremagic.com...

 Do you think we can change _all_ the druntime and phobos code to just 
 use
 va_arg directly?  It would be nice to have it all portable like that.
Oh, yeah, do it! You have references to __va_argsave in phobos, don't you?
Here it is: https://github.com/D-Programming-Language/phobos/pull/2926 __va_argsave wasn't used here, but it was creating its own __va_argsave_t in order to abuse va_arg!
Jan 27 2015
prev sibling next sibling parent reply "David Nadlinger" <code klickverbot.at> writes:
On Monday, 5 January 2015 at 17:44:31 UTC, Daniel Murphy wrote:
 I think I've got a handle on this, sort of.  I've moved the 
 declaration of __va_argsave into the glue layer, and added 
 intrinsic detection for va_start/va_end/va_arg (the two-arg 
 form).

 I've implemented them in the backend for win32 and they have 
 passed a simple test!
I'd suggest you have a look at Posix x86_64 first before finalizing the "easy" x86 implementation. The former comes with two extra niceties compared to the simple "pointer to stack-allocated arguments" model: 1) You need to copy the registers to the stack on function entry (in case the arguments are later accessed using va_arg, they are just regular functions on the caller side), and then be able to access the address of this area in va_start. This is what va_argsave is currently used for in DMD. 2) The issue with passing va_list as a parameter (especially regarding C ABI compatibility) vs. allocating the struct storage allocation. If you simply make it a pointer on x86_64, it's hard to implement va_copy correctly. The DMD implementation of the latter is currently broken, which is the reason for some of the vararg-related version(X86_64) blocks.
 Do you think we can change _all_ the druntime and phobos code 
 to just use va_arg directly?  It would be nice to have it all 
 portable like that.
Yes. Some parts might need a bit of rework, though. This job would be quite a bit easier if we could finally ditch the old vararg-based std.format stuff before. Be sure to let me know if you have any specific questions. David
Jan 06 2015
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"David Nadlinger"  wrote in message 
news:qzodhfgpknmlbjtnwmqc forum.dlang.org...

 I'd suggest you have a look at Posix x86_64 first before finalizing the 
 "easy" x86 implementation. The former comes with two extra niceties 
 compared to the simple "pointer to stack-allocated arguments" model:
I know, I had a read of the ABI. x86 certainly is easy mode.
   1) You need to copy the registers to the stack on function entry (in 
 case the arguments are later accessed using va_arg, they are just regular 
 functions on the caller side), and then be able to access the address of 
 this area in va_start. This is what va_argsave is currently used for in 
 DMD.
Yes, but __va_argsave is declared in the frontend, which is unnecessary. It was easy enough to make the glue layer reserve the right number of bytes for varargs functions.
   2) The issue with passing va_list as a parameter (especially regarding C 
 ABI compatibility) vs. allocating the struct storage allocation. If you 
 simply make it a pointer on x86_64, it's hard to implement va_copy 
 correctly. The DMD implementation of the latter is currently broken, which 
 is the reason for some of the vararg-related version(X86_64) blocks.
I made it a magic compiler type, and I'll make it automagically pass by ref when used as a function argument on X86_64 posix. That should do it.
 Yes. Some parts might need a bit of rework, though. This job would be 
 quite a bit easier if we could finally ditch the old vararg-based 
 std.format stuff before.

 Be sure to let me know if you have any specific questions.
How does LDC currently handle it? Does llvm have an easy way to handle the implementation of va_* for you?
Jan 06 2015
parent reply "David Nadlinger" <code klickverbot.at> writes:
On Tuesday, 6 January 2015 at 15:42:22 UTC, Daniel Murphy wrote:
 Yes, but __va_argsave is declared in the frontend, which is 
 unnecessary.  It was easy enough to make the glue layer reserve 
 the right number of bytes for varargs functions.
I agree. Walter said that he didn't manage to implement it back then, though, and I never looked at the glue layer.
 I made it a magic compiler type, and I'll make it automagically 
 pass by ref when used as a function argument on X86_64 posix.  
 That should do it.
Yes, that should indeed do it. I shied away from unilaterially making it a "magic" type in LDC to avoid unpleasant surprises for users. However, it is definitely the cleaner option imho.
 How does LDC currently handle it?  Does llvm have an easy way 
 to handle the implementation of va_* for you?
LLVM gives us va_start/…, and in theory also va_arg. However, there are two issues why we don't use the latter on Posix x86_64 and rely on Walter's druntime implementation instead: 1) For the template version of va_arg(), we'd need to redo the lowering of D types to the ABI types (passing in registers and so on, which is sadly not automatic in LLVM as its type system can't represent all C types). This could be implemented somewhat easily on top of argTypes, but because of 2) it was not really worth the effort. 2) There is also a va_arg version that takes a TypeInfo at runtime. There doesn't really seem to be a way to implement this on top of what LLVM offers. And as I said above, we currently have va_list as a pointer type for reasons of simplicity. Thus, we need to actually have our LDC va_start/va_copy intrinsics actually allocate memory for the register save area on the stack before forwarding to the LLVM ones. This is a huge hack, but just about seems to be enough to covervirtually all real-world use cases. In any case, I'm looking forward to cleaning this mess up once your DMD patches are in. David
Jan 06 2015
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
Is there something wrong with this code or have I found a dmc bug?

#include <stdarg.h>
#include <assert.h>

struct S16 {
    char val_0;
    unsigned char val_1;
    int val_2;
    unsigned val_3;
    long long val_4;
    unsigned val_5;
};

void checkValues(int arg0, unsigned long long arg1, long long arg2, int 
arg3, S16 arg4, unsigned arg5, double arg6);
void cppvararg(int arg0, unsigned long long arg1, ...)
{
    long long arg2;
    int arg3;
    S16 arg4;
    unsigned arg5;
    double arg6;
    va_list va;
    va_start(va, arg1);
    // __asm nop;
    arg2 = va_arg(va, long long);
    arg3 = va_arg(va, int);
    arg4 = va_arg(va, S16);
    arg5 = va_arg(va, unsigned);
    arg6 = va_arg(va, double);
    va_end(va);
    checkValues(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
}


void checkValues(int arg0, unsigned long long arg1, long long arg2, int 
arg3, S16 arg4, unsigned arg5, double arg6)
{
    assert(arg0 == 99);
    assert(arg1 == 99);
    assert(arg2 == 99);
    assert(arg3 == 99);
    assert(arg4.val_0 == 99);
    assert(arg4.val_1 == 99);
    assert(arg4.val_2 == 99);
    assert(arg4.val_3 == 99);
    assert(arg4.val_4 == 99);
    assert(arg4.val_5 == 99);
    assert(arg5 == 99);
    assert(arg6 == 0);
}

void main()
{
    int arg0 = 99;
    unsigned long long arg1 = 99;
    long long arg2 = 99;
    int arg3 = 99;
    S16 arg4 = {99, 99, 99, 99, 99, 99};
    unsigned arg5 = 99;
    double arg6 = 0;
    // dvararg(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
    cppvararg(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
}
Jan 06 2015
parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 7 January 2015 at 05:27, Daniel Murphy via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 Is there something wrong with this code or have I found a dmc bug?
I'd say bug in dmc.
Jan 07 2015
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw via Digitalmars-d"  wrote in message 
news:mailman.4248.1420631820.9932.digitalmars-d puremagic.com...

 I'd say bug in dmc.
Yeah I'm thinking so, fun. It looks like dmc sets up the code to copy the struct into the variable but never bothers emitting the loop/movsds. What about this: struct S { } void main() { S a = void; S b = void; assert(a == b); // Should this ever fail? }
Jan 07 2015
parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 7 January 2015 at 12:35, Daniel Murphy via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 "Iain Buclaw via Digitalmars-d"  wrote in message
 news:mailman.4248.1420631820.9932.digitalmars-d puremagic.com...

 I'd say bug in dmc.
Yeah I'm thinking so, fun. It looks like dmc sets up the code to copy the struct into the variable but never bothers emitting the loop/movsds. What about this: struct S { } void main() { S a = void; S b = void; assert(a == b); // Should this ever fail? }
No, that assert should never fail.
Jan 07 2015
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw via Digitalmars-d"  wrote in message 
news:mailman.4250.1420635158.9932.digitalmars-d puremagic.com...

 No, that assert should never fail.
And yet for some reason it does.
Jan 07 2015
parent reply "Tobias Pankrath" <tobias pankrath.net> writes:
On Wednesday, 7 January 2015 at 13:02:20 UTC, Daniel Murphy wrote:
 "Iain Buclaw via Digitalmars-d"  wrote in message 
 news:mailman.4250.1420635158.9932.digitalmars-d puremagic.com...

 No, that assert should never fail.
And yet for some reason it does.
Every type has at least a size of one byte. So a and b occupy different stack slots due to padding. The default op== does a memcmp and compares the padding as well. My guess.
Jan 07 2015
parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Tobias Pankrath"  wrote in message 
news:sdturuippuqoqvbuqqox forum.dlang.org...

 Every type has at least a size of one byte. So a and b occupy different 
 stack slots due to padding. The default op== does a memcmp and compares 
 the padding as well.

 My guess.
Haha yes, you're spot on. I was asking more like, why does dmd do something so stupid? https://issues.dlang.org/show_bug.cgi?id=13947
Jan 07 2015
prev sibling parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Daniel Murphy"  wrote in message news:m8eihu$21to$1 digitalmars.com...

 I'll run some more extensive tests tomorrow, and then have a look at some 
 other platforms.
The problem with using a fuzz tester to verify the new varargs implementation is I need to fix all the existing ABI bugs first.
Jan 08 2015
prev sibling next sibling parent reply "Brian Schott" <briancschott gmail.com> writes:
On Monday, 5 January 2015 at 00:50:57 UTC, Brian Schott wrote:
 Looks like it's time to spend some more time with perf:

 http://i.imgur.com/k50dFbU.png

 X-axis: Meaningless (Phobos module file names)
 Y-axis: Time in "hnsecs" (Lower is better)

 I had to hack the ddmd code to get it compile (more "1337 h4x" 
 were required to compile with LDC than with DMD), so I haven't 
 uploaded the code for the benchmark to Github yet.

 Both tests were in the same binary and thus had the same 
 compiler flags.
Now with more copy-paste inlining! http://i.imgur.com/D5IAlvl.png I'm glad I could get this kind of speed up, but not happy with how ugly the changes were.
Jan 05 2015
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Brian Schott"  wrote in message 
news:bhmpbqutpimjxtbcsrtw forum.dlang.org...

 Now with more copy-paste inlining!

 http://i.imgur.com/D5IAlvl.png

 I'm glad I could get this kind of speed up, but not happy with how ugly 
 the changes were.
Nice! How far would forceinline go to getting the same results without the ugly? I don't expect you to do this, but what features would ddmd's lexer need before you could entirely replace libdparse's with it?
Jan 06 2015
parent reply "Brian Schott" <briancschott gmail.com> writes:
On Tuesday, 6 January 2015 at 12:39:27 UTC, Daniel Murphy wrote:
 Nice!  How far would  forceinline go to getting the same 
 results without the ugly?
forceinline would solve all of it.
 I don't expect you to do this, but what features would ddmd's 
 lexer need before you could entirely replace libdparse's with 
 it?
It would have to be range-based and be capable of performing syntax highlighting. My D lexer is based on lexer generator code that might someday become std.lexer, so I want to keep it around to make sure that the std.lexer code is good enough.
Jan 06 2015
parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Brian Schott"  wrote in message 
news:wyligkafbpgxzlevfgwi forum.dlang.org...

  forceinline would solve all of it.
Ok, good.
 It would have to be range-based and be capable of performing syntax 
 highlighting. My D lexer is based on lexer generator code that might 
 someday become std.lexer, so I want to keep it around to make sure that 
 the std.lexer code is good enough.
It would be great to get to the point where it's trivial to swap them out.
Jan 07 2015
prev sibling parent Shammah Chancellor <anonymous coward.com> writes:
On 2015-01-05 00:50:55 +0000, Brian Schott said:

 Looks like it's time to spend some more time with perf:
 
 http://i.imgur.com/k50dFbU.png
 
 X-axis: Meaningless (Phobos module file names)
 Y-axis: Time in "hnsecs" (Lower is better)
 
 I had to hack the ddmd code to get it compile (more "1337 h4x" were 
 required to compile with LDC than with DMD), so I haven't uploaded the 
 code for the benchmark to Github yet.
 
 Both tests were in the same binary and thus had the same compiler flags.
I'd be interested to know where libd sits on here. It's lexer is very clever. Props to Amaury or Bernhard (whoever wrote it) -S.
Jan 08 2015