Thread overview
Problems with Template codegen
Feb 05, 2007
kris
Feb 05, 2007
kris
Feb 05, 2007
Derek Parnell
February 05, 2007
At this time, D templates are a bit finicky when it comes to argument matching -- IFTI matching, to be explicit. For example:

# uint locate(T) (T[] source, T match, uint start=0);
#
# locate ("wumpus", 'p', 1);

will not compile because '1' is an integer literal, and does not match the template parameter 'uint'.

To get around this, template writers will revert to tricks like this one:

# uint locate(T) (T[] source, T match, uint start=0);
#
# uint locate(T, U=uint) (T[] source, T match, U start=0)
# {
#     return locate!(T) (source, match, start);
# }
#
# locate ("wumpus", 'p', 1);


See what's going on? There's a stub added, which marshalls (for want of a better term) the 'int' argument  across. This is done to (a) permit use of both int & uint arguments and (b) to avoid template duplication for both int and uint types.

So, that's a current shortcoming of IFTI -- but it's one that we hope will be fixed. Moving onto the primary concern ...

As one would expect, the DM compiler generates code for the stub to re-push the arguments and call the /real/ implementation. However, in /all/ cases we really want to eliminate the stub since it is nothing but a pass-through call; one generated to workaround what seems to be an IFTI limitation.

Unfortunately, the DM tools will remove the stub /only/ when you use the -inline switch. This is a very powerful switch, causing all kinds of inlining to occur -- in some cases, things which many engineers would balk at. Inline is often just too /big/ a switch to pull.

However, we'd still like darned stubs to be removed from the codegen. How do we get that to happen?
February 05, 2007
kris wrote:
> At this time, D templates are a bit finicky when it comes to argument matching -- IFTI matching, to be explicit. For example:
> 
> # uint locate(T) (T[] source, T match, uint start=0);
> #
> # locate ("wumpus", 'p', 1);
> 
> will not compile because '1' is an integer literal, and does not match the template parameter 'uint'.
> 
> To get around this, template writers will revert to tricks like this one:
> 
> # uint locate(T) (T[] source, T match, uint start=0);
> #
> # uint locate(T, U=uint) (T[] source, T match, U start=0)
> # {
> #     return locate!(T) (source, match, start);
> # }
> #
> # locate ("wumpus", 'p', 1);
> 
> 
> See what's going on? There's a stub added, which marshalls (for want of a better term) the 'int' argument  across. This is done to (a) permit use of both int & uint arguments and (b) to avoid template duplication for both int and uint types.
> 
> So, that's a current shortcoming of IFTI -- but it's one that we hope will be fixed. Moving onto the primary concern ...
> 
> As one would expect, the DM compiler generates code for the stub to re-push the arguments and call the /real/ implementation. However, in /all/ cases we really want to eliminate the stub since it is nothing but a pass-through call; one generated to workaround what seems to be an IFTI limitation.
> 
> Unfortunately, the DM tools will remove the stub /only/ when you use the -inline switch. This is a very powerful switch, causing all kinds of inlining to occur -- in some cases, things which many engineers would balk at. Inline is often just too /big/ a switch to pull.
> 
> However, we'd still like darned stubs to be removed from the codegen. How do we get that to happen?

One notion would be to use the (T, U=uint) notation for the 'real' template and leave the stub out, but it defeats the original intent somewhat and doesn't really *solve* the problem.  I'd say IFTI just needs to incorporate implicit casting rules such as int->uint and that would be a solution.

-- Chris Nicholson-Sauls
February 05, 2007
On Sun, 04 Feb 2007 16:50:02 -0800, kris wrote:

> At this time, D templates are a bit finicky when it comes to argument matching -- IFTI matching, to be explicit. For example:
> 
> # uint locate(T) (T[] source, T match, uint start=0);
> #
> # locate ("wumpus", 'p', 1);
> 
> will not compile because '1' is an integer literal, and does not match the template parameter 'uint'.

The way I'd prefer D to work is rather than seeing the 1 and deciding that this literal must only be an *int*, it could recognize that the literal *1* is ambiguous, as it could be stored as one of a number of integer forms. It would then search for which signatures match "integer" rather than "int", and if there is only one, resolve the literal's ambiguity by using the sole matching signature. Of course, if there are multiple matching signatures then it needs to alert the coder of the ambiguity and have them sort it out by explicit casts.

I base my opinion on the need for programming languages and compilers to be helpful to people, as a first priority.

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocrity!"
5/02/2007 1:37:33 PM
February 05, 2007
Chris Nicholson-Sauls wrote:
> kris wrote:
> 
>> At this time, D templates are a bit finicky when it comes to argument matching -- IFTI matching, to be explicit. For example:
>>
>> # uint locate(T) (T[] source, T match, uint start=0);
>> #
>> # locate ("wumpus", 'p', 1);
>>
>> will not compile because '1' is an integer literal, and does not match the template parameter 'uint'.
>>
>> To get around this, template writers will revert to tricks like this one:
>>
>> # uint locate(T) (T[] source, T match, uint start=0);
>> #
>> # uint locate(T, U=uint) (T[] source, T match, U start=0)
>> # {
>> #     return locate!(T) (source, match, start);
>> # }
>> #
>> # locate ("wumpus", 'p', 1);
>>
>>
>> See what's going on? There's a stub added, which marshalls (for want of a better term) the 'int' argument  across. This is done to (a) permit use of both int & uint arguments and (b) to avoid template duplication for both int and uint types.
>>
>> So, that's a current shortcoming of IFTI -- but it's one that we hope will be fixed. Moving onto the primary concern ...
>>
>> As one would expect, the DM compiler generates code for the stub to re-push the arguments and call the /real/ implementation. However, in /all/ cases we really want to eliminate the stub since it is nothing but a pass-through call; one generated to workaround what seems to be an IFTI limitation.
>>
>> Unfortunately, the DM tools will remove the stub /only/ when you use the -inline switch. This is a very powerful switch, causing all kinds of inlining to occur -- in some cases, things which many engineers would balk at. Inline is often just too /big/ a switch to pull.
>>
>> However, we'd still like darned stubs to be removed from the codegen. How do we get that to happen?
> 
> 
> One notion would be to use the (T, U=uint) notation for the 'real' template and leave the stub out, but it defeats the original intent somewhat and doesn't really *solve* the problem.

That's right, because you wind up with multiple instantiations of the same template, just for the same of supporting int type-variations.


> I'd say IFTI just needs to incorporate implicit casting rules such as int->uint and that would be a solution.

Right. But are we supposed to do in the interim?

- Kris