www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - __ctfe

reply "Philippe Sigaud" <philippe.sigaud gmail.com> writes:
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?
Oct 01 2012
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
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.
Oct 01 2012
next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
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!
Oct 01 2012
prev sibling parent reply Don Clugston <dac nospam.com> writes:
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.
Oct 02 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Oct 02 2012
parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
"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
Oct 02 2012