Re: @ctfeonly

2017-12-08 Thread Joakim via Digitalmars-d
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson 
wrote:
I'd like to add an attribute to indicate that the annotated 
function is only available at compile time so that in cases 
where the operation is invalid at runtime (strings and 
concatenation on a GPU for instance) but the result is only 
used at compile time (for a mixin) the compiler is free to not 
codegen that function.


I can add this to LDC pretty easily, but does anyone else have 
a use for this (e.g. shrinking binary sizes for mixin heavy 
codebases) and would benefit having this as a standard thing?


This doesn't fulfill everything you're looking for, ie no 
compile-time error if tried to use at runtime, but isn't this 
existing idiom good enough?


https://github.com/dlang/phobos/blob/master/std/functional.d#L307


Re: @ctfeonly

2017-12-08 Thread David Nadlinger via Digitalmars-d

On Friday, 8 December 2017 at 18:59:00 UTC, Manu wrote:

Nicholas wants a *compile* error, not a link error.


I don't think this is necessarily implied from the original post. 
Certainly, a linker error would just work fine for the original 
use case (avoiding unsupported codegen on compute targets).


 -David


Re: @ctfeonly

2017-12-08 Thread Manu via Digitalmars-d
On 7 December 2017 at 19:43, Walter Bright via Digitalmars-d <
digitalmars-d@puremagic.com> wrote:

> On 12/7/2017 5:20 PM, Manu wrote:
>
>> Right, but that's what I'm saying; using your solution of putting a
>> function in a module that's not compiled to inhibit code generation won't
>> inhibit people from *attempting* to making runtime calls (and getting link
>> errors)... whereas a compile error trying to runtime-call a function that
>> shouldn't be runtime-called might be more desirable.
>>
>
> That's exactly what happens if you put a declaration in a .h file, call
> the function, and don't link in the implementation. I don't see the
> difference.
>

Nicholas wants a *compile* error, not a link error.


Re: @ctfeonly

2017-12-08 Thread Manu via Digitalmars-d
On 7 December 2017 at 19:49, Walter Bright via Digitalmars-d <
digitalmars-d@puremagic.com> wrote:

> On 12/7/2017 5:30 PM, Manu wrote:
>
>> I tried this, and was surprised it didn't work:
>>
>> int ctfeOnly(int x)
>> {
>> static assert(__ctfe);
>> return x + 1;
>> }
>>
>
> The error is:
>
> test2.d(3): Error: variable __ctfe cannot be read at compile time
> test2.d(3):while evaluating: static assert(__ctfe)
>
> because static asserts are evaluated when the function is semantically
> analyzed, not when it is executed.
>

Sorry, in my mind, it was meant to be a template function...


Re: @ctfeonly

2017-12-08 Thread Manu via Digitalmars-d
On 7 December 2017 at 17:45, Nicholas Wilson via Digitalmars-d <
digitalmars-d@puremagic.com> wrote:

> On Friday, 8 December 2017 at 01:30:13 UTC, Manu wrote:
>
>> I tried this, and was surprised it didn't work:
>>
>> int ctfeOnly(int x)
>> {
>> static assert(__ctfe);
>> return x + 1;
>> }
>>
>> This would probably solve the problem in a satisfying way without an
>> attribute?
>>
>
> I think that's because __ctfe, despite being magic, is actually a regular
> variable.
>
> While this looks not too inelegant for a user perspective, I dont know how
> to handle this from a compiler perspective: filtering by attribute is as
> easy as "does this function have a UDA ctfeonly? If so, don't code generate
> it. Generating errors at codegen time is also trivial: when generating a
> call check to see if the callee is @ctfeonly, if it is give an error message
>
> I don't know how to do that for a `static assert(__ctfe);`. That would
> require changes and semantic analysis in the front end which I am much less
> familiar with.
>

Oh, sorry, I forgot key detail! (parens)

int ctfeOnly()(int x) ...  (in my mind, it was a template function, which
means it would instantiate for the ctfe call separately to regular calls(?))


Re: @ctfeonly

2017-12-08 Thread H. S. Teoh via Digitalmars-d
On Fri, Dec 08, 2017 at 05:53:37AM +0200, ketmar via Digitalmars-d wrote:
[...]
> still, why `__ctfe` was designed as variable, and not as `enum ctfe = 
> ;`?

https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time


T

-- 
I think the conspiracy theorists are out to get us...


Re: @ctfeonly

2017-12-08 Thread H. S. Teoh via Digitalmars-d
On Fri, Dec 08, 2017 at 11:03:34AM +, Paolo Invernizzi via Digitalmars-d 
wrote:
> On Friday, 8 December 2017 at 02:14:09 UTC, H. S. Teoh wrote:
> > On Thu, Dec 07, 2017 at 07:20:57PM -0700, Jonathan M Davis via
> > Digitalmars-d wrote: [...]
> > > In spite of the fact that CTFE is done at compile time, __ctfe is
> > > a runtime thing - it's just that it's runtime from the perspective
> > > of CTFE. So, stuff like static if or static assert doesn't work.
> > > You have to use if or a ternary operator or some other runtime
> > > conditional, though it's a common misunderstanding that __ctfe is
> > > used with static if, and people screw it up all the time. I don't
> > > know why it's a runtime thing rather than a compile time thing
> > > though. There's probably a good reason for it, but at first
> > > glance, it seems like a rather weird choice.
> > [...]
> > 
> > Sigh:
> > 
> > https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time
> > 
> > 
> > T
> 
> Woaaa... amazing job, Teoh!
> 
> It seems that no link in the wiki points to that, or I'm wrong?
> That valuable stuff should be more visible...
[...]

The reason nothing (official) points to it, is because it's still a
draft that hasn't been polished, and some parts may not be 100%
accurate.  Unfortunately, I haven't had the time to work on finishing it
up.

But since it's a wiki, if you're up to it, contributions are welcome.
:-)


T

-- 
Life is unfair. Ask too much from it, and it may decide you don't deserve what 
you have now either.


Re: @ctfeonly

2017-12-08 Thread Stefan Koch via Digitalmars-d

On Friday, 8 December 2017 at 11:48:26 UTC, Nicholas Wilson wrote:

On Friday, 8 December 2017 at 10:46:20 UTC, John Colvin wrote:
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson 
wrote:

[...]


How would such a thing interact with __traits(compiles, ...) 
and is-expressions?


VERY good question, I'm not sure.

From a purely practical perspective I'd say it should pass 
__traits(compiles, ...)  and is-expressions purely because the 
kind of things that @ctfeonly would be used to cull from the 
produced binaries are used as is-expressions (e.g. the template 
lambda that determines isInputRange), although I expect it use 
to be rare. Ultimately I think this this feature would fall in 
to the category of "use responsibly" and it would be the 
responsibility of the user. They could always reflect on the 
presence of the attribute if need be.


From a point of consistency, probably however semantic 
constraints on things like LDC's magic attributes are done. I'm 
not sure how that is handled, but I suspect that 
__traits(compiles,...) does not take it into account. Johan?


I will think more on it.

Thanks.


You might want to wait until Dconf 2018 before you start 
implementing something.
As it happens I am working on a way which will make ctfe-only 
functions possible (though that's s side-effect rather then the 
goal)


Re: @ctfeonly

2017-12-08 Thread Nicholas Wilson via Digitalmars-d

On Friday, 8 December 2017 at 10:46:20 UTC, John Colvin wrote:
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson 
wrote:
I'd like to add an attribute to indicate that the annotated 
function is only available at compile time so that in cases 
where the operation is invalid at runtime (strings and 
concatenation on a GPU for instance) but the result is only 
used at compile time (for a mixin) the compiler is free to not 
codegen that function.


I can add this to LDC pretty easily, but does anyone else have 
a use for this (e.g. shrinking binary sizes for mixin heavy 
codebases) and would benefit having this as a standard thing?


How would such a thing interact with __traits(compiles, ...) 
and is-expressions?


VERY good question, I'm not sure.

From a purely practical perspective I'd say it should pass 
__traits(compiles, ...)  and is-expressions purely because the 
kind of things that @ctfeonly would be used to cull from the 
produced binaries are used as is-expressions (e.g. the template 
lambda that determines isInputRange), although I expect it use to 
be rare. Ultimately I think this this feature would fall in to 
the category of "use responsibly" and it would be the 
responsibility of the user. They could always reflect on the 
presence of the attribute if need be.


From a point of consistency, probably however semantic 
constraints on things like LDC's magic attributes are done. I'm 
not sure how that is handled, but I suspect that 
__traits(compiles,...) does not take it into account. Johan?


I will think more on it.

Thanks.


Re: @ctfeonly

2017-12-08 Thread Paolo Invernizzi via Digitalmars-d

On Friday, 8 December 2017 at 02:14:09 UTC, H. S. Teoh wrote:
On Thu, Dec 07, 2017 at 07:20:57PM -0700, Jonathan M Davis via 
Digitalmars-d wrote: [...]
In spite of the fact that CTFE is done at compile time, __ctfe 
is a runtime thing - it's just that it's runtime from the 
perspective of CTFE. So, stuff like static if or static assert 
doesn't work. You have to use if or a ternary operator or some 
other runtime conditional, though it's a common 
misunderstanding that __ctfe is used with static if, and 
people screw it up all the time. I don't know why it's a 
runtime thing rather than a compile time thing though. There's 
probably a good reason for it, but at first glance, it seems 
like a rather weird choice.

[...]

Sigh:

https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time


T


Woaaa... amazing job, Teoh!

It seems that no link in the wiki points to that, or I'm wrong?
That valuable stuff should be more visible...

/Paolo




Re: @ctfeonly

2017-12-08 Thread John Colvin via Digitalmars-d
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson 
wrote:
I'd like to add an attribute to indicate that the annotated 
function is only available at compile time so that in cases 
where the operation is invalid at runtime (strings and 
concatenation on a GPU for instance) but the result is only 
used at compile time (for a mixin) the compiler is free to not 
codegen that function.


I can add this to LDC pretty easily, but does anyone else have 
a use for this (e.g. shrinking binary sizes for mixin heavy 
codebases) and would benefit having this as a standard thing?


How would such a thing interact with __traits(compiles, ...) and 
is-expressions?


Re: @ctfeonly

2017-12-08 Thread bauss via Digitalmars-d

On Thursday, 7 December 2017 at 06:33:42 UTC, E.S. Quinn wrote:

On Thursday, 7 December 2017 at 05:53:06 UTC, bauss wrote:
On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis 
wrote:

As I understand it, with the way CTFE works,
it pretty much can't know whether a function can be called at 
compile time until it tries


- Jonathan M Davis


I think that's the point of the attribute. You tell the 
compiler that this function can only be called at compile-time 
and any attempt to call it during run-time would be an error.


If all you need is a runtime error, you can already put 
assert(__ctfe); in your function.


It's to avoid having a run-time error, so something that would 
produce a run-time call gives a compile-time error.


Re: @ctfeonly

2017-12-07 Thread Mike Franklin via Digitalmars-d

On Friday, 8 December 2017 at 06:39:10 UTC, ketmar wrote:

no compilation errors, runtime assert. that is, it is 
technically still executed in runtime.


damnit!



Re: @ctfeonly

2017-12-07 Thread ketmar via Digitalmars-d

Mike Franklin wrote:


 // I couldn't figure out how to force `onlyCompileTime` to
 // execute at runtime.  That's probably a good thing.


string s = onlyCompileTime();

no compilation errors, runtime assert. that is, it is technically still 
executed in runtime.


Re: @ctfeonly

2017-12-07 Thread Mike Franklin via Digitalmars-d

On Friday, 8 December 2017 at 01:30:13 UTC, Manu wrote:


I tried this, and was surprised it didn't work:

int ctfeOnly(int x)
{
static assert(__ctfe);
return x + 1;
}

This would probably solve the problem in a satisfying way 
without an attribute?


Interestingly, if you put `__ctfe` in a function it does seem to 
work (unless I'm missing something).  Check this out.


import std.stdio;

bool isRunTime()
{
return !__ctfe;
}

bool isCompileTime()
{
static if (!isRunTime())
return __ctfe;
else
return false;
}

string onlyCompileTime()
{
static assert(isCompileTime(),
"This function can only be executed at compile time");
assert(isCompileTime(),
"This function can only be execute at compile time");
return "onlyCompileTime";
}

string onlyRunTime()
{
// This assert will actually throw an error at compile-time,
// if an attempt is made to execute it at compile time.
assert(isRunTime(), "This function can only be executed at 
run time");

return "onlyRunTime";
}

void main(string[] args)
{
static assert(isCompileTime());
static assert (!isRunTime());

assert(!isCompileTime());
assert(isRunTime());

static assert(onlyCompileTime() == "onlyCompileTime");

// Compile-time Error: Good!
//static assert(onlyRunTime() == "onlyRunTime");

assert(onlyRunTime() == "onlyRunTime");

// Compile-time Error: Good!
// pragma(msg, onlyRunTime());

// I couldn't figure out how to force `onlyCompileTime` to
// execute at runtime.  That's probably a good thing.
}

https://run.dlang.io/is/64fRRX

I guess this is due to the fact that wrapping `__ctfe` in a 
function causes it to run at compile-time instead of 
at...well...compile-time (i.e. 
https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time)


Mike


Re: @ctfeonly

2017-12-07 Thread Nicholas Wilson via Digitalmars-d

On Friday, 8 December 2017 at 03:41:05 UTC, Walter Bright wrote:


bar.d:
module bar;
string generateString(T)()
{
return T.stringof ~ " foo;";
}

enum s = generateString!int();

a.d:
@compute(CompileFor.deviceOnly) module a;

int baz()
{
import bar;
bar.s;
return foo;
}


That requires that I know what instantiations I will have a head 
of time or I have to maintain a "header file" of named 
instantiations. Both of which I consider subpar solutions. Also 
while it may not bloat the GPU binary it will still bloat the 
host binary.


Re: @ctfeonly

2017-12-07 Thread ketmar via Digitalmars-d

ketmar wrote:

still, why `__ctfe` was designed as variable, and not as `enum ctfe = 
;`?


ah, sorry, i remembered. that was stupid question.

the rationale is: `static if` and `static assert` are processed *before* 
CTFE phase. i.e. CTFE interpreter never sees them, and cannot do the 
choice. and on semantic analysis phase it is not known yet if the code is 
for CTFE or not. that is, to allow `static assert(__ctfe)` to work, the 
whole semantic phase must be redesigned.


Re: @ctfeonly

2017-12-07 Thread ketmar via Digitalmars-d

ketmar wrote:

still, why `__ctfe` was designed as variable, and not as `enum ctfe = 
;`?


p.s.: i see only one reason for this rationale: to explicitly prevent 
people using `static if` to separate CTFE and non-CTFE code (that is, to 
lessen the chance than function heaves differently in runtime and in 
compile-time). but that doesn't work, as `if (__ctfe)` allows two 
completely different code pathes anyway.


Re: @ctfeonly

2017-12-07 Thread ketmar via Digitalmars-d

Walter Bright wrote:


On 12/7/2017 5:30 PM, Manu wrote:

I tried this, and was surprised it didn't work:
int ctfeOnly(int x)
{
static assert(__ctfe);
return x + 1;
}


The error is:

test2.d(3): Error: variable __ctfe cannot be read at compile time
test2.d(3):while evaluating: static assert(__ctfe)

because static asserts are evaluated when the function is semantically 
analyzed, not when it is executed.


still, why `__ctfe` was designed as variable, and not as `enum ctfe = ;`?


Re: @ctfeonly

2017-12-07 Thread Walter Bright via Digitalmars-d

On 12/7/2017 5:30 PM, Manu wrote:

I tried this, and was surprised it didn't work:

int ctfeOnly(int x)
{
static assert(__ctfe);
return x + 1;
}


The error is:

test2.d(3): Error: variable __ctfe cannot be read at compile time
test2.d(3):while evaluating: static assert(__ctfe)

because static asserts are evaluated when the function is semantically analyzed, 
not when it is executed.


Re: @ctfeonly

2017-12-07 Thread Walter Bright via Digitalmars-d

On 12/7/2017 5:20 PM, Manu wrote:
Right, but that's what I'm saying; using your solution of putting a function in 
a module that's not compiled to inhibit code generation won't inhibit people 
from *attempting* to making runtime calls (and getting link errors)... whereas a 
compile error trying to runtime-call a function that shouldn't be runtime-called 
might be more desirable.


That's exactly what happens if you put a declaration in a .h file, call the 
function, and don't link in the implementation. I don't see the difference.


Re: @ctfeonly

2017-12-07 Thread Walter Bright via Digitalmars-d

On 12/7/2017 3:41 PM, Nicholas Wilson wrote:

On Thursday, 7 December 2017 at 21:32:24 UTC, Walter Bright wrote:

On 12/7/2017 2:07 AM, Nicholas Wilson wrote:

Doesn't work for templates.


I don't know how your code is organized, but if the template is instantiated 
in another file, it won't have code generated for it either.


As a trivial example:

bar.d:
module bar;
string generatesMixin(T)()
{
     return T.stringof ~ " foo;";
}


a.d:
@compute(CompileFor.deviceOnly) module a;

int baz()
{
     mixin(generatesMixin!int());
     return foo;
}

a's symbol table contains `baz` and `generatesMixin!int`. generateMixin deals 
with strings which are not allowed (global variables are unsupported). This 
would fail compilation. If `generatesMixin` were to be marked `@ctfeonly`, this 
would pass.




bar.d:
module bar;
string generateString(T)()
{
return T.stringof ~ " foo;";
}

enum s = generateString!int();

a.d:
@compute(CompileFor.deviceOnly) module a;

int baz()
{
import bar;
bar.s;
return foo;
}


Re: @ctfeonly

2017-12-07 Thread H. S. Teoh via Digitalmars-d
On Thu, Dec 07, 2017 at 07:20:57PM -0700, Jonathan M Davis via Digitalmars-d 
wrote:
[...]
> In spite of the fact that CTFE is done at compile time, __ctfe is a
> runtime thing - it's just that it's runtime from the perspective of
> CTFE. So, stuff like static if or static assert doesn't work. You have
> to use if or a ternary operator or some other runtime conditional,
> though it's a common misunderstanding that __ctfe is used with static
> if, and people screw it up all the time. I don't know why it's a
> runtime thing rather than a compile time thing though. There's
> probably a good reason for it, but at first glance, it seems like a
> rather weird choice.
[...]

Sigh:

https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time


T

-- 
Everybody talks about it, but nobody does anything about it!  -- Mark Twain


Re: @ctfeonly

2017-12-07 Thread Jonathan M Davis via Digitalmars-d
On Thursday, December 07, 2017 17:30:13 Manu via Digitalmars-d wrote:
> On 7 December 2017 at 17:20, Manu <turkey...@gmail.com> wrote:
> > On 7 December 2017 at 13:35, Walter Bright via Digitalmars-d <
> >
> > digitalmars-d@puremagic.com> wrote:
> >> On 12/7/2017 11:41 AM, Manu wrote:
> >>> Misuse of the API; ie, a runtime call, will result in an unsuspecting
> >>> user getting a surprising link error, rather than a nice compile-time
> >>> error explaining what they did wrong...
> >>
> >> I think Nicholas is talking about functions for which code cannot be
> >> generated.
> >>
> >> In any case, in C/C++/D if you call functions in .h files (or imports)
> >> that are not linked in, you'll get a linker error.
> >
> > Right, but that's what I'm saying; using your solution of putting a
> > function in a module that's not compiled to inhibit code generation
> > won't
> > inhibit people from *attempting* to making runtime calls (and getting
> > link errors)... whereas a compile error trying to runtime-call a
> > function that shouldn't be runtime-called might be more desirable.
> > I'm not actually registering support for @ctfeonly, just that I think
> > it's a pattern that I have wanted and should be supported in some way,
> > and a compile-time error would be nicer than a link error.
>
> I tried this, and was surprised it didn't work:
>
> int ctfeOnly(int x)
> {
> static assert(__ctfe);
> return x + 1;
> }
>
> This would probably solve the problem in a satisfying way without an
> attribute?

In spite of the fact that CTFE is done at compile time, __ctfe is a runtime
thing - it's just that it's runtime from the perspective of CTFE. So, stuff
like static if or static assert doesn't work. You have to use if or a
ternary operator or some other runtime conditional, though it's a common
misunderstanding that __ctfe is used with static if, and people screw it up
all the time. I don't know why it's a runtime thing rather than a compile
time thing though. There's probably a good reason for it, but at first
glance, it seems like a rather weird choice.

- Jonathan M Davis



Re: @ctfeonly

2017-12-07 Thread Nicholas Wilson via Digitalmars-d

On Friday, 8 December 2017 at 01:30:13 UTC, Manu wrote:

I tried this, and was surprised it didn't work:

int ctfeOnly(int x)
{
static assert(__ctfe);
return x + 1;
}

This would probably solve the problem in a satisfying way 
without an attribute?


I think that's because __ctfe, despite being magic, is actually a 
regular variable.


While this looks not too inelegant for a user perspective, I dont 
know how to handle this from a compiler perspective: filtering by 
attribute is as easy as "does this function have a UDA ctfeonly? 
If so, don't code generate it. Generating errors at codegen time 
is also trivial: when generating a call check to see if the 
callee is @ctfeonly, if it is give an error message


I don't know how to do that for a `static assert(__ctfe);`. That 
would require changes and semantic analysis in the front end 
which I am much less familiar with.


Re: @ctfeonly

2017-12-07 Thread Manu via Digitalmars-d
On 7 December 2017 at 17:20, Manu <turkey...@gmail.com> wrote:

> On 7 December 2017 at 13:35, Walter Bright via Digitalmars-d <
> digitalmars-d@puremagic.com> wrote:
>
>> On 12/7/2017 11:41 AM, Manu wrote:
>>
>>> Misuse of the API; ie, a runtime call, will result in an unsuspecting
>>> user getting a surprising link error, rather than a nice compile-time error
>>> explaining what they did wrong...
>>>
>>
>> I think Nicholas is talking about functions for which code cannot be
>> generated.
>>
>> In any case, in C/C++/D if you call functions in .h files (or imports)
>> that are not linked in, you'll get a linker error.
>>
>
> Right, but that's what I'm saying; using your solution of putting a
> function in a module that's not compiled to inhibit code generation won't
> inhibit people from *attempting* to making runtime calls (and getting link
> errors)... whereas a compile error trying to runtime-call a function that
> shouldn't be runtime-called might be more desirable.
> I'm not actually registering support for @ctfeonly, just that I think it's
> a pattern that I have wanted and should be supported in some way, and a
> compile-time error would be nicer than a link error.
>

I tried this, and was surprised it didn't work:

int ctfeOnly(int x)
{
static assert(__ctfe);
return x + 1;
}

This would probably solve the problem in a satisfying way without an
attribute?


Re: @ctfeonly

2017-12-07 Thread Manu via Digitalmars-d
On 7 December 2017 at 13:35, Walter Bright via Digitalmars-d <
digitalmars-d@puremagic.com> wrote:

> On 12/7/2017 11:41 AM, Manu wrote:
>
>> Misuse of the API; ie, a runtime call, will result in an unsuspecting
>> user getting a surprising link error, rather than a nice compile-time error
>> explaining what they did wrong...
>>
>
> I think Nicholas is talking about functions for which code cannot be
> generated.
>
> In any case, in C/C++/D if you call functions in .h files (or imports)
> that are not linked in, you'll get a linker error.
>

Right, but that's what I'm saying; using your solution of putting a
function in a module that's not compiled to inhibit code generation won't
inhibit people from *attempting* to making runtime calls (and getting link
errors)... whereas a compile error trying to runtime-call a function that
shouldn't be runtime-called might be more desirable.
I'm not actually registering support for @ctfeonly, just that I think it's
a pattern that I have wanted and should be supported in some way, and a
compile-time error would be nicer than a link error.


Re: @ctfeonly

2017-12-07 Thread Nicholas Wilson via Digitalmars-d

On Thursday, 7 December 2017 at 21:32:24 UTC, Walter Bright wrote:

On 12/7/2017 2:07 AM, Nicholas Wilson wrote:

Doesn't work for templates.


I don't know how your code is organized, but if the template is 
instantiated in another file, it won't have code generated for 
it either.


As a trivial example:

bar.d:
module bar;
string generatesMixin(T)()
{
return T.stringof ~ " foo;";
}


a.d:
@compute(CompileFor.deviceOnly) module a;

int baz()
{
mixin(generatesMixin!int());
return foo;
}

a's symbol table contains `baz` and `generatesMixin!int`. 
generateMixin deals with strings which are not allowed (global 
variables are unsupported). This would fail compilation. If 
`generatesMixin` were to be marked `@ctfeonly`, this would pass.




Re: @ctfeonly

2017-12-07 Thread Iain Buclaw via Digitalmars-d
On 7 December 2017 at 03:09, lobo via Digitalmars-d
 wrote:
> On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:
>>
>> I'd like to add an attribute to indicate that the annotated function is
>> only available at compile time so that in cases where the operation is
>> invalid at runtime (strings and concatenation on a GPU for instance) but the
>> result is only used at compile time (for a mixin) the compiler is free to
>> not codegen that function.
>>
>> I can add this to LDC pretty easily, but does anyone else have a use for
>> this (e.g. shrinking binary sizes for mixin heavy codebases) and would
>> benefit having this as a standard thing?
>
>
> Shouldn't the linker do this already?
>
> Once the compiler has CTFE'd the function any call in the code should be
> replaced with the function evaluation. The linker should then drop the code
> out of the binary because it really is dead code.
>

It should be possible to add heuristics for this (mark a function as
being instantiated and only used at compile-time).  It just doesn't
exist yet.

As for normal functions, regardless of protection, they will always be
compiled as a function visible outside the CU.  You're either going to
rely on LTO support in the compiler, kindly request that DIP45 be
given another thought, or write a new DIP that considers another way
to control symbol visibility.  But I wouldn't hold my breath on
anything happening soon.


Re: @ctfeonly

2017-12-07 Thread Johannes Pfau via Digitalmars-d
Am Thu, 7 Dec 2017 13:38:54 -0800
schrieb Walter Bright <newshou...@digitalmars.com>:

> On 12/6/2017 11:41 PM, Mike Franklin wrote:
> > On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis
> > wrote: 
> >> The simplest way to do that is to write a unit test that uses a
> >> static assertion. As I understand it, with the way CTFE works, it
> >> pretty much can't know whether a function can be called at compile
> >> time until it tries, but a unit test can catch it if the function
> >> no longer works at compile time.  
> > 
> > Not bad, but that is swaying into the cumbersome category.  If
> > that's the best we can do, a @ctfeonly attribute starts looking
> > pretty good.  
> 
> More and more attributes to do essentially trivial things is
> cumbersomeness all on its own.

I think this is more of an optimization UDA than a standard attribute.
So it's similar to all the noinline, forceinline, weak, section etc.
attributes: https://wiki.dlang.org/Using_GDC#Attributes

-- Johannes



Re: @ctfeonly

2017-12-07 Thread Johannes Pfau via Digitalmars-d
Am Thu, 07 Dec 2017 01:32:35 -0700
schrieb Jonathan M Davis <newsgrou...@jmdavisprog.com>:

> 
> In the vast majority of cases, when a function is used for CTFE, it's
> also used during runtime. So, in most cases, you want to ensure that
> a function works both with CTFE and without, and in those cases
> something like @ctfeonly wouldn't make any sense. In my experience,
> pretty much the only time that something like @ctfeonly would make
> any sense would be with a function for generating a string mixin.

Not only string mixins. When programming for microcontrollers you want
to do as much in CTFE as possible, as space for executable code is
severely limited. So you may for example want to use CTFE to generate
some lookup tables and similar stuff. Basically the whole
'initialize a variable / constant using CTFE' idiom benefits a lot from
such an attribute.

-- Johannes



Re: @ctfeonly

2017-12-07 Thread Johannes Pfau via Digitalmars-d
Am Wed, 06 Dec 2017 20:18:57 -0700
schrieb Jonathan M Davis :

> Folks have talked about all kinds of template code and stuff being
> kept around in binaries even though it was only used at compile time
> (e.g. stuff like isInputRange), but I don't know how much that's
> actually true.

You probably never call isInputRange at runtime, so the code is likely
stripped. However, TypeInfo of structs used only at CTFE is still
generated and not stripped. I remember we once had this problem with
gcc.attribute, a module which shouldn't generate any code but generated
useless TypeInfo.

-- Johannes



Re: @ctfeonly

2017-12-07 Thread Johannes Pfau via Digitalmars-d
Am Thu, 7 Dec 2017 05:55:54 +0200
schrieb ketmar <ket...@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



Re: @ctfeonly

2017-12-07 Thread Walter Bright via Digitalmars-d

On 12/6/2017 11:41 PM, Mike Franklin wrote:

On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis wrote:

The simplest way to do that is to write a unit test that uses a static 
assertion. As I understand it, with the way CTFE works, it pretty much can't 
know whether a function can be called at compile time until it tries, but a 
unit test can catch it if the function no longer works at compile time.


Not bad, but that is swaying into the cumbersome category.  If that's the best 
we can do, a @ctfeonly attribute starts looking pretty good.


More and more attributes to do essentially trivial things is cumbersomeness all 
on its own.


Re: @ctfeonly

2017-12-07 Thread Walter Bright via Digitalmars-d

On 12/7/2017 2:07 AM, Nicholas Wilson wrote:

Doesn't work for templates.


I don't know how your code is organized, but if the template is instantiated in 
another file, it won't have code generated for it either.




Re: @ctfeonly

2017-12-07 Thread Walter Bright via Digitalmars-d

On 12/7/2017 11:41 AM, Manu wrote:
Misuse of the API; ie, a runtime call, will result in an unsuspecting user 
getting a surprising link error, rather than a nice compile-time error 
explaining what they did wrong...


I think Nicholas is talking about functions for which code cannot be generated.

In any case, in C/C++/D if you call functions in .h files (or imports) that are 
not linked in, you'll get a linker error.


Re: @ctfeonly

2017-12-07 Thread Manu via Digitalmars-d
On 7 December 2017 at 01:34, Walter Bright via Digitalmars-d <
digitalmars-d@puremagic.com> wrote:

> On 12/6/2017 5:21 PM, Nicholas Wilson wrote:
>
>> I'd like to add an attribute to indicate that the annotated function is
>> only available at compile time so that in cases where the operation is
>> invalid at runtime (strings and concatenation on a GPU for instance) but
>> the result is only used at compile time (for a mixin) the compiler is free
>> to not codegen that function.
>>
>
> Put these functions into a separate import. Then import the file and use
> the functions at compile time. They will not have code generated for them.
>

Misuse of the API; ie, a runtime call, will result in an unsuspecting user
getting a surprising link error, rather than a nice compile-time error
explaining what they did wrong...


Re: @ctfeonly

2017-12-07 Thread Nicholas Wilson via Digitalmars-d

On Thursday, 7 December 2017 at 09:34:51 UTC, Walter Bright wrote:

On 12/6/2017 5:21 PM, Nicholas Wilson wrote:
I'd like to add an attribute to indicate that the annotated 
function is only available at compile time so that in cases 
where the operation is invalid at runtime (strings and 
concatenation on a GPU for instance) but the result is only 
used at compile time (for a mixin) the compiler is free to not 
codegen that function.


Put these functions into a separate import. Then import the 
file and use the functions at compile time. They will not have 
code generated for them.


Doesn't work for templates.


Re: @ctfeonly

2017-12-07 Thread Michał via Digitalmars-d
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson 
wrote:
I'd like to add an attribute to indicate that the annotated 
function is only available at compile time so that in cases 
where the operation is invalid at runtime (strings and 
concatenation on a GPU for instance) but the result is only 
used at compile time (for a mixin) the compiler is free to not 
codegen that function.


I can add this to LDC pretty easily, but does anyone else have 
a use for this (e.g. shrinking binary sizes for mixin heavy 
codebases) and would benefit having this as a standard thing?


I once tried to use dmd's -vgc option but it is not so useful 
when all CTFE funtions to generate D code trigger warnings about 
GC alcoations.


I think such an attribute would silence this warnings, dmd -vgc 
would be much cleaner then.


Re: @ctfeonly

2017-12-07 Thread Walter Bright via Digitalmars-d

On 12/6/2017 5:21 PM, Nicholas Wilson wrote:
I'd like to add an attribute to indicate that the annotated function is only 
available at compile time so that in cases where the operation is invalid at 
runtime (strings and concatenation on a GPU for instance) but the result is only 
used at compile time (for a mixin) the compiler is free to not codegen that 
function.


Put these functions into a separate import. Then import the file and use the 
functions at compile time. They will not have code generated for them.


Re: @ctfeonly

2017-12-07 Thread Jonathan M Davis via Digitalmars-d
On Thursday, December 07, 2017 07:41:18 Mike Franklin via Digitalmars-d 
wrote:
> On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis
>
> wrote:
> > The simplest way to do that is to write a unit test that uses a
> > static assertion. As I understand it, with the way CTFE works,
> > it pretty much can't know whether a function can be called at
> > compile time until it tries, but a unit test can catch it if
> > the function no longer works at compile time.
>
> Not bad, but that is swaying into the cumbersome category.  If
> that's the best we can do, a @ctfeonly attribute starts looking
> pretty good.

In the vast majority of cases, when a function is used for CTFE, it's also
used during runtime. So, in most cases, you want to ensure that a function
works both with CTFE and without, and in those cases something like
@ctfeonly wouldn't make any sense. In my experience, pretty much the only
time that something like @ctfeonly would make any sense would be with a
function for generating a string mixin. I'm sure that there are folks who
have other uses for functions that would only be used during CTFE, but
really, CTFE is designed with the idea that functions would be useable both
at runtime and at compile time, and most functions that are used during CTFE
were not designed just for CTFE. Certainly, trying to test or enforce that a
function is only used at compile time is not going to be the common case.

- Jonathan M Davis



Re: @ctfeonly

2017-12-06 Thread Mike Franklin via Digitalmars-d

On Thursday, 7 December 2017 at 06:33:42 UTC, E.S. Quinn wrote:

If all you need is a runtime error, you can already put 
assert(__ctfe); in your function.


For me, a runtime error is exactly what I want to avoid.

Mike


Re: @ctfeonly

2017-12-06 Thread Mike Franklin via Digitalmars-d
On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis 
wrote:


The simplest way to do that is to write a unit test that uses a 
static assertion. As I understand it, with the way CTFE works, 
it pretty much can't know whether a function can be called at 
compile time until it tries, but a unit test can catch it if 
the function no longer works at compile time.


Not bad, but that is swaying into the cumbersome category.  If 
that's the best we can do, a @ctfeonly attribute starts looking 
pretty good.


Mike




Re: @ctfeonly

2017-12-06 Thread Stefan Koch via Digitalmars-d
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson 
wrote:
I'd like to add an attribute to indicate that the annotated 
function is only available at compile time so that in cases 
where the operation is invalid at runtime (strings and 
concatenation on a GPU for instance) but the result is only 
used at compile time (for a mixin) the compiler is free to not 
codegen that function.


I can add this to LDC pretty easily, but does anyone else have 
a use for this (e.g. shrinking binary sizes for mixin heavy 
codebases) and would benefit having this as a standard thing?


Hi Nicholas,

I am going to add a feature which will help you in this case;
As part of the work I am doing to make templates faster.




Re: @ctfeonly

2017-12-06 Thread E.S. Quinn via Digitalmars-d

On Thursday, 7 December 2017 at 05:53:06 UTC, bauss wrote:
On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis 
wrote:

As I understand it, with the way CTFE works,
it pretty much can't know whether a function can be called at 
compile time until it tries


- Jonathan M Davis


I think that's the point of the attribute. You tell the 
compiler that this function can only be called at compile-time 
and any attempt to call it during run-time would be an error.


If all you need is a runtime error, you can already put 
assert(__ctfe); in your function.


Re: @ctfeonly

2017-12-06 Thread bauss via Digitalmars-d
On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis 
wrote:

As I understand it, with the way CTFE works,
it pretty much can't know whether a function can be called at 
compile time until it tries


- Jonathan M Davis


I think that's the point of the attribute. You tell the compiler 
that this function can only be called at compile-time and any 
attempt to call it during run-time would be an error.




Re: @ctfeonly

2017-12-06 Thread Jonathan M Davis via Digitalmars-d
On Thursday, December 07, 2017 03:43:42 Nicholas Wilson via Digitalmars-d 
wrote:
> On Thursday, 7 December 2017 at 03:18:57 UTC, Jonathan M Davis
>
> wrote:
> > On Thursday, December 07, 2017 02:09:56 lobo via Digitalmars-d
> >
> > wrote:
> >> On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson
> >>
> >> wrote:
> >> > I'd like to add an attribute to indicate that the annotated
> >> > function is only available at compile time so that in cases
> >> > where the operation is invalid at runtime (strings and
> >> > concatenation on a GPU for instance) but the result is only
> >> > used at compile time (for a mixin) the compiler is free to
> >> > not codegen that function.
> >> >
> >> > I can add this to LDC pretty easily, but does anyone else
> >> > have a use for this (e.g. shrinking binary sizes for mixin
> >> > heavy codebases) and would benefit having this as a standard
> >> > thing?
> >>
> >> Shouldn't the linker do this already?
> >>
> >> Once the compiler has CTFE'd the function any call in the code
> >> should be replaced with the function evaluation. The linker
> >> should then drop the code out of the binary because it really
> >> is dead code.
>
> Unfortunately I don't have a linker to do that for me with
> DCompute.
>
> > Regardless, needing something like an attribute to tell the
> > compiler to strip stuff out of the binary seems like a hack to
> > me. It may actually be necessary in some cases, but it just
> > feels like it should be unnecessary.
>
> Do you have any other ideas about how to achieve this other than
> an attribute?
> Having an attribute seems the most simple and straightforward.

It may be that an attribute is required in at least some cases, but it seems
like it shouldn't be and that if the compiler and/or linker isn't smart
enough to strip out stuff that's only used at compile time, then it should
be fixed to be smart enough. However, too often, there's some detail that's
not obvious that makes it so that things can't work they way that it seems
like they should. And of course, I have no clue how whatever you're doing
works if you're not using a linker with dcompute, so I don't know how it
differs from normal. I've never done anything with GPU programming.

- Jonathan M Davis



Re: @ctfeonly

2017-12-06 Thread Jonathan M Davis via Digitalmars-d
On Thursday, December 07, 2017 03:59:09 Mike Franklin via Digitalmars-d 
wrote:
> Also, I want the
> compiler to let me know if my intended-for-compile-time-only
> function cannot be used at compile-time because I mistakenly made
> it dependent on something that is only available at runtime.

The simplest way to do that is to write a unit test that uses a static
assertion. As I understand it, with the way CTFE works, it pretty much can't
know whether a function can be called at compile time until it tries, but a
unit test can catch it if the function no longer works at compile time.

- Jonathan M Davis



Re: @ctfeonly

2017-12-06 Thread meppl via Digitalmars-d
On Thursday, 7 December 2017 at 03:43:42 UTC, Nicholas Wilson 
wrote:

...

Do you have any other ideas about how to achieve this other 
than an attribute?

Having an attribute seems the most simple and straightforward.


llvm has "Aggressive Dead Code Elimination"- and "Dead Code 
Elimination"-switches, who I find interesting.

https://llvm.org/docs/Passes.html#transform-passes

I remember once I actually stripped off kinda 99% of a statically 
linked phobos-library with that and I got a small executable who 
was still working


Re: @ctfeonly

2017-12-06 Thread ketmar via Digitalmars-d

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).


Re: @ctfeonly

2017-12-06 Thread Mike Franklin via Digitalmars-d
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson 
wrote:


I can add this to LDC pretty easily, but does anyone else have 
a use for this (e.g. shrinking binary sizes for mixin heavy 
codebases) and would benefit having this as a standard thing?


I've thought about this in the past, but never really pursued it 
much to see if there are already existing facilities in the 
language to accomplish what I want.


I want to enforce that a method is only used at compile time.  
That is I want either the compiler or the linker to throw an 
error if I've accidentally used a function at runtime when I only 
intended it to be used at compile-time.  Also, I want the 
compiler to let me know if my intended-for-compile-time-only 
function cannot be used at compile-time because I mistakenly made 
it dependent on something that is only available at runtime.


That being said, I want D's features to carry their weight.  I 
would first like to prove that facilities don't already exist or 
that existing facilities are too cumbersome to accomplish said 
goal before adding such a feature.


Also, my primary motivation for using D is so I can program 
resource-constrained microcontrollers in a more fun and 
convenient language than C/C++.  I've definitely encountered 
code-size problems in D, but they were mostly due to the 
compiler's unnecessary coupling to the runtime, and the way the 
compiler generated code as the linker couldn't prove that the 
code was dead (Exhibit A: 
https://issues.dlang.org/show_bug.cgi?id=14758).  I don't yet see 
how @ctfeonly would help with that.


Mike


Re: @ctfeonly

2017-12-06 Thread ketmar via Digitalmars-d

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).




I definitely don't want D to become C++. What is smartlinking?
any decent linker simply drops anything that is not reveferenced. i.e. any 
function that is not referenced from another function that is definitely 
included in the binary, will be skipped. as linker knows program entry 
point, it is able to build reference tree, and do "smart" linking instead 
of just putting everything into resulting binary.




This is intended for stuff like code that generates strings for mixins.
as i said, this is something compiler can do automatically, without user's 
help. we already have too much attributes, i believe, adding even more 
won't do any good.


Re: @ctfeonly

2017-12-06 Thread Nicholas Wilson via Digitalmars-d
On Thursday, 7 December 2017 at 03:18:57 UTC, Jonathan M Davis 
wrote:
On Thursday, December 07, 2017 02:09:56 lobo via Digitalmars-d 
wrote:

On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson

wrote:
> I'd like to add an attribute to indicate that the annotated 
> function is only available at compile time so that in cases 
> where the operation is invalid at runtime (strings and 
> concatenation on a GPU for instance) but the result is only 
> used at compile time (for a mixin) the compiler is free to 
> not codegen that function.

>
> I can add this to LDC pretty easily, but does anyone else 
> have a use for this (e.g. shrinking binary sizes for mixin 
> heavy codebases) and would benefit having this as a standard 
> thing?


Shouldn't the linker do this already?

Once the compiler has CTFE'd the function any call in the code 
should be replaced with the function evaluation. The linker 
should then drop the code out of the binary because it really 
is dead code.




Unfortunately I don't have a linker to do that for me with 
DCompute.


Regardless, needing something like an attribute to tell the 
compiler to strip stuff out of the binary seems like a hack to 
me. It may actually be necessary in some cases, but it just 
feels like it should be unnecessary.


Do you have any other ideas about how to achieve this other than 
an attribute?

Having an attribute seems the most simple and straightforward.



Re: @ctfeonly

2017-12-06 Thread Nicholas Wilson via Digitalmars-d

On Thursday, 7 December 2017 at 02:33:49 UTC, ketmar wrote:

H. S. Teoh wrote:

On Thu, Dec 07, 2017 at 01:21:11AM +, Nicholas Wilson via 
Digitalmars-d wrote:

[...]


I'd like to have this too.  Some of my template-heavy code use 
a good
number of CTFE-only functions that are only called at 
compile-time.
Since they are nested inside the template, they do quickly add 
up to a
lot of dead code in the executable.  Having a @ctfeonly 
annotation that
tells the compiler not to codegen the (many instantiations of 
the)

function would be greatly welcomed.


T


this is a hack for something that really should be done in 
linker, automatically. please, people, let's not turn D into 
C++! ;-)


