Thread overview
__ctfe
Oct 01, 2012
Philippe Sigaud
Oct 01, 2012
Adam D. Ruppe
Oct 01, 2012
Philippe Sigaud
Oct 02, 2012
Don Clugston
Oct 02, 2012
Jonathan M Davis
Oct 02, 2012
Daniel Murphy
October 01, 2012
On Mon, Oct 1, 2012 at 8:36 PM, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

[Creating a new thread for this]

> __ctfe exists purely so that you can provide an alternate implementation which
> works at compile time when the normal implementation doesn't (since CTFE _is_
> more restrictive in what it allows than running a function at runtime is).

Something I wanted to ask for a long time: is there any runtime speed penalty in using __ctfe? I have functions that are OK at runtime and do not work at compile-time. If I find a way to make them work at CT and use __ctfe to distinguish the two branches, will runtime execution become slower?


October 01, 2012
On Monday, 1 October 2012 at 19:22:37 UTC, Philippe Sigaud wrote:
> Something I wanted to ask for a long time: is there any runtime speed penalty in using __ctfe?

No. What happens is when it goes to the compile the runtime code, __ctfe is a constant false, so then the optimizer can see it is obviously dead code and eliminate the branch entirely. You don't even have to use the -O switch to get this:

void test() {
	if(__ctfe) {
		asm { nop; nop; nop; nop; }
	} else {
		asm { hlt; }
	}
}

$ dmd test.d -c
$ objdump --disassemble test.o
Disassembly of section .text._D4test4testFZv:

00000000 <_D4test4testFZv>:
   0:   55                      push   %ebp
   1:   8b ec                   mov    %esp,%ebp
   3:   f4                      hlt
   4:   5d                      pop    %ebp
   5:   c3                      ret


Note that there's no trace of a compare, jmp, nor the nops from the dead ctfe branch.
October 01, 2012
On Mon, Oct 1, 2012 at 9:30 PM, Adam D. Ruppe <destructionator@gmail.com> wrote:
> On Monday, 1 October 2012 at 19:22:37 UTC, Philippe Sigaud wrote:
>>
>> Something I wanted to ask for a long time: is there any runtime speed penalty in using __ctfe?
>
>
> No. What happens is when it goes to the compile the runtime code, __ctfe is a constant false, so then the optimizer can see it is obviously dead code and eliminate the branch entirely.

Cool.I feared it was a runtime-determined value, somehow.


> $ dmd test.d -c
> $ objdump --disassemble test.o
> Disassembly of section .text._D4test4testFZv:
>
> 00000000 <_D4test4testFZv>:
>    0:   55                      push   %ebp
>    1:   8b ec                   mov    %esp,%ebp
>    3:   f4                      hlt
>    4:   5d                      pop    %ebp
>    5:   c3                      ret
>
>
> Note that there's no trace of a compare, jmp, nor the nops from the dead ctfe branch.

OK, I'm sold.

Thanks!
October 02, 2012
On 01/10/12 21:30, Adam D. Ruppe wrote:
> On Monday, 1 October 2012 at 19:22:37 UTC, Philippe Sigaud wrote:
>> Something I wanted to ask for a long time: is there any runtime speed
>> penalty in using __ctfe?
>
> No. What happens is when it goes to the compile the runtime code, __ctfe
> is a constant false, so then the optimizer can see it is obviously dead
> code and eliminate the branch entirely. You don't even have to use the
> -O switch to get this:

Yes, I was VERY careful about this. The "if (__ctfe)" branch gets discarded at the end of the front-end. The backend never sees it.
October 02, 2012
On Tuesday, October 02, 2012 09:45:10 Don Clugston wrote:
> On 01/10/12 21:30, Adam D. Ruppe wrote:
> > On Monday, 1 October 2012 at 19:22:37 UTC, Philippe Sigaud wrote:
> >> Something I wanted to ask for a long time: is there any runtime speed penalty in using __ctfe?
> > 
> > No. What happens is when it goes to the compile the runtime code, __ctfe is a constant false, so then the optimizer can see it is obviously dead code and eliminate the branch entirely. You don't even have to use the
> 
> > -O switch to get this:
> Yes, I was VERY careful about this. The "if (__ctfe)" branch gets discarded at the end of the front-end. The backend never sees it.

By the way, why is it not used in static if? That's what most of us would have expected (and it frequently seems to trip people up). I assume that it's due to some implementation detail of CTFE (like it doesn't really compile any functions differently for CTFE)?

- Jonathan M Davis
October 02, 2012
"Jonathan M Davis" <jmdavisProg@gmx.com> wrote in message news:mailman.477.1349164468.5162.digitalmars-d@puremagic.com...
>
> By the way, why is it not used in static if? That's what most of us would
> have
> expected (and it frequently seems to trip people up). I assume that it's
> due
> to some implementation detail of CTFE (like it doesn't really compile any
> functions differently for CTFE)?
>
> - Jonathan M Davis

Code inside static if blocks does not have to be semantically valid if it is
not selected, and is discarded well before the interpreter could be invoked
on it.  It could be done using static if or version, but that would require
duplicating the function and re-running semantic, which is less elegant and
not really what you want.
There is a little bit of explanation in the original bug report:
http://d.puremagic.com/issues/show_bug.cgi?id=3556