January 05, 2012
So regarding my assumptions about translating the D front end expressions
to GCC? Is that all simpler than I imagine?
Do you think GDC generates optimal code comparable to C code?

What about pure functions, can you make good on optimisations like caching results of pure functions, moving them outside loops, etc?

On 6 January 2012 00:03, Iain Buclaw <ibuclaw@ubuntu.com> wrote:

> On 5 January 2012 16:49, Manu <turkeyman@gmail.com> wrote:
> >> D is not a compiler, it is a language. Furthermore it is not true that DMDs backend is rubbish and there are already more backends than just
> the
> >> DMC backend.
> >
> >
> > Sorry, I was generalising a little general in that claim. And where I say 'rubbish', I was drawing comparison to the maturity of C compilers for
> x86,
> > which STILL have trouble and make lots of mistakes with centuries of man
> > hours of work.
> > DMD has inferior code gen (there was a post last night comparing some
> > disassemblies of trivial programs with GDC), will probably never rival
> GCC,
> > that's fine, it's a reference, I get that.
> > But to say that using GDC will magically fix code gen is also false. I'm
> not
> > familiar with the GCC code, so I may be wrong, but my understanding is
> that
> > there is frontend work, and frontend-GCC glue work that will allow for
> back
> > end optimisation (which GCC can do quite well) to work properly. This is
> > still a lot of work for a small OSS team.
> > I also wonder if the D language provides some opportunities for
> optimisation
> > that aren't expressible in other languages, and therefore may not already have an expression in the GCC back end... so I can imagine some of future optimisations frequently discussed in this forum won't just magically
> appear
> > with GCC/LLVM maturity. I can't imagine Iain and co extending the GCC
> back
> > end to support some obscure D optimisations happening any time soon.
> >
>
> Actually, it's just me. ;)
>
> So far I have come across no D optimisations that aren't supported in GCC.  Infact, most of the time I find myself thinking of how I can use obscure GCC optimisation X to improve D.    One example is an interesting feature of Fortran, though written with C++ in mind. Seems like something that could be right up D's street.
>
>
> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=147822
>
> --
> Iain Buclaw
>
> *(p < e ? p++ : p) = (c & 0x0f) + '0';
>


January 05, 2012
On 01/05/12 22:50, Iain Buclaw wrote:
> I don't think D enforces any sort of aliasing rules, but it would be nice to turn on strict aliasing though...

-fstrict-aliasing is already turned on by default in gdc...

artur
January 05, 2012
On 6 January 2012 00:10, Iain Buclaw <ibuclaw@ubuntu.com> wrote:

> The reasoning behind is more so that you can write asm statements on all architectures, not just x86. And with GDC being a frontend of GCC, seems a natural thing to support (this has actually been in GDC since 2004, so I'm not sure why you should through all arms up about it now).


When I was first reading about D I read that the inline assembler syntax is
built in and standardised in the language... and I gave a large sigh of
relief.
If that's not the case, there are competing asm syntax in D, well... that
sucks. Am I version-ing my asm blocks for DMD and GDC now like I have to in
C for VC and GCC?
Surely D should settle on just one... If that happens to be the GCC syntax
for compatibility, great...?


January 05, 2012
On 5 January 2012 22:11, Manu <turkeyman@gmail.com> wrote:
> So regarding my assumptions about translating the D front end expressions to
> GCC? Is that all simpler than I imagine?
> Do you think GDC generates optimal code comparable to C code?
>
> What about pure functions, can you make good on optimisations like caching results of pure functions, moving them outside loops, etc?
>
>

I think you are confusing the pure with memoization.  I could be wrong however... :)

-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
January 05, 2012
On 6 January 2012 00:17, Iain Buclaw <ibuclaw@ubuntu.com> wrote:

> On 5 January 2012 22:11, Manu <turkeyman@gmail.com> wrote:
> > So regarding my assumptions about translating the D front end
> expressions to
> > GCC? Is that all simpler than I imagine?
> > Do you think GDC generates optimal code comparable to C code?
> >
> > What about pure functions, can you make good on optimisations like
> caching
> > results of pure functions, moving them outside loops, etc?
> >
> >
>
> I think you are confusing the pure with memoization.  I could be wrong however... :)


Umm, maybe... but I don't think so.
And I don't think you just answered either of my questions ;)


January 05, 2012
On Thursday, 5 January 2012 at 21:05:07 UTC, Sean Kelly wrote:
> On Jan 5, 2012, at 1:03 PM, Manu wrote:
>
>> That is the case with overriding a non-virtual function - the compiler will compile it anyway, and most of the time it will work. That's what makes it so eeevil.
>> 
>> I saw today, or last night, someone suggesting a keyword to make non-virtual override explicit, and error otherwise. Which actually sounded like a really good idea to me, and also addresses this problem.
>
> I think the override keyword fits here, though in reverse.

