inlining...

Jacob Carlborg doob at me.com
Fri Mar 14 10:57:59 PDT 2014


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?

> 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.

> 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.

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list