template functions, a special case of constant folding?

Kevin Bealer Kevin_member at pathlink.com
Fri Mar 24 19:14:42 PST 2006


In article <e00jv5$19h2$1 at digitaldaemon.com>,
=?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= says...
>
>Hasan Aljudy wrote:
>> Derek Parnell wrote:
>>> On Thu, 23 Mar 2006 16:34:07 -0700, Hasan Aljudy wrote:
>>>
>>>
>>>> Given the following expression:
>>>> #x = 10 * 5 + y;
>>>> the compiler will compute 10 * 5 at compile-time and convert the
>>>> expression into
>>>> #x = 50 + y;
>>>>
>>>> I think that's called constant-folding, am I right?
>>>>
>>>> Why can't this be extended such that for the following function:
>>>> # int add( int x, int y ) { return x + y; }
>>>>
>>>> if it's called with constant arguments:
>>>> # x = add( 10, 3 );
>>>>
>>>
>>>
>>> You can almost do this with mixins, except that mixins only allow one to
>>> mixin a complete statement and not just an expression. What would be
>>> useful
>>> is to allow mixins (or some other similar thing) to generate
>>> expressions at
>>> compile time and not just statements. Something like ...
>>>
>>>  
>>>  template add(b,c)
>>>  {
>>>     b + c;
>>>  }
>>>
>>>  int main()
>>>  {
>>>    int q;
>>>    q = mixin add!(10,3);
>>>    return q;
>>>  }
>>>
>>> Which would generate
>>>  int main()
>>>  {
>>>    int q;
>>>    q = 10 + 3;
>>>    return q;
>>>  }
>>>
>>> Which the compiler would constant-fold as normal.
>>>
>>> But this is starting to look too much like text macros which Walter is
>>> very
>>> concerned not to have.
>>>
>> 
>> but you're still using templates. which completely defies my point!
>
>Doing this kind of compiler optimization is very expensive (adds
>compiling time & optimizer complexity and thus more bugs). If you
>already know that the function should be folded / inlined when you're
>writing the code, it's a natural way to explicitly say this with
>templates. I think the compiler already does some tricks when -inline is
>used. I think new M$ compilers convert stuff like this:
>
> int a = 5, b = 2;
> for (int i=0; i<3; i++) a *= b;
> int get(int c) { return c+2; }
> a = b = get(a);
>
>into:
>
> int a = 42, b = 42;
>
>but IMHO it's a sign of a bad coder not to optimize code on the higher
>levels. It's extremely simple to "hint" to compiler by using templates
>and lift the burden of implementation to the metaprogramming engine.
>
>-- 
>Jari-Matti

An idiom that I find helpful is static variables.

: int[] BuildLookupTable(...)
: {
:     // computes some complex table or
:     // other data set.
: }
:
: int do_lookup(int i)
: {
:     static int[] s = BuildLookupTable(...);
:     return s[i];
: }

The static int[] gets computed once and stored the first time the code runs,
after this the compiler just checks that it is assigned.  I use this in C++.  

I'm not sure if this works in D, if not you can still do this:

: static int[] s;
: if (s.length == 0) {
:    s = BuildLookupTable();
: }

Sometimes a data structure computation is complex and has a lot of data, but the
code to compute it is compact.  This lets you build that code on demand at the
point of use, and only if the program needs it.

Kevin





More information about the Digitalmars-d-announce mailing list