Compile-time optimization

JS js.mdnq at gmail.com
Tue Jul 23 16:35:23 PDT 2013


On Tuesday, 23 July 2013 at 22:38:35 UTC, Yota wrote:
> On Tuesday, 23 July 2013 at 20:11:21 UTC, JS wrote:
>> Your code doesn't exactly do what I wanted but probably 
>> because I wasn't clear... I think it is modifiable and solves 
>> the problem I was having(again, assuming your code is correct).
>>
>> Note though that something like
>>
>> string x = "asd"
>> join(x,...); // x is compile time known and should be joined 
>> at compile time. Not sure if D is smart enough to get this one?
>>
>> When I get some time later I'll check your code out, what I 
>> want to do is get something like
>>
>> string x = join(a, b, "a", "b"); to produce the same code as
>> string x = a~b~"ab";
>>
>> (no looping using for each except for string arrays)
>>
>> Thanks!
>
>
> Don't forget that tuples can store more than just types!  See 
> this for instance.
>
>   import std.stdio;
>
>   typeof(Xs[0]) sum(Xs...)()
>   {
>       pragma(msg, Xs); // tuple(1, 2, 3)
>       typeof(Xs[0]) y;
>       foreach(x; Xs) y ~= x;
>       return y;
>   }
>
>   int main() {
>       auto n = sum!(1, 2, 3);
>       enum m = sum!(1, 2, 3);
>
>       pragma(msg, typeof(n)); // int
>       writeln(n); // 6
>       writeln(m); // 6
>
>       return 0;
>   }
>
> Works great.  When I comment out the 'sum!("1", "2", "3")' and 
> replace it with a literal '6', the compiled EXE is byte for 
> byte exactly the same.  You can exchange the '+=' for '~=' and 
> it will concatenate strings instead.  Of course, now all 
> arguments MUST be known at compile time, but that's no surprise.
>
> PS: OK, just noticed that you were hoping to mix run time and 
> compile time arguments.  Oops....
> Oh well, posting anyway because I think it's neat. lol
>
> As for a~"B"~"C" compiling into a~"BC", I think we just need to 
> work on constant folding in the compiler. (If it doesn't 
> already do this anyway.)

Well, it's not that simple. Constant folding is easy when it is 
obvious to the compiler... but something buried in foreach loop 
that uses runtime and compile time objects is not obvious.

My three points out of the post is:

1. D needs some way to make doing this stuff easier.
2. It needs to be done! ;)
3. Goto 1.

I didn't realize D could even potentially do it, and still not 
sure if it can(have to check out T's post again and work with the 
code).

I think there is a lot of potential power behind such techniques 
with regard to optimization.

Suppose you are writing a matrix library. Wouldn't it be nice to 
have certain matrix computations that can be done at compile time 
actually done? (I suppose what I'm trying to do is extend the 
compiler's "constant folding" to be able to deal with much more 
complex cases).


Another way to potentially do it, I think, is for the compiler to 
automatically expand ctfe functions and replace runtime entities 
with "placeholder" code which is then expanded at runtime.

e.g., for a simple join

join(T...)(T t)
{
     string s;
     foreach(tt; t)
         s ~= tt;
     return s;
}

the compiler can unroll the loop to get

s ~= t[0]~t[1]~t[2]~...;

replace the compile time entities, e.g., suppose t[1] and t[3] 
are known at compile time at the invocation, then

s ~= t[0]~"abcd"~t[2]~"asdf";

then this code could be used inline for the join call instead of 
the actual code. The key here is there is no dependence on the 
for loop. If all arguments are compile-time evaluable, then s 
could be just a reference lookup to a static string. If it can't 
be done, then no big deal, it is optimized as far as it can go. 
Only if all arguments passed are runtime entities will the exact 
code be used.

This seems like it would take a pretty smart compiler and 
possibly it would have issues in some many cases. I personally 
don't mind writing the code itself but it seems pretty complex, 
and having no way to debug the code generation easily(AFAIK) 
makes it difficult to do.

Possibly using version(ctfe) can help... I'll work on it when I 
get a chance...


More information about the Digitalmars-d mailing list