March 15, 2014
On 15 March 2014 14:33, Daniel Murphy <yebbliesnospam@gmail.com> wrote:

> "Manu" <turkeyman@gmail.com> wrote in message news:mailman.128.1394856947. 23258.digitalmars-d@puremagic.com...
>
>  > 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.
>>
>
> Huh?  The pragma could easily be restricted to apply to exactly one function declaration, if that's what's desired.
>

Then why bother with a pragma?
It's just a special case for the sake of a special case... I don't see why
resist the language conventions. Where's the precedent for that? It just
sounds like it's asking to cause edge cases and trouble down the line.
Is it gonna get messy when it involves with templates? What about methods,
sub-functions?


March 17, 2014
On 15 March 2014 14:55, Manu <turkeyman@gmail.com> wrote:

> On 15 March 2014 14:33, Daniel Murphy <yebbliesnospam@gmail.com> wrote:
>
>> "Manu" <turkeyman@gmail.com> wrote in message news:mailman.128.1394856947.23258.digitalmars-d@puremagic.com...
>>
>>  > 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.
>>>
>>
>> Huh?  The pragma could easily be restricted to apply to exactly one function declaration, if that's what's desired.
>>
>
> Then why bother with a pragma?
> It's just a special case for the sake of a special case... I don't see why
> resist the language conventions. Where's the precedent for that? It just
> sounds like it's asking to cause edge cases and trouble down the line.
> Is it gonna get messy when it involves with templates? What about methods,
> sub-functions?
>

*bump*
I actually care about this a whole lot more than final-by-default right now
;)

I'd like to think there's a possible solution to these problems that everyone agrees with.


March 17, 2014
On 3/17/14, 6:26 AM, Manu wrote:
> On 15 March 2014 14:55, Manu <turkeyman@gmail.com
> <mailto:turkeyman@gmail.com>> wrote:
>
>     On 15 March 2014 14:33, Daniel Murphy <yebbliesnospam@gmail.com
>     <mailto:yebbliesnospam@gmail.com>> wrote:
>
>         "Manu" <turkeyman@gmail.com <mailto:turkeyman@gmail.com>> wrote
>         in message
>         news:mailman.128.1394856947.__23258.digitalmars-d@puremagic.__com...
>
>              > 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.
>
>
>         Huh?  The pragma could easily be restricted to apply to exactly
>         one function declaration, if that's what's desired.
>
>
>     Then why bother with a pragma?
>     It's just a special case for the sake of a special case... I don't
>     see why resist the language conventions. Where's the precedent for
>     that? It just sounds like it's asking to cause edge cases and
>     trouble down the line.
>     Is it gonna get messy when it involves with templates? What about
>     methods, sub-functions?
>
>
> *bump*
> I actually care about this a whole lot more than final-by-default right
> now ;)
>
> I'd like to think there's a possible solution to these problems that
> everyone agrees with.

I'd like to see a solution to inlining along the lines of "pliz pliz inline" (best effort) and "never inline".

Outlining only at a specific call site is seldom needed and when it is it's trivially achievable with a noinline function forwarding to the inline function. Inlining only at a specific call site is a tall order and essentially impossible if header generation had been used.


Andrei

March 17, 2014
On 18 March 2014 01:36, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>wrote:

>
> I'd like to see a solution to inlining along the lines of "pliz pliz inline" (best effort) and "never inline".
>
> Outlining only at a specific call site is seldom needed and when it is it's trivially achievable with a noinline function forwarding to the inline function. Inlining only at a specific call site is a tall order and essentially impossible if header generation had been used.


I don't follow, how does that work?
It's the key innovation here. Since D doesn't have macros, I think it's
something that really needs to be supported nicely.
Obviously it's impossible if source is unavailable. It should give the same
complaints that CTFE gives when source is unavailable.


March 17, 2014
On 3/17/14, 9:10 AM, Manu wrote:
> On 18 March 2014 01:36, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org <mailto:SeeWebsiteForEmail@erdani.org>>
> wrote:
>
>
>     I'd like to see a solution to inlining along the lines of "pliz pliz
>     inline" (best effort) and "never inline".
>
>     Outlining only at a specific call site is seldom needed and when it
>     is it's trivially achievable with a noinline function forwarding to
>     the inline function. Inlining only at a specific call site is a tall
>     order and essentially impossible if header generation had been used.
>
>
> I don't follow, how does that work?
> It's the key innovation here. Since D doesn't have macros, I think it's
> something that really needs to be supported nicely.
> Obviously it's impossible if source is unavailable. It should give the
> same complaints that CTFE gives when source is unavailable.

The notion that a compiler can ask for any function to be inlined without the compiler having been "warned" in the function declaration makes me uncomfortable about feasibility.

However, upon further thinking the same happens with CTFE.


Andrei

March 18, 2014
On 18 March 2014 06:37, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>wrote:

> On 3/17/14, 9:10 AM, Manu wrote:
>
>> On 18 March 2014 01:36, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org <mailto:SeeWebsiteForEmail@erdani.org>>
>>
>> wrote:
>>
>>
>>     I'd like to see a solution to inlining along the lines of "pliz pliz
>>     inline" (best effort) and "never inline".
>>
>>     Outlining only at a specific call site is seldom needed and when it
>>     is it's trivially achievable with a noinline function forwarding to
>>     the inline function. Inlining only at a specific call site is a tall
>>     order and essentially impossible if header generation had been used.
>>
>>
>> I don't follow, how does that work?
>> It's the key innovation here. Since D doesn't have macros, I think it's
>> something that really needs to be supported nicely.
>> Obviously it's impossible if source is unavailable. It should give the
>> same complaints that CTFE gives when source is unavailable.
>>
>
> The notion that a compiler can ask for any function to be inlined without the compiler having been "warned" in the function declaration makes me uncomfortable about feasibility.
>
> However, upon further thinking the same happens with CTFE.


Exactly, we already have it in CTFE. It doesn't really add any new concept
that D isn't already comfortable with.
It can kinda be seen as sort of a type safe macro, which is a tool that D
is lacking compared to C. I think the mixin keyword and concept makes
perfect sense in this context. It feels quite intuitive to me.


March 18, 2014
On Saturday, 15 March 2014 at 04:17:06 UTC, Manu wrote:
> I'd say it should inline only func. Any sub-calls are subject to the
> regular inline heuristics.

I agree with you that explicit inlining is absolutely necessary and that call site inlining is highly desirable. However, I think that the call-site inlining should inline as much as possible. Basically this is something you will try when the code is too slow to meet real time deadlines and you hope to avoid going for a hand optimized solution in order to cut down on dev time. That suggests aggressive inlining to me.

If the inlining only goes one level then I don't think this will be used frequently enough to be useful, e.g. you can just create one inline version and then a non-inline version that calls the inline version.

E.g.:

noninline_func(){ inline_func();}


Ola.
March 19, 2014
On 18 March 2014 23:11, <7d89a89974b0ff40.invalid@internationalized.invalid>wrote:

> On Saturday, 15 March 2014 at 04:17:06 UTC, Manu wrote:
>
>> I'd say it should inline only func. Any sub-calls are subject to the regular inline heuristics.
>>
>
> I agree with you that explicit inlining is absolutely necessary and that call site inlining is highly desirable. However, I think that the call-site inlining should inline as much as possible. Basically this is something you will try when the code is too slow to meet real time deadlines and you hope to avoid going for a hand optimized solution in order to cut down on dev time. That suggests aggressive inlining to me.
>

Inlining is a basic codegen tool, and it's important that low-level
programmers have tight control over this aspect of the compiler's codegen.
I think it's a mistake to consider it an optimisation, unless you know
precisely what you're doing.
I wouldn't want to see it try and forcibly inline the whole tree; there's
no reason to believe that the whole tree should be inlined 100% of the
time, rather, it's almost certainly not the case.
In the case you do want to inline the whole tree, you can just cascade the
mixin through the stack. In the case you suggest which flattens the tree by
default, we've lost control; how to tell it only to do it for one level
without hacks? And I believe this is the common case.

For example, It's very likely that you might require a function to inline that is relatively trivial in its own right; a wrapper or a macro effectively, but conditionally calls an expensive function, or perhaps calls a function that you don't have source for (it would break at that point if it tried to inline the tree).

If the inlining only goes one level then I don't think this will be used
> frequently enough to be useful, e.g. you can just create one inline version and then a non-inline version that calls the inline version.
>

As the one that requested it, I have numerous uses for it to mixin just the one level. I can't imagine any uses where I would ever want to explicitly inline the whole tree, and not be happy to cascade it manually.

E.g.:
>
> noninline_func(){ inline_func();}
>

