[SAOC 2026] CTFE Performance Weekly Update #3

Abul Hossain Khan abulkhan19175 at gmail.com
Mon Oct 12 20:02:31 UTC 2026


Hi everyone,

So last time I did the semantic upfront experiment. It worked but 
it broke some valid code and couldn't handle virtual calls. So 
this week I tried the other way round, and also added a CTFE 
workload to the perf bot.

#### Semantic through a callback

The interpreter stays lazy, but it can only get semantic by 
asking through a function it is given. One function pointer:

```d
alias CtfeSemantic = bool function(Dsymbol);
Expression ctfeInterpret(Expression e, CtfeSemantic semantic = 
&frontendSemantic);
```

The default is the frontend's own code moved out of the 
interpreter. The interpreter asks at the 4 places where it used 
to call semantic itself, before running a function body and 
before reading a constant that has no value yet. None of the 78 
call sites change. Then a global check, any semantic that starts 
during `ctfeInterpret` without going through the ask is counted, 
and with `DMD_CTFE_CALLBACK=strict` it's an error.

| | test suite | Phobos unittests |
|---|--:|--:|
| asks for a function body / that had to analyse one | 133,597 / 
3,274 | 5,172,111 / 1,885 |
| asks for a variable / that did real semantic | 75,245 / 13 | 
165,190 / 30 |
| semantic outside the callback | 0 | 0 |
| failing with the check as an error | 0 of 3,926 | 0 of 166 |

So nothing runs semantic inside CTFE except through the ask. The 
function one is the only one that really matters, the variable 
one almost always finds the initializer already done. The valid 
code that broke with the pre-pass compiles, and virtual calls 
just work, the interpreter asks for the override once it has 
picked it. One thing the engine has to allow is being entered 
again while it waits for an ask, that happens 22,678 times in the 
test suite.

Everything so far, the boundary, the probing, both experiments, 
is here - 
https://gist.github.com/abulgit/43f640a032c95557de959f7120d4fd69

#### CTFE workload in the perf bot

Thanks Dmitry for the suggestion. I took the default ctRegex 
subset of `std/regex/internal/tests.d` compiled with `-unittest`. 
It gets instructions, peak RSS, page faults and a time trace like 
the other workloads.
PR Link - https://github.com/dlang/dmd/pull/24011 [Merged]

#### What's next

- Dennis filed a bunch of CTFE bugs his wasm experiment 
uncovered. I'll be fixing those to get a better understanding of 
the interpreter before writing the interface and all.
- A small code example for the rarer expression kinds going in 
and out, in a separate gist.
- Have a deeper look at Steven's old CTFE engine, as he 
suggested, to see what can be reused.

Thanks to Dennis for mentoring this. As always, feel free to 
leave any feedback or suggestions!



More information about the Digitalmars-d mailing list