C# uses "new" and Delphi uses "reintroduce".
January 05, 2012
On 5 January 2012 22:16, Manu <turkeyman@gmail.com> wrote:
> On 6 January 2012 00:10, Iain Buclaw <ibuclaw@ubuntu.com> wrote:
>>
>> The reasoning behind is more so that you can write asm statements on all architectures, not just x86. And with GDC being a frontend of GCC, seems a natural thing to support (this has actually been in GDC since 2004, so I'm not sure why you should through all arms up about it now).
>
>
> When I was first reading about D I read that the inline assembler syntax is
> built in and standardised in the language... and I gave a large sigh of
> relief.
> If that's not the case, there are competing asm syntax in D, well... that
> sucks. Am I version-ing my asm blocks for DMD and GDC now like I have to in
> C for VC and GCC?
> Surely D should settle on just one... If that happens to be the GCC syntax
> for compatibility, great...?

For all its intentions, I think D-style syntax is great, however for GDC, all lines need to be translated into GCC-equivalent syntax when emitting AST.

Example - what ARM assembly would look like in D:

asm {
    cmp R0, R1;
    blt Lbmax;
    mov R2, R0;
    b Lrest;
Lbmax:
    mov R2, R1;
Lrest:
}

In order to compile *correctly*, we must be able to tell GCC what are outputs, what are inputs, what are labels, and what gets clobbered. The backend needs to know this to ensure syntax is correct, and it doesn't try to do anything odd that may invalidate what you are trying to do.  ie:  Output operands, the compiler can check this that outputs are lvalue.  Clobbers, tells the backend that a register is not free to use as a place to store temporary values.  Labels, tells the backend that this asm block of code could jmp to a given location, meaning it should be protected from the usual dead code elimination passes.

For this to work, requires the frontend to be *aware* of what assembly language it is compiling, and be able to parse it, understand it correctly.  Which would not be the most pleasant of things to implement granted the number of support architectures.  Converting x86 Intel syntax assembly to x86 GCC syntax assembly is enough for me. :)


-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
January 05, 2012
On Jan 5, 2012, at 2:08 PM, Manu wrote:

> On 5 January 2012 23:53, Sean Kelly <sean@invisibleduck.org> wrote:
> I recall Walter rejecting the idea because compilers shouldn't optimize across asm blocks.  This should probably be revisited at some point.
> 
> It's proven then, inline asm blocks break the optimiser... they are officially useless. This is why all C coders use intrinsics these days, and D should too.

For the record, some compilers do optimize across asm blocks.  It's simply DMD/DMC that doesn't.  Though the lack of "volatile" makes doing this unsafe in D as a general rule.
January 05, 2012
On 5/01/12 7:41 PM, Sean Kelly wrote:
> On Jan 5, 2012, at 10:02 AM, Manu wrote:
>>
>> That said, this is just one of numerous issues myself and the OP raised. I don't know why this one became the most popular for discussion... my suspicion is that is because this is the easiest of my complaints to dismiss and shut down ;)
>
> It's also about the only language change among the issues you mentioned.  Most of the others are QOI issues for compiler vendors.  What I've been curious about is if you really have a need for the performance that would be granted by these features, or if this is more of an idealistic issue.

It's not idealistic. For example, in my current project, I have a 3x perf improvement by rewriting that function with a few hundred lines of inline asm, purely to use SIMD instructions.

This is a nuisance because:

(a) It's hard to maintain. I have to thoroughly document what registers I'm using for what just so that I don't forget.

(b) Difficult to optimize further. I could optimize the inline assembly further by doing better scheduling of instructions, but instruction scheduling naturally messes up the organization of your code, which makes it a maintenance nightmare.

(c) It's not cross platform. Luckily x86/x86_64 are similar enough that I can write the code once and patch up the differences with CTFE + string mixins.

I know other parts of my code that would benefit from SIMD, but it's too much hassle to write and maintain inline assembly.

If we had support for

align(16) float[4] a, b;
a[] += b[]; // addps on x86

Then that would solve a lot of problems, but only solves the problem when you are doing "float-like" operations (addition, multiplication etc.) There's no obvious existing syntax for doing things like shuffles, conversions, SIMD square roots, cache control etc. that would naturally match to SIMD instructions.

Also, there's no way to tell the compiler whether you want to treat a float[4] as an array or a vector. Vectors are suited for data parallel execution whereas array are suited for indexing. If the compiler makes the wrong decision then you suffer heavily.

Ideally, we'd introduce vector types, e.g. vec_float4, vec_int4, vec_double2 etc.

These would naturally match to vector registers on CPUs and be aligned appropriately for the target platform.

Elementary operations would match naturally and generate the code you expect. Shuffling and other non-elementary operations would require the use of intrinsics.

// 4 vector norms in parallel
vec_float4 xs, ys, zs, ws;
vec_float4 lengths = vec_sqrt(xs * xs + ys * ys + zs * zs + ws * ws);

On x86 w/SSE, this would ideally generate:

// assuming xs in xmm0, ys in xmm1 etc.
mulps xmm0, xmm0;
mulps xmm1, xmm1;
addps xmm0, xmm1;
mulps xmm2, xmm2;
addps xmm0, xmm2;
mulps xmm3, xmm3;
addps xmm0, xmm3;
sqrtps xmm0, xmm0;

On platforms that don't support the vector types natively, there's two options (1) compile error, (2) compile, replacing them with float ops.

I think this is the only sensible way forward.
January 05, 2012
On 5 January 2012 22:22, Manu <turkeyman@gmail.com> wrote:
> On 6 January 2012 00:17, Iain Buclaw <ibuclaw@ubuntu.com> wrote:
>>
>> On 5 January 2012 22:11, Manu <turkeyman@gmail.com> wrote:
>> > So regarding my assumptions about translating the D front end
>> > expressions to
>> > GCC? Is that all simpler than I imagine?
>> > Do you think GDC generates optimal code comparable to C code?
>> >
>> > What about pure functions, can you make good on optimisations like
>> > caching
>> > results of pure functions, moving them outside loops, etc?
>> >
>> >
>>
>> I think you are confusing the pure with memoization.  I could be wrong however... :)
>
>
> Umm, maybe... but I don't think so.
> And I don't think you just answered either of my questions ;)

What I meant was, pure attribute will only allow the compiler to reduce the number of times the function is called in certain circumstances. However it makes no guarantees that it will do so, only if it think it's appropriate.

-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';