Why? This is really overcomplicating a simple thing. And I'm not quite sure
what you're suggesting this should do either. Are you saying the call tree
is flattened behind this proxy non-inline function? I don't think that's
useful.
I don't think anything would/should be marked __alwaysinline unless you
REALLY mean that it has literally no business being called. Ie, marking
something __alwaysinline just for the sake of wrapping it with a non-inline
is the wrong thing to do.

Just to reiterate, inline is a tool, not an 'optimisation'. It doesn't necessarily yield faster code, in many situations it is slower, and best left to the compiler to decide. But it's an important tool for any low-level programmer to have. D must provide a sufficient suite of low-level tools that allow proper control over the code generation. I think as a tool, it should be deliberate and conservative in approach, ie, just one level, and let the programmer cascade it if that's what they mean to do. There should be no surprises with something like this, and if it's inlining a whole call tree, you often don't know what happens further down the tree, and it's more likely to change on you unexpectedly.


March 19, 2014
On Wednesday, 19 March 2014 at 01:28:48 UTC, Manu wrote:
> In the case you do want to inline the whole tree, you can just cascade the
> mixin through the stack. In the case you suggest which flattens the tree by
> default, we've lost control; how to tell it only to do it for one level
> without hacks? And I believe this is the common case.

You could provide it with a recursion level parameter or parameters for cost level heuristics.

It could also be used to flatten tail-call recursion.

> As the one that requested it, I have numerous uses for it to mixin just the
> one level. I can't imagine any uses where I would ever want to explicitly
> inline the whole tree, and not be happy to cascade it manually.

In innerloops to factor out common subexpressions that are otherwise recomputed over and over and over.

When the function is generated code (not hand written).

>> noninline_func(){ inline_func();}
>>
>
> Why? This is really overcomplicating a simple thing. And I'm not quite sure
> what you're suggesting this should do either. Are you saying the call tree
> is flattened behind this proxy non-inline function?

No, I am saying that the one level mixin doesn't provide you with anything new. You already have that. It is sugar.
March 19, 2014
On 19 March 2014 16:18, <7d89a89974b0ff40.invalid@internationalized.invalid>wrote:

> On Wednesday, 19 March 2014 at 01:28:48 UTC, Manu wrote:
>
>> In the case you do want to inline the whole tree, you can just cascade the
>> mixin through the stack. In the case you suggest which flattens the tree
>> by
>> default, we've lost control; how to tell it only to do it for one level
>> without hacks? And I believe this is the common case.
>>
>
> You could provide it with a recursion level parameter or parameters for cost level heuristics.
>

Again, I think this is significantly overcomplicating something which see is being extremely simple.

It could also be used to flatten tail-call recursion.


I don't think it's valid to inline a tail call recursion, because the
inlined call also wants to inline another call to itself...
You can't know how fer it should go, so it needs to be transformed into a
loop, and not we're talking about something completely different than
inlining.

 As the one that requested it, I have numerous uses for it to mixin just the
>> one level. I can't imagine any uses where I would ever want to explicitly inline the whole tree, and not be happy to cascade it manually.
>>
>
> In innerloops to factor out common subexpressions that are otherwise recomputed over and over and over.
>

This is highly context sensitive. I would trust the compiler heuristics to
make the right decision here.
The idea of eliminating common sub-expressions suggests that there _are_
common sub-expressions, which aren't affected by the function arguments.
This case is highly unusual in my experience. And I personally wouldn't
depend on a feature such as this to address that sort of a problem in my
codegen. I would just refactor the function a little bit to call the common
sub-expression ahead of time.

When the function is generated code (not hand written).


I'm not sue what you mean here?

 noninline_func(){ inline_func();}
>>>
>>>
>> Why? This is really overcomplicating a simple thing. And I'm not quite
>> sure
>> what you're suggesting this should do either. Are you saying the call tree
>> is flattened behind this proxy non-inline function?
>>
>
> No, I am saying that the one level mixin doesn't provide you with anything new.


It really does provide something new. It provides effectively, a type-safe implementation of something that may be used in place of C/C++ macros. I think that would be extremely useful in a variety of applications.

You already have that. It is sugar.
>

I don't already have it, otherwise I'd be making use of it. D has no control over the inliner. GDC/LDC offer attributes, but then it's really annoying that D has no mechanism to make use of compiler-specific attributes in a portable way (ie, attribute aliasing), so I can't make use of those without significantly interfering with my code.

I also don't think that suggestion of yours works. I suspect the compiler will see the outer function as a trivial wrapper which will fall within the compilers normal inline heuristics, and it will all inline anyway.