| Thread overview | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 10, 2012 Is it possible to force CTFE? | ||||
|---|---|---|---|---|
| ||||
Three related questions:
1) Is there a way to force a function to be always executed at compile time (when it's possible to do so) no matter what context it's called in?
2) Is it possible to specialize a function based on whether or not the parameter that was passed in is a compile time constant?
3) Does any D compiler currently optimize out a conditional branch which _can_ be evaluated at compile time (but which isn't forced into CTFE)? Like:
int getValue(bool b)
{
return b ? 123 : 456;
}
//...
auto value = getValue(true);
| ||||
June 10, 2012 Re: Is it possible to force CTFE? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Tommi | > 1) Is there a way to force a function to be always executed at compile time (when it's possible to do so) no matter what context it's called in? No, but you could wrap it in a template to force it to always execute at compile time. Of course it could then only be called at compile time. > 2) Is it possible to specialize a function based on whether or not the parameter that was passed in is a compile time constant? No. > 3) Does any D compiler currently optimize out a conditional branch which _can_ be evaluated at compile time (but which isn't forced into CTFE)? Like: > > int getValue(bool b) > { > return b ? 123 : 456; > } > > //... > auto value = getValue(true); DMD, LDC and GDC all do this when compiling with optimizations turned on. They all compile these functions to exactly the same code: auto foo() { return getValue(true); } auto bar() { return 123; } | |||
June 10, 2012 Re: Is it possible to force CTFE? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Tommi | On 06/10/2012 09:04 AM, Tommi wrote: > Three related questions: > > 1) Is there a way to force a function to be always executed at compile > time (when it's possible to do so) no matter what context it's called in? > No there is not. You could use a template that calls a private function at compile time instead. What is your use case? > 2) Is it possible to specialize a function based on whether or not the > parameter that was passed in is a compile time constant? > This has been discussed before, but there is not. 1-2) could be introduced later when D gets AST macros. > 3) Does any D compiler currently optimize out a conditional branch which > _can_ be evaluated at compile time (but which isn't forced into CTFE)? > Like: > > int getValue(bool b) > { > return b ? 123 : 456; > } > > //... > auto value = getValue(true); Yes, DMD/GDC/LDC should be able to do this to different extents. | |||
June 10, 2012 Re: Is it possible to force CTFE? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Sunday, 10 June 2012 at 10:23:09 UTC, Timon Gehr wrote:
> No there is not. You could use a template that calls a private function at compile time instead. What is your use case?
I was just thinking about a situation where a property accessor/mutator methods are not as simple as read/assign value, such as in this silly example:
struct Flipping123
{
private int m_number = 123;
@property bool isPositive()
{
return m_number >= 0;
}
@property void isPositive(bool b)
{
m_number = b ? 123 : -123;
}
}
//...
Flipping123 fl;
fl.isPositive = false; // I'd rather not have cond. branching in release mode
| |||
September 27, 2012 Re: Is it possible to force CTFE? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to jerro | On Sunday, 10 June 2012 at 10:16:23 UTC, jerro wrote:
>
> No, but you could wrap it in a template to force it to always
> execute at compile time.
So, I just realized, I could have just this one convenience template that I can use whenever I want to force an expression to be evaluated at compile-time. Like so:
template ct(alias expr)
{
enum ct = expr;
}
int fun(int a, int b)
{
return a + b;
}
//... and use it like:
ct!(fun(1, 2))
That's not *too* inconvenient. Although, best would be a function attribute that would force the compiler to apply ctfe aggressively whenever it can with calls to that function.
| |||
September 27, 2012 Re: Is it possible to force CTFE? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Tommi | Tommi:
> 2) Is it possible to specialize a function based on whether or not the parameter that was passed in is a compile time constant?
I am interested in this since some years. I think it's useful, but I don't know if it can be implemented. I don't remember people discussing about this much.
Bye,
bearophile
| |||
September 27, 2012 Re: Is it possible to force CTFE? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 2012-09-27 15:01, bearophile wrote: > Tommi: > >> 2) Is it possible to specialize a function based on whether or not the >> parameter that was passed in is a compile time constant? > > I am interested in this since some years. I think it's useful, but I > don't know if it can be implemented. I don't remember people discussing > about this much. There's the if (__ctfe) hack. Also using only template parameters will force the function to be CTFE. -- /Jacob Carlborg | |||
September 27, 2012 Re: Is it possible to force CTFE? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | Jacob Carlborg:
>> I am interested in this since some years. I think it's useful, but I don't know if it can be implemented. I don't remember
>> people discussing about this much.
>
> There's the if (__ctfe) hack. Also using only template parameters will force the function to be CTFE.
This is quite far from what I was discussing about here...
Bye,
bearophile
| |||
September 28, 2012 Re: Is it possible to force CTFE? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | One use case I can think of for specializing functions based on whether or not its arguments are compile-time evaluable:
// Big container that can't be accessed in constant time:
immutable cachedResults = init();
double getResult(<args>)
if (areCompileTimeConstants!(<args>) == false)
{
return cachedResults.at(<args>);
}
double getResult(<args>)
if (areCompileTimeConstants!(<args>) == true)
{
// Computing the result takes long time
...
return computedResult;
}
Point being that A) cachedResults takes so much memory we don't want to evaluate it at compile-time and bloat the executable, and B) accessing cachedResults takes some non-trivial time, so we don't want to do that at runtime if it can be done at compile-time. Don't know how common this kind of thing would be though.
But, that made me think...
In a perfect world, I think, the compiler would always evaluate all possible functions at compile-time, given that doing so would produce a smaller (or equal size) executable than what not-evaluating-at-compile-time would produce. For example (assuming the following initialization functions are compile-time evaluable):
// The following wouldn't be evaluated at compile time,
// because that function call (probably) wouldn't take
// as much space in the executable as million ints:
int[1_000_000] bigArray = initBigArray();
// The following would be always evaluated at compile time,
// because a single int value would take less space in the
// executable than the function call:
int myValue = initMyValue();
Although, to speed up test compilations, we'd need a compiler flag to disable this "aggressive" CTFE behaviour.
| |||
September 28, 2012 Re: Is it possible to force CTFE? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Tommi | On Friday, 28 September 2012 at 17:52:55 UTC, Tommi wrote:
> In a perfect world, I think, the compiler would always evaluate all possible functions at compile-time, given that doing so would produce a smaller (or equal size) executable than what not-evaluating-at-compile-time would produce.
Or, a simpler rule (for both the compiler and the coder):
Have a compiler flag where you set a value (in bytes), and if a function returns a type that's size is not larger than the set value, the compiler would execute all calls to that function at compile-time (if possible).
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply