dmd icon indicating copy to clipboard operation
dmd copied to clipboard

Fix Issue 18119 - Mark if(__ctfe) blocks as SCOPEctfe

Open ibuclaw opened this issue 7 years ago • 27 comments

Revival of #3572

ibuclaw avatar Dec 24 '17 16:12 ibuclaw

Thanks for your pull request, @ibuclaw!

Bugzilla references

Auto-close Bugzilla Severity Description
18119 enhancement Allow code that may allocated inside __ctfe condition branches in @nogc functions

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#7509"

dlang-bot avatar Dec 24 '17 16:12 dlang-bot

this is nasty special casing, then again this is actually useful. please propose a spec change @ibuclaw.

stefan-koch-sociomantic avatar Dec 24 '17 16:12 stefan-koch-sociomantic

@stefan-koch-sociomantic - I've put in a changelog entry that gives a real world example of who might benefit.

ibuclaw avatar Dec 24 '17 17:12 ibuclaw

please also put that an expression involving __ctfe even it it is 0 + __ctfe will not mark the scope.

stefan-koch-sociomantic avatar Dec 24 '17 17:12 stefan-koch-sociomantic

please propose a spec change

Imho this is not a spec change, but an improvement of the compiler like e.g. optimization.

wilzbach avatar Dec 24 '17 23:12 wilzbach

This might make it easier to get allocators to work at CTFE 😃.

jacob-carlborg avatar Dec 25 '17 08:12 jacob-carlborg

I don't have any answers at this time, but there seems to be a fundamental design problem in the language if we have to resort to something like this. I'd like to see some brainstorming for a more elegant solution.

JinShil avatar Dec 25 '17 08:12 JinShil

@JinShil - That's part of why rebasing these old PRs is supposed to achieve. Debate whether they are sound ideas that may need some TLC (or a better implementation), or reject + close related issues.

ibuclaw avatar Dec 27 '17 22:12 ibuclaw

so .... thinking about this again, in theory we should be able to constant-fold everything around __ctfe in cases where marking the scope can be done and/or simplifying the expression to only depend on __ctfe.

UplinkCoder avatar Jan 08 '18 08:01 UplinkCoder

@UplinkCoder - what do you mean?

ibuclaw avatar Jan 09 '18 22:01 ibuclaw

@jacob-carlborg I'll rather support __ctfeAlloc and __ctfeFree.

stefan-koch-sociomantic avatar Jan 10 '18 00:01 stefan-koch-sociomantic

I'll rather support __ctfeAlloc and __ctfeFree.

@stefan-koch-sociomantic Doesn't matter to me, as long as then end goal works.

jacob-carlborg avatar Jan 10 '18 12:01 jacob-carlborg

Why add a new keyword though?

ibuclaw avatar Jan 10 '18 20:01 ibuclaw

it would not be a keyword. rather a very magic function :)

stefan-koch-sociomantic avatar Jan 10 '18 23:01 stefan-koch-sociomantic

and we already have precedent for this. namely builtins.

stefan-koch-sociomantic avatar Jan 10 '18 23:01 stefan-koch-sociomantic

How would a hypothetical __ctfeAlloc/Free even be related to allowing GC new in __ctfe blocks?

dnadlinger avatar Jan 10 '18 23:01 dnadlinger

it removes the need for gc in ctfe. currently a @nogc function cannot be ctfe since ctfe has no way of allocating memory without gc. It follows that providing a way to allocate without gc at ctfe will enable ctfe-branches/ctfe-functions to be @nogc

stefan-koch-sociomantic avatar Jan 10 '18 23:01 stefan-koch-sociomantic

Ctfe should not be a separate language to runtime. I don't think any of these __ctfeXxx function ideas are any good.

ibuclaw avatar Jan 12 '18 08:01 ibuclaw

I'd like to see this feature added. Can this be revived? There didn't seem to be any opposition. This would be a first step to opening a lot more things to CTFE, e.g. any functions that use RefCounted.

schveiguy avatar Jun 16 '20 00:06 schveiguy

but there seems to be a fundamental design problem in the language if we have to resort to something like this.

I don't think so. Anything run at compile-time can't use the GC, as it doesn't exist. This is, IMO, more of a correction than a kludge. Really, the only kludgy part is that it needs a specialized form (but then again, the specialized form is nearly always what anyone uses).

schveiguy avatar Jun 16 '20 00:06 schveiguy

@ibuclaw since you don't like ctfe to be another langauge, we could "fake" a malloc call at ctfe.

UplinkCoder avatar Jun 16 '20 00:06 UplinkCoder

it would not be a keyword. rather a very magic function :)

You don't need any magic to implement CTFE alloc: https://github.com/dlang/druntime/blob/246d15ac85b2bc7ae7d7a7f61df2ceb80377ed8c/src/core/internal/convert.d#L13-L34


/+
A @nogc function can allocate memory during CTFE.
+/
@nogc nothrow pure @trusted
private ubyte[] ctfe_alloc()(size_t n)
{
    if (!__ctfe)
    {
        assert(0, "CTFE only");
    }
    else
    {
        static ubyte[] alloc(size_t x) nothrow pure
        {
            if (__ctfe) // Needed to prevent _d_newarray from appearing in compiled prorgam.
                return new ubyte[x];
            else
                assert(0);
        }
        return (cast(ubyte[] function(size_t) @nogc nothrow pure) &alloc)(n);
    }
}

n8sh avatar Jun 16 '20 01:06 n8sh

@n8sh there's a lot happening in there (it's a template, you have a seemingly unnecessary check for CTFE at the beginning, and then again later). I don't know if I'd consider that not magic.

But it does provide a path forward as a workaround. I'd still rather have the requirements for @nogc CTFE simply be that you can allocate inside an if(__ctfe) block.

schveiguy avatar Jun 16 '20 15:06 schveiguy

Wait, I didn't notice the cast. That's interesting.

schveiguy avatar Jun 16 '20 15:06 schveiguy

I tested and it works for my purpose (using GC to allocate in CTFE, C malloc otherwise)

schveiguy avatar Jun 16 '20 15:06 schveiguy

(it's a template, you have a seemingly unnecessary check for CTFE at the beginning, and then again later).

The second __ctfe check is so it can be used with -betterC.

n8sh avatar Jun 16 '20 16:06 n8sh

No, I misunderstood the example. I thought there was some specific magic going on, but really, it is just casting in @nogc and ensuring the compiler doesn't actually emit any GC calls using if(__ctfe). The other parts of the example aren't important (that it's a template, that it asserts __ctfe at the beginning). I tested it separately, and it works exactly as I would want.

schveiguy avatar Jun 16 '20 16:06 schveiguy