inlining...

Manu turkeyman at gmail.com
Fri Mar 14 21:15:33 PDT 2014


On 15 March 2014 03:57, Jacob Carlborg <doob at me.com> wrote:

> On 2014-03-14 07:21, Manu wrote:
>
>> So, I'm constantly running into issues with not having control over
>> inline.
>> I've run into it again doing experiments in preparation for my dconf
>> talk...
>>
>> I have identified 2 cases which come up regularly:
>>   1. A function that should always be inline unconditionally (std.simd
>> is effectively blocked on this)
>>   2. A particular invocation of a function should be inlined for this
>> call only
>>
>> The first case it just about having control over code gen. Some
>> functions should effectively be macros or pseudo-intrinsics (ie,
>> intrinsic wrappers in std.simd, beauty wrappers around asm code, etc),
>> and I don't ever want to see a symbol appear in the binary.
>>
>> My suggestion is introduction of __forceinline or something like it. We
>> need this.
>>
>
> Haven't we already agreed a pragma for force inline should be implemented.
> Or is that something I have dreamed?


It's been discussed. I never agreed to it (I _really_ don't like it), but
I'll take it if it's the best I'm gonna get.

I don't like stateful attributes like that. I think it's error prone,
especially when it's silent.
'private:' for instance will complain if you write a new function in an
area influenced by the private state and try and call it from elsewhere;
ie, you know you made the mistake.
If you write a new function in an area influenced by the forceinline state
which wasn't intended to be inlined, you won't know. I think that's
dangerous.

 The second case is interesting, and I've found it comes up a few times
>> on different occasions.
>> In my current instance, I'm trying to build generic framework to perform
>> efficient composable data processing, and a basic requirement is that
>> the components are inlined, such that the optimiser can interleave the
>> work properly.
>>
>> Let's imagine I have a template which implements a work loop, which
>> wants to call a bunch of work elements it receives by alias. The issue
>> is, each of those must be inlined, for this call instance only, and
>> there's no way to do this.
>> I'm gonna draw the line at stringified code to use with mixin; I hate
>> that, and I don't want to encourage use of mixin or stringified code in
>> user-facing API's as a matter of practise. Also, some of these work
>> elements might be useful functions in their own right, which means they
>> can indeed be a function existing somewhere else that shouldn't itself
>> be attributed as __forceinline.
>>
>> What are the current options to force that some code is inlined?
>>
>> My feeling is that an ideal solution would be something like an
>> enhancement which would allow the 'mixin' keyword to be used with
>> regular function calls.
>> What this would do is 'mix in' the function call at this location, ie,
>> effectively inline that particular call, and it leverages a keyword and
>> concept that we already have. It would obviously produce a compile error
>> of the code is not available.
>>
>> I quite like this idea, but there is a potential syntactical problem;
>> how to assign the return value?
>>
>> int func(int y) { return y*y+10; }
>>
>> int output = mixin func(10); // the 'mixin' keyword seems to kinda 'get
>>
>
> I think this is the best syntax of these three alternatives.
>
>
>  in the way' if the output
>> int output = mixin(func(10)); // now i feel paren spammy...
>>
>
> This syntax can't work. It's already interpreted calling "func" and use
> the result as a string mixin.
>
>
>  mixin(int output = func(10)); // this doesn't feel right...
>>
>
> No.
>
>
>  My feeling is the first is the best, but I'm not sure about that
>> grammatically.
>>
>
> Yeah, I agree.


So you think it's grammatically okay?

 The other thing that comes to mind is that it seems like this might make
>> a case for AST macros... but I think that's probably overkill for this
>> situation, and I'm not confident we're ever gonna attempt to crack that
>> nut. I'd like to see something practical and unobjectionable preferably.
>>
>
> AST macros would solve it. It could solve the first use case as well. I
> would not implement AST macros just to support force inline but we have
> many other uses cases as well. I would have implement AST macros a long
> time ago. Hopefully this would avoid the need to create new language
> features in some cases.
>
> First use case, just define a macro that returns the AST for the content
> of the function you would create.
>
> macro func (Ast!(int) a)
> {
>     return <[ $a * $a; ]>;
> }
>
> int output = func(10); // always inlined
>
> Second use case, define a macro, "inline", that takes the function you
> want to call as a parameter. The macro will basically inline the body.
>
> macro inline (T, U...) (Ast!(T function (U) func)
> {
>     // this would probably be more complicated
>     return func.body;
> }
>
> int output = func(10); // not inlined
> int output = inline(func(10)); // always inlined
>
>
>  This problem is fairly far reaching; phobos receives a lot of lambdas
>> these days, which I've found don't reliably inline and interfere with
>> the optimisers ability to optimise the code.
>>
>
> I thought since lambdas are passed as template parameters they would
> always be inlined.


Maybe... (and not in debug builds). Without explicit control of the
inliner, you just never know.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20140315/0704746d/attachment.html>


More information about the Digitalmars-d mailing list