i mean: this has a short-time benefits, but makes the language 
more complex, less clear, and completely destroys any incentive 
to make smartlinking work as intended in case it is broken.


Not all of the generated code goes through a linker ;)
For dcompute strings aren't even supported yet! Let alone 
concatenation.


Also not generating the code in the first place means less I/O 
for the compiler and less work for the linker.


I definitely don't want D to become C++. What is smartlinking?

This is intended for stuff like code that generates strings for 
mixins.


Re: @ctfeonly

2017-12-06 Thread Jonathan M Davis via Digitalmars-d
On Thursday, December 07, 2017 02:09:56 lobo via Digitalmars-d wrote:
> On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson
>
> wrote:
> > I'd like to add an attribute to indicate that the annotated
> > function is only available at compile time so that in cases
> > where the operation is invalid at runtime (strings and
> > concatenation on a GPU for instance) but the result is only
> > used at compile time (for a mixin) the compiler is free to not
> > codegen that function.
> >
> > I can add this to LDC pretty easily, but does anyone else have
> > a use for this (e.g. shrinking binary sizes for mixin heavy
> > codebases) and would benefit having this as a standard thing?
>
> Shouldn't the linker do this already?
>
> Once the compiler has CTFE'd the function any call in the code
> should be replaced with the function evaluation. The linker
> should then drop the code out of the binary because it really is
> dead code.

