@ctfeonly

Johannes Pfau nospam at example.com
Thu Dec 7 21:42:22 UTC 2017


Am Thu, 7 Dec 2017 05:55:54 +0200
schrieb ketmar <ketmar at ketmar.no-ip.org>:

> ketmar wrote:
> 
> > Nicholas Wilson wrote:
> >  
> >> Also not generating the code in the first place means less I/O for
> >> the compiler and less work for the linker.  
> > this is solvable without any additional flags, tho: compiler should
> > just skip codegen phase for any function that is not referenced by
> > another compiled function (except for library case).  
> 
> p.s.: actually, dmd already creates .a files suitable for
> smartlinking (otherwise any binary would include the whole
> libphobos2.a ;-). but for "dmd mycode.d" dmd doesn't do this ('cause
> it is quite compilcated for non-library case). the whole issue prolly
> can be solved by "generate smart object files for linking" flag
> (which will create .a files for everything, so linker can do it's
> smart work).

AFAIK there's a design flaw in D which prevents a compiler from
doing any such operations without additional user input:

Currently you can write code like this:
-------------------------------------------------------------------
module mod;

private int thisIsNeverUsed()
{
    return 42;
}

private int thisIsUsed(int a)
{
    return 42 + a;
}

int someTemplate(T)(T t)
{
    return t.thisIsUsed();
}
-------------------------------------------------------------------

Whether thisIsUsed and thisIsNeverUsed actually have to appear in the
object file depends on how someTemplate is instantiated. Generally, when
compiling module mod you can never know whether thisIsUsed or
thisIsNeverUsed are actually required. You can not evaluate the
someTemplate template without specifying a concrete type for T. 

This means neither the compiler nor the linker can remove seemingly
unused, private functions. For GDC this means we simply mark all
functions as TREE_PUBLIC in the GCC backend.

Note that this is also an issue for exporting templates from DLLs on
windows. I think the DLL DIP which requires to mark private functions
as 'export' if they are used outside outside of the module (even via
templates) will fix this problem and allow for some nice optimizations.
Until then, smart linking isn't really possible.

BTW: The private/export combination probably still wouldn't solve all
problems: Maybe you want to mark the whole module as @nogc. @nogc
checking is done in semantic phase, so it will still error about GC
usage in functions which later turn out to be only used in CTFE.
Detecting this in the linker or compiler backend is too late. So we'd
have to detect unexported, unused private functions in semantic. I'm
not sure if this is feasible or whether a simple @ctfeonly UDA isn't
much simpler to implement.

Additionally @ctfeonly documents intended usage and allows for nice
error messages when using a function at runtime. Relying on the linker
to remove private, unexported functions can break easily.

-- Johannes



More information about the Digitalmars-d mailing list