digitalmars.D - pragma(__ctfe)
- Nicholas Wilson (5/5) Sep 27 2023 I have need of the ability to suppress the code generation of
- Richard (Rikki) Andrew Cattermole (5/5) Sep 27 2023 I certainly would prefer ``assert(__ctfe);``.
- H. S. Teoh (12/13) Sep 27 2023 +1.
- Bruce Carneal (12/17) Sep 27 2023 The assert hack is useful but limited. It will not fail at
- Richard (Rikki) Andrew Cattermole (3/7) Sep 27 2023 This proposal (should this PR changed to it) would restrict that
- Bruce Carneal (3/11) Sep 28 2023 Correct.
- Nicholas Wilson (9/14) Sep 28 2023 That would suffer all the same problems that `pragma(inline)` as
- Richard (Rikki) Andrew Cattermole (5/7) Sep 28 2023 No not really, think about the constraints of CTFE.
- Steven Schveighoffer (19/29) Sep 28 2023 I think what Nic means is if you have a function:
- Richard (Rikki) Andrew Cattermole (3/40) Sep 28 2023 Yeah, I got it. Don't elide the function body of a CTFE only function,
- ryuukk_ (6/11) Sep 27 2023 Why couldn't the compiler already guess this?
- Richard (Rikki) Andrew Cattermole (5/10) Sep 27 2023 When you do multi-step builds (which are common), this would result in
- Bruce Carneal (5/16) Sep 28 2023 Correct. If the function is intended to actually be ctfe only,
- Basile B. (5/8) Nov 26 2023 Yes but that should be trivial to add a check during CallExp sema
- Imperatorn (4/9) Sep 28 2023 It's a good idea in general, but what alternatives exists? Could
- Steven Schveighoffer (24/31) Sep 28 2023 Have you tried immediately-called lambdas?
- Dave P. (48/79) Sep 28 2023 As far as I can tell, this already works.
- Steven Schveighoffer (3/5) Sep 28 2023 Oh nice! Since 2.103, I hadn't realized.
I have need of the ability to suppress the code generation of functions for using mixin generation functions with dcompute. Below is a link to a PR to implement that functionality. https://github.com/dlang/dmd/pull/15636 What are peoples thoughts on this?
Sep 27 2023
I certainly would prefer ``assert(__ctfe);``. It would opt-in existing code (correctly). That alone is a pretty convincing argument. Not having to learn additional things, and having what appears like it should work work is always a good design choice.
Sep 27 2023
On Thu, Sep 28, 2023 at 04:35:10PM +1300, Richard (Rikki) Andrew Cattermole via Digitalmars-d wrote:I certainly would prefer ``assert(__ctfe);``.+1. Maybe also detect code of the following form? auto func(Args args) { if (__ctfe) { ... } else assert(0); } T -- If it breaks, you get to keep both pieces. -- Software disclaimer notice
Sep 27 2023
On Thursday, 28 September 2023 at 03:35:10 UTC, Richard (Rikki) Andrew Cattermole wrote:I certainly would prefer ``assert(__ctfe);``. It would opt-in existing code (correctly). That alone is a pretty convincing argument. Not having to learn additional things, and having what appears like it should work work is always a good design choice.The assert hack is useful but limited. It will not fail at compile time, will not prevent all code/symbol generation, will not enable compile time understanding that the function is restricted to use at compile time (if that's useful apart from the other ...). I think we can do better in this area (eliminating/controlling spew to the linker) and in target enumeration generally {CT, generic CPU, CPU specializations, dcompute variants} but not without quite a bit more effort for the generality and/or soup-free analysis.
Sep 27 2023
On 28/09/2023 5:58 PM, Bruce Carneal wrote:The assert hack is useful but limited. It will not fail at compile time, will not prevent all code/symbol generation, will not enable compile time understanding that the function is restricted to use at compile time (if that's useful apart from the other ...).This proposal (should this PR changed to it) would restrict that function to CTFE only.
Sep 27 2023
On Thursday, 28 September 2023 at 06:02:05 UTC, Richard (Rikki) Andrew Cattermole wrote:On 28/09/2023 5:58 PM, Bruce Carneal wrote:Correct.The assert hack is useful but limited. It will not fail at compile time, will not prevent all code/symbol generation, will not enable compile time understanding that the function is restricted to use at compile time (if that's useful apart from the other ...).This proposal (should this PR changed to it) would restrict that function to CTFE only.
Sep 28 2023
On Thursday, 28 September 2023 at 03:35:10 UTC, Richard (Rikki) Andrew Cattermole wrote:I certainly would prefer ``assert(__ctfe);``. It would opt-in existing code (correctly). That alone is a pretty convincing argument. Not having to learn additional things, and having what appears like it should work work is always a good design choice.That would suffer all the same problems that `pragma(inline)` as a statement has. The information that a function should not be emitted (or should be inlined) is an outward facing attribute of that function, not an internal facing attribute. It will screw up .di generation, and make separate compilation more difficult. You also can't flip a switch to change if from not emitting to emitting it if you want to debug the function at runtime.
Sep 28 2023
On 28/09/2023 8:36 PM, Nicholas Wilson wrote:It will screw up .di generation, and make separate compilation more difficult.No not really, think about the constraints of CTFE. You can't elide a function body which is to be used from CTFE. Since you have to have the function body to CTFE it. So where the annotation exists, doesn't matter too much.
Sep 28 2023
On 9/28/23 4:02 AM, Richard (Rikki) Andrew Cattermole wrote:On 28/09/2023 8:36 PM, Nicholas Wilson wrote:I think what Nic means is if you have a function: ```d string genMixin(string param) { assert(__ctfe); return "int " ~ param ~ " = 5;"; } ``` Now, if that doesn't go into the binary, what happens with the di generated file? ```d string genMixin(string param); ``` oops, there's the function, but it can't be called for CTFE, *and* it doesn't exist in the object file. Personally, I don't see the problem here. Don't use .di files generation for d files that contain those functions. Or the compiler can detect it, and omit the function, but meh. -SteveIt will screw up .di generation, and make separate compilation more difficult.No not really, think about the constraints of CTFE. You can't elide a function body which is to be used from CTFE. Since you have to have the function body to CTFE it. So where the annotation exists, doesn't matter too much.
Sep 28 2023
On 29/09/2023 6:08 AM, Steven Schveighoffer wrote:On 9/28/23 4:02 AM, Richard (Rikki) Andrew Cattermole wrote:Yeah, I got it. Don't elide the function body of a CTFE only function, or one called from it and it will work fine, which is what I said :)On 28/09/2023 8:36 PM, Nicholas Wilson wrote:I think what Nic means is if you have a function: ```d string genMixin(string param) { assert(__ctfe); return "int " ~ param ~ " = 5;"; } ``` Now, if that doesn't go into the binary, what happens with the di generated file? ```d string genMixin(string param); ``` oops, there's the function, but it can't be called for CTFE, *and* it doesn't exist in the object file. Personally, I don't see the problem here. Don't use .di files generation for d files that contain those functions. Or the compiler can detect it, and omit the function, but meh. -SteveIt will screw up .di generation, and make separate compilation more difficult.No not really, think about the constraints of CTFE. You can't elide a function body which is to be used from CTFE. Since you have to have the function body to CTFE it. So where the annotation exists, doesn't matter too much.
Sep 28 2023
On Thursday, 28 September 2023 at 03:30:01 UTC, Nicholas Wilson wrote:I have need of the ability to suppress the code generation of functions for using mixin generation functions with dcompute. Below is a link to a PR to implement that functionality. https://github.com/dlang/dmd/pull/15636 What are peoples thoughts on this?Why couldn't the compiler already guess this? To me a simple static analysis would be enough and better, or is it too slow? time saved not generating what's not used could offset time spent on the analysis?
Sep 27 2023
On 28/09/2023 6:04 PM, ryuukk_ wrote:Why couldn't the compiler already guess this? To me a simple static analysis would be enough and better, or is it too slow? time saved not generating what's not used could offset time spent on the analysis?When you do multi-step builds (which are common), this would result in link failures. Since you don't have all the code, you can't do any analysis without failures being possible. It would make druntime and Phobos fail to link correctly with a giant list of missing symbols.
Sep 27 2023
On Thursday, 28 September 2023 at 06:04:51 UTC, Richard (Rikki) Andrew Cattermole wrote:On 28/09/2023 6:04 PM, ryuukk_ wrote:Correct. If the function is intended to actually be ctfe only, as marked, and a reference somehow gets emitted to be linked against, then you will see a link time error.Why couldn't the compiler already guess this? To me a simple static analysis would be enough and better, or is it too slow? time saved not generating what's not used could offset time spent on the analysis?When you do multi-step builds (which are common), this would result in link failures. Since you don't have all the code, you can't do any analysis without failures being possible. It would make druntime and Phobos fail to link correctly with a giant list of missing symbols.
Sep 28 2023
On Thursday, 28 September 2023 at 11:05:07 UTC, Bruce Carneal wrote:Correct. If the function is intended to actually be ctfe only, as marked, and a reference somehow gets emitted to be linked against, then you will see a link time error.Yes but that should be trivial to add a check during CallExp sema to emit a proper error message. There's a "are we in CTFE" flag in DMD `Scope`.
Nov 26 2023
On Thursday, 28 September 2023 at 03:30:01 UTC, Nicholas Wilson wrote:I have need of the ability to suppress the code generation of functions for using mixin generation functions with dcompute. Below is a link to a PR to implement that functionality. https://github.com/dlang/dmd/pull/15636 What are peoples thoughts on this?It's a good idea in general, but what alternatives exists? Could the compiler infer it some other way?
Sep 28 2023
On 9/27/23 11:30 PM, Nicholas Wilson wrote:I have need of the ability to suppress the code generation of functions for using mixin generation functions with dcompute. Below is a link to a PR to implement that functionality. https://github.com/dlang/dmd/pull/15636 What are peoples thoughts on this?Have you tried immediately-called lambdas? What I need is for this to work: ```d void foo() nogc { int[] buf; if (__ctfe) { buf = new int[10000]; } else { buf = (cast(int*)malloc(int.sizeof * 10000))[0 .. 10000]; } scope(exit) if(!__ctfe) free(buf.ptr); ... // use buf } ``` We need the compiler to back-off when it comes to enforcing runtime attributes in compile-time-only blocks. Without it, reasonable backup plans don't exist for what seems like obvious allowances. BetterC CTFE code becomes impossible, etc. I'd also like to see `assert(__ctfe)` just suppress code generation, as mentioned. -Steve
Sep 28 2023
On Thursday, 28 September 2023 at 17:04:00 UTC, Steven Schveighoffer wrote:On 9/27/23 11:30 PM, Nicholas Wilson wrote:As far as I can tell, this already works. ```d import core.stdc.stdlib; import core.stdc.stdio; int foo() nogc { int[] buf; if (__ctfe) { buf = new int[10000]; } else { buf = (cast(int*)malloc(int.sizeof * 10000))[0 .. 10000]; } scope(exit) if(!__ctfe) free(buf.ptr); foreach(ref b; buf){ b = 2; } int x = 0; foreach(b; buf){ x += b; } return x; } enum z = foo(); pragma(msg, z); void d_main(){ int y = foo(); printf("%d\n", y); printf("%d\n", z); } version(D_BetterC){ extern(C) int main(){ d_main(); return 0; } } else { void main(){ d_main(); } } ``` works with betterC, normal D, works at compile time, runtime. It works as this bug was resolved: https://issues.dlang.org/show_bug.cgi?id=21492I have need of the ability to suppress the code generation of functions for using mixin generation functions with dcompute. Below is a link to a PR to implement that functionality. https://github.com/dlang/dmd/pull/15636 What are peoples thoughts on this?Have you tried immediately-called lambdas? What I need is for this to work: ```d void foo() nogc { int[] buf; if (__ctfe) { buf = new int[10000]; } else { buf = (cast(int*)malloc(int.sizeof * 10000))[0 .. 10000]; } scope(exit) if(!__ctfe) free(buf.ptr); ... // use buf } ``` We need the compiler to back-off when it comes to enforcing runtime attributes in compile-time-only blocks. Without it, reasonable backup plans don't exist for what seems like obvious allowances. BetterC CTFE code becomes impossible, etc. I'd also like to see `assert(__ctfe)` just suppress code generation, as mentioned. -Steve
Sep 28 2023
On 9/28/23 3:56 PM, Dave P. wrote:It works as this bug was resolved: https://issues.dlang.org/show_bug.cgi?id=21492Oh nice! Since 2.103, I hadn't realized. -Steve
Sep 28 2023