As I understand it, if you're statically linking it should, but it can't
with dynamic linking - at least not right now. With the export improvements
that Martin Nowak and Benjamin Thaut want to do (where IIUC, export would
then be required for anything in a shared library to be accessible outside
it), then it would be possible, but right now, everything gets exported (at
least on all systems other than Windows), so none of it can be stripped out
as unused, since the linker doesn't know what's actually going to be used.
Executables should be in the same boat as static libraries though.

Also, I think that in some cases, stuff like ModuleInfo ends up referring to
stuff and keeping it around even though it isn't necessarily really used,
but I'm not sure.

Folks have talked about all kinds of template code and stuff being kept
around in binaries even though it was only used at compile time (e.g. stuff
like isInputRange), but I don't know how much that's actually true.
Personally, I don't care much about binary sizes. I certainly agree that
having unused symbols stripped out where possible is a good thing, but
AFAIK, it doesn't really matter for most of the stuff I do, and having a
binary be 5MiB instead of 1MiB doesn't matter much to me, much as I agree
that having the binary smaller is good. It just isn't usually enough disk
space or memory to matter much in practice. Clearly, some people care quite
a bit about that sort of thing, but I don't know how much it actually
matters in practice unless you're doing something with embedded systems.

Regardless, needing something like an attribute to tell the compiler to
strip stuff out of the binary seems like a hack to me. It may actually be
necessary in some cases, but it just feels like it should be unnecessary.

- Jonathan M Davis



Re: @ctfeonly

2017-12-06 Thread ketmar via Digitalmars-d

H. S. Teoh wrote:

On Thu, Dec 07, 2017 at 01:21:11AM +, Nicholas Wilson via 
Digitalmars-d wrote:

I'd like to add an attribute to indicate that the annotated function
is only available at compile time so that in cases where the operation
is invalid at runtime (strings and concatenation on a GPU for
instance) but the result is only used at compile time (for a mixin)
the compiler is free to not codegen that function.
I can add this to LDC pretty easily, but does anyone else have a use
for this (e.g. shrinking binary sizes for mixin heavy codebases) and
would benefit having this as a standard thing?


I'd like to have this too.  Some of my template-heavy code use a good
number of CTFE-only functions that are only called at compile-time.
Since they are nested inside the template, they do quickly add up to a
lot of dead code in the executable.  Having a @ctfeonly annotation that
tells the compiler not to codegen the (many instantiations of the)
function would be greatly welcomed.


T


this is a hack for something that really should be done in linker, 
automatically. please, people, let's not turn D into C++! ;-)


i mean: this has a short-time benefits, but makes the language more 
complex, less clear, and completely destroys any incentive to make 
smartlinking work as intended in case it is broken.


Re: @ctfeonly

2017-12-06 Thread lobo via Digitalmars-d
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson 
wrote:
I'd like to add an attribute to indicate that the annotated 
function is only available at compile time so that in cases 
where the operation is invalid at runtime (strings and 
concatenation on a GPU for instance) but the result is only 
used at compile time (for a mixin) the compiler is free to not 
codegen that function.


I can add this to LDC pretty easily, but does anyone else have 
a use for this (e.g. shrinking binary sizes for mixin heavy 
codebases) and would benefit having this as a standard thing?


Shouldn't the linker do this already?

Once the compiler has CTFE'd the function any call in the code 
should be replaced with the function evaluation. The linker 
should then drop the code out of the binary because it really is 
dead code.


bye,
lobo


Re: @ctfeonly

2017-12-06 Thread H. S. Teoh via Digitalmars-d
On Thu, Dec 07, 2017 at 01:21:11AM +, Nicholas Wilson via Digitalmars-d 
wrote:
> I'd like to add an attribute to indicate that the annotated function
> is only available at compile time so that in cases where the operation
> is invalid at runtime (strings and concatenation on a GPU for
> instance) but the result is only used at compile time (for a mixin)
> the compiler is free to not codegen that function.
> 
> I can add this to LDC pretty easily, but does anyone else have a use
> for this (e.g. shrinking binary sizes for mixin heavy codebases) and
> would benefit having this as a standard thing?

I'd like to have this too.  Some of my template-heavy code use a good
number of CTFE-only functions that are only called at compile-time.
Since they are nested inside the template, they do quickly add up to a
lot of dead code in the executable.  Having a @ctfeonly annotation that
tells the compiler not to codegen the (many instantiations of the)
function would be greatly welcomed.


T

-- 
Let's eat some disquits while we format the biskettes.


@ctfeonly

2017-12-06 Thread Nicholas Wilson via Digitalmars-d
I'd like to add an attribute to indicate that the annotated 
function is only available at compile time so that in cases where 
the operation is invalid at runtime (strings and concatenation on 
a GPU for instance) but the result is only used at compile time 
(for a mixin) the compiler is free to not codegen that function.


I can add this to LDC pretty easily, but does anyone else have a 
use for this (e.g. shrinking binary sizes for mixin heavy 
codebases) and would benefit having this as a standard thing?


Re: @ctfeonly

2017-12-06 Thread Nicholas Wilson via Digitalmars-d-announce
On Thursday, 7 December 2017 at 01:18:04 UTC, Nicholas Wilson 
wrote:
I'd like to add an attribute to indicate that the annotated 
function is only available at compile time so that in cases 
where the operation is invalid at runtime (strings and 
concatenation on a GPU for instance) but the result is only 
used at compile time (for a mixin) the compiler is free to not 
codegen that function.


I can add this to LDC pretty easily, but does anyone else have 
a use for this (e.g. shrinking binary sizes for mixin heavy 
codebases) and would benefit having this as a standard thing?


Urgh, this was meant for general. I'll post it there. Please 
ignore this.


@ctfeonly

2017-12-06 Thread Nicholas Wilson via Digitalmars-d-announce
I'd like to add an attribute to indicate that the annotated 
function is only available at compile time so that in cases where 
the operation is invalid at runtime (strings and concatenation on 
a GPU for instance) but the result is only used at compile time 
(for a mixin) the compiler is free to not codegen that function.


I can add this to LDC pretty easily, but does anyone else have a 
use for this (e.g. shrinking binary sizes for mixin heavy 
codebases) and would benefit having this as a standard thing?