www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Optimizing / removing inlined or ctfe-only private functions

Here's a recent stackoverflow thread where somebody asked why GDC is
not able to remove completely inlined or unused, module-private
functions: http://stackoverflow.com/q/42494205/471401
In C it's possible to mark a function as static and the compiler won't
emit an externally callable function into the object file if not
necessary (A function could still be required if the address of the
function is taken somewhere in the module).

Turns out we also have a bug report for this:
https://issues.dlang.org/show_bug.cgi?id=6528

One thing I was wondering about though and which is not yet mentioned in
the bug report:
--------------------------------------------------------
// a.d
private void fooPrivate() {}

/*template*/ void fooPublic(string func = "fooPrivate")()
{
    mixin(func ~ "();");
}
--------------------------------------------------------

When compiling a.d we haven't analyzed the fooPublic template and the
example shows why we can't know at all which private functions could
be called from a template. As the template is instantiated into another
object file (e.g. module b.d) we can't know in a.d that fooPrivate is
actually required.

So does that mean removing private functions in D is completely
impossible as we can't know if a function is unused? People sometimes
refer to the linker as a solution but if a.d is in a shared library
this won't work either.

This seems to be a problem especially for CTFE only functions, as it
means for example that any such function in phobos (e.g. used for
string creation for mixins) bloats the phobos library.

It's interesting to think about template instances here as
well: If a template instance is completely inlined in a module, do we
have to keep the function in the object file? AFAICS no, as the
template should be re-instantiated if used in a different module, but I
don't know the template <=> object file rules in detail. Right now this
means we could get lots of template instances in the phobos shared
library for template instances only used in CTFE:

--------------------------------------------------------
import std.conv;
private string fooPrivate(int a)
{
    return `int b = ` ~ to!string(a) ~";";
}
mixin(fooPrivate(42));
--------------------------------------------------------
https://godbolt.org/g/VW8yLr

Any idea to measure the impact of this on the binary shared libphobos
file? We probably can get some estimate by counting all template
instances that are only referenced by private functions which are
themselves never referenced...

Any idea how to solve this problem? I think the same problem was
mentioned in the DLL-support context as this implies we also have to
export private functions from modules for templates to work. Was there
some kind of solution / discussion? I think I remember something about
marking `private` functions as `export private` instead?

-- Johannes
Mar 04 2017