dmd
dmd copied to clipboard
Don't generate code for compile-time only functions
Thanks for your pull request, @UplinkCoder!
Bugzilla references
Your PR doesn't reference any Bugzilla issue.
If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.
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#11103"
is it possible to test this?
@thewilsonator not on it's own. There is a work in progress PR however that want's to use this. https://github.com/dlang/dmd/pull/11101
Maybe add a dshelltests that compiles a compile-time only function and dump the symbols of the generated binary using nm?
There's no way to mark functions compile-time only in the current language. But it's going to come.
Interestingly, two of the three mentions of this flag in dmd right now has this comment:
funcdecl.flags |= FUNCFLAG.compileTimeOnly; // don't emit code for this function
and
compileTimeOnly = 0x100, /// is a compile time only function; no code will be generated for it
Looks like people assumed this was already the behavior!
It appears its only actual use right now is when generating a closure, it won't emit the _d_allocmemory reference in response to someone filing a -betterC bug.
I'm not sure that this patch is necessary (unless i got the dmd code/docs wrong).
Consider this example:
int foo(T)()
{
return cast(int) T.sizeof;
}
enum e = __traits(compiles, foo!int());
foo!int is marked as compileTimeOnly because it's inside of __traits(compiles, ...) here:
https://github.com/dlang/dmd/blob/804b9b3f9486294a4a81354fdb28840502047ffa/src/dmd/dsymbolsem.d#L3238-L3239
$(DMD) -c ./sample.d && nm sample.o
0000000000000000 t
0000000000000000 R _D6simple12__ModuleInfoZ
U __start_minfo
U __stop_minfo
U _d_dso_registry
foo!int isn't emitted into the object file (tested with v2.091.0)
EDIT: Extending the example with another method doesn't make a difference either:
int foo(T)()
{
return bar(cast(int) T.sizeof);
}
int bar(T)(T i)
{
return 2 * i;
}
enum e = __traits(compiles, foo!int());
$(DMD) -c ./simple.d && nm simple.o
0000000000000000 t
0000000000000000 R _D6simple12__ModuleInfoZ
U __start_minfo
U __stop_minfo
U _d_dso_registry
@MoonlightSentinel It is needed for type functions.
and assert(__ctfe) (when I revive that).
That's because you're using the template in a specutlative context. The templates instance in not generated for a diffrent reason.
@MoonlightSentinel It is needed for type functions. and
assert(__ctfe)(when I revive that).
Okay. I'm a little concerned that this adds dead code which might (or might not) be used later instead of including it in the PRs relying on this change.
EDIT:
A reasonable way forward were to identify the existing mechanism (which doesn't seem to use FUNCFLAG.compileTimeOnly) and replace it with this approach s.t. we don't have different implementations of the same concept. Then this PR would provide value on its own.
@UplinkCoder I think the examples posted by @MoonlightSentinel would suffice for testing this. It would be good to move forward with this. Also rebasing will probably get rid of the buildkite failure.
Is this still necessary and being worked on it?
It would be nice to have. The discussion is in a stalemate though I think.