Skip to content

[DO NOT MERGE] Implement fast DFA's escape analysis#23314

Draft
rikkimax wants to merge 1 commit into
dlang:masterfrom
rikkimax:fastdfa-escape
Draft

[DO NOT MERGE] Implement fast DFA's escape analysis#23314
rikkimax wants to merge 1 commit into
dlang:masterfrom
rikkimax:fastdfa-escape

Conversation

@rikkimax

Copy link
Copy Markdown
Contributor

Escape analysis for the fast dfa engine based upon my previous DIP design work.

Two relationship strengths are implemented as well as an unknown state.
In outer cell of parameter @escape(var&) + via indirection @escape(var=)

No new attributes for users to use are implemented as that requires DIP.

There is a UDA recognized for specifically named test files, this does not affect the rest of the frontend. It is required for verifying inference.

Currently the engine is forced on for all code, except some specific test suite files, both of this will be disabled prior to merging. Have to verify what the CI as a whole does and that requires this behaviour. Same as previous PRs.

@rikkimax

rikkimax commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

Ooo that is a fun little error, because in theory it should be true. But it requires assumptions in the AST.

src/dmd/glue/package.d(914): Error: Assert can be proven to be false
        assert(sthis);
               ^

@rikkimax

rikkimax commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

I don't think this should be erroring:

src\core\internal\dassert.d(176): Error: Parameter is required to be scope but escapes
private string miniFormat(V)(const scope ref V v)
                                               ^
src\core\internal\dassert.d(521): Error: template instance `core.internal.dassert.miniFormat!(MonoTimeImpl!(ClockType.coarse))` error instantiating
    alias miniT = miniFormat!T;
                  ^

Ooo another fun one:

  compilable/test14781.d(13): Error: cannot rebind scope variables
              x = 1;      // accessing pure function context is just ok
                ^

I think that is because it's marking x as on stack.

@rikkimax rikkimax force-pushed the fastdfa-escape branch 3 times, most recently from 06e60d1 to 3fdf65a Compare June 26, 2026 13:52
@rikkimax

rikkimax commented Jun 28, 2026

Copy link
Copy Markdown
Contributor Author

Looks like the following code is not seeing the cell like it should.

                *(cast(void[]*)&ret) = _d_newarrayUTrace(__FILE__, __LINE__,
                __FUNCTION__, typeid(E[]), size);

It thinks that its a null deref on ret, which isn't correct.

@rikkimax

rikkimax commented Jun 28, 2026

Copy link
Copy Markdown
Contributor Author

For gcc iasm:

    scope tint32 = new TypeBasic(ASTCodegen.Tint32);
    tint32.merge();
    ASTCodegen.Type.tint32 = tint32;

Doesn't look right:

src/dmd/iasm/gcc.d(580): Error: Escape of unknown lifetime via global
    ASTCodegen.Type.tint32 = tint32;
                           ^
src/dmd/iasm/gcc.d(578):        Pointer stored in variable `tint32` has potentially escaped
    scope tint32 = new TypeBasic(ASTCodegen.Tint32);
          ^

Will need fixing.

That should be allowed due to it being @system but for some reason its not gated.

@rikkimax

Copy link
Copy Markdown
Contributor Author

Aw after fixing bugs I've lost Ocean's null deref report that I was quite proud of.

Oh well, at least it was 0 + 0.

I don't think I can bring it back there is a rather large comment at this point showing why it can't be.

@rikkimax

rikkimax commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

It looks like I may need to rebase.

compilable\dtoh_ignored.d is erroring out:

..\test\compilable\dtoh_ignored.d(103): Error: internal compiler error: type `ifloat` cannot be mapped to C++

    ifloat onReturn()
           ^

But only after I fix a segfault in dmd.mangle.cppwin:

    extern (D) this(VisualCPPMangler rvl) scope @safe
    {
        this.saved_idents[] = rvl.saved_idents[];
        this.saved_types[] = rvl.saved_types[];
        this.loc = rvl.loc;
        this.eSink = rvl.eSink;
    }

Missing eSink assignment.

I haven't figured out what commit I'm missing because clearly something is different between the two branches allowing this new untested pathway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant