February 03, 2015
On Tuesday, 3 February 2015 at 13:34:23 UTC, Steven Schveighoffer wrote:
> On 2/3/15 7:39 AM, Manu via Digitalmars-d wrote:
>> On 3 February 2015 at 01:16, John Colvin via Digitalmars-d

> To be honest, I thought the debate was more about whether force inline should fail to compile if inlining cannot happen, with Walter thinking it should still compile. But maybe I don't remember it well enough.

But this is exactly the difference between force_inline and please_inline.

I think the fastest and easiest way to move forward right now on the issue is with a pragma instead of attirbutes.

The former is not as disruptive and could be easily re-defined or rolled back if too much trouble.

As a personal opinion, I think we (well, generic "we") should be a bit a more liberal when it comes to experimenting with pragmas.

I would prefer better parameters for this pragma instead of "true" and "false".

Maybe "cold" and "hot" or "warning", "error" (as action to be taken by the compiler if the inlining is impossible).

Anyway, I feel that the pragma shall provide a way to cancel compilation if the inline clause cannot be satisfied, but for those functions that are specifically marked as such (see "error" above).

February 03, 2015
On Tue, Feb 03, 2015 at 09:53:37PM +1100, Daniel Murphy via Digitalmars-d wrote:
> "Walter Bright"  wrote in message news:maq7f1$2hka$1@digitalmars.com...
[...]
> >It's like the old joke where a captain is asked by a colonel how he'd get a flagpole raised. The captain replied with a detailed set of instructions. The colonel said wrong answer, the correct response would be for the captain to say: "Sergeant, get that flag pole raised!"
[...]
> We have inline assembler because sometimes being explicit is what's needed.  I would consider using forceinline in the same situations where inline assembly is a viable option.  eg interfacing with hardware, computation kernels

Computation colonels? :-D


T

-- 
Having a smoking section in a restaurant is like having a peeing section in a swimming pool. -- Edward Burr
February 03, 2015
On 2/3/15 12:17 AM, Johannes Pfau wrote:
> Well I see that you're not even considering adding a simple pragma to
> help embedded programming. In that case I see absolutely no reason to
> continue working on that. You guys say "we lack expertise so we cannot
> help directly" and you're in "search of champions" for these areas. But
> whenever somebody working with D on embedded systems actually comes up
> with an issue related to embedded programming and propose solutions you
> simply dismiss it. Often even based on vague statements like "that's
> not a common task".
> http://wiki.dlang.org/Vision/2015H1

I think we need to work on better inlining. Which format (pragma vs. attribute etc) is just tactical detail. Clearly there needs to be "best effort" and "won't compile unless it inlines" directives.

Johannes, please let us know whether this is everything needed to float your boat. I'm unclear whether you believe "volatile" data is needed or not. If it's not, we're good; if it is, you need to redo your argument because it was poorly conducted.

> pragma(address) could be trivially implemented now and I still think
> it's a logical extension of the language, whereas global property ref
> functions for this purpose are just hacks. Till D will have full inline
> control rust will probably already have all the market share in these
> areas. At least I'm not willing to invest any more effort into this.

No need to get agitated over this. We're all on the same boat.

Rust also uses intrinsics for volatile loads and stores: http://doc.rust-lang.org/core/intrinsics/. It does have a way to force inlining recommended to use with caution: https://mail.mozilla.org/pipermail/rust-dev/2013-May/004272.html


Andrei
February 03, 2015
Am Tue, 03 Feb 2015 07:09:10 -0800
schrieb Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>:

> On 2/3/15 12:17 AM, Johannes Pfau wrote:
> > Well I see that you're not even considering adding a simple pragma to help embedded programming. In that case I see absolutely no reason to continue working on that. You guys say "we lack expertise so we cannot help directly" and you're in "search of champions" for these areas. But whenever somebody working with D on embedded systems actually comes up with an issue related to embedded programming and propose solutions you simply dismiss it. Often even based on vague statements like "that's not a common task". http://wiki.dlang.org/Vision/2015H1
> 
> I think we need to work on better inlining. Which format (pragma vs. attribute etc) is just tactical detail. Clearly there needs to be "best effort" and "won't compile unless it inlines" directives.
> 

I wasn't part of that discussion and I don't want to be part of it. In the end I don't care how exactly force inline is implemented, as long as it is implemented.

> Johannes, please let us know whether this is everything needed to float your boat. I'm unclear whether you believe "volatile" data is needed or not. If it's not, we're good; if it is, you need to redo your argument because it was poorly conducted.
> 

I was actually not arguing for any kind of 'volatile data' or replacing volatileLoad/Store (in this discussion).

> > pragma(address) could be trivially implemented now and I still think it's a logical extension of the language, whereas global property ref functions for this purpose are just hacks. Till D will have full inline control rust will probably already have all the market share in these areas. At least I'm not willing to invest any more effort into this.
> 
> No need to get agitated over this. We're all on the same boat.
> 
> Rust also uses intrinsics for volatile loads and stores: http://doc.rust-lang.org/core/intrinsics/. It does have a way to force inlining recommended to use with caution: https://mail.mozilla.org/pipermail/rust-dev/2013-May/004272.html
> 
> 
> Andrei

That's a misunderstanding. I don't want to replace
volatileLoad/Store intrinsics or any other kind of volatile access.
pragma(address) is something completely different. I posted a full
example here: https://forum.dlang.org/post/maotpd$1ape$1@digitalmars.com

Basically it adds this feature:
extern __gshared int x; //extern variable, default mangled name
pragma(mangle, "noop") extern __gshared int y; //specify name
pragma(address, 0x05) extern __gshared int z; //specify address
=====================

It doesn't make z volatile or add any other magic. It simply declares that z is a variable at a _fixed absolute_ location (compile time constant). I even posted a link to a full working implementation, 80 loc.

It's very useful on embedded systems where you have data at fixed locations. Why not access this data like any other extern data using variables?

It does allow some nice patterns when _combined_ with volatileLoad/Store
but this seems to only confuse people. Here's a reduced example for
that:
http://pastebin.com/RGhKdm9i
__builtin_volatile_load <=> volatileLoad
February 03, 2015
On Tuesday, 3 February 2015 at 08:31:24 UTC, Walter Bright wrote:
> On 2/2/2015 8:36 PM, Daniel Murphy wrote:
>> The user can modify the code to allow it to be inlined.  There are a huge number
>> of constructs that cause dmd's inliner to completely give up.  If a function
>> _must_ be inlined, the compiler needs to give an error if it fails.
>
> A separate message with a pragmatic difficulty with your suggestion.
>
> Different compilers will have different inlining capabilities. Different versions of the same compiler may behave differently. This means that sometimes a user may get a compilation failure, sometimes not. It's highly brittle.

This is _exactly_ why error message is needed. Considering
compiler differences and with all inlining bugs in mind it is
impossible for developer to reason if certain code will be
inlined and rely on it in any fashion.

For most programs it is mere inconvenience. For something
low-level like embedded programming it can become a deal-breaker
making the difference between working and broken program.

> So enter the workaround code. Different compilers and different versions will require different workaround code. Is this really reasonable for users to put up with?

Yes, and this is very good as it will ensure that feature won't
be abused in "normal" programs because it is so hard to deal
with. But in barebone world it is very common to develop
exclusively for one specific compiler version so it won't be a
problem.

> And will they really want to be running the workaround code when they upgrade the compiler and now it could have inlined it?

No, they will really want to not use this feature. Because it has
different niche.

To sum it up, I don't think your proposal is bad on its own - it
simply tries to solve different problems than ones being asked.
Manu problem is a different problem than Johannes has - but you
seem to consider those identical.

Why can't we simply have 3 cases for pragma?

pragma(inline, never);  // not even with -inline
pragma(inline, always); // even without -inline
pragma(inline, force);  // error if can't inline
February 03, 2015
On 2015-02-03 05:05, Daniel Murphy wrote:
> "Walter Bright" wrote in message news:maq8ao$2idu$1@digitalmars.com...
>
>> Yup. I understand the concern that a compiler would opt out of
>> inlining those if it legally could, but I just cannot see that
>> happening in reality. Modern compilers have been inlining for 25
>> years now, and they're not likely to just stop doing it.
>
> No, the problem is that the code might accidentally contain a
> construct that is not inlineable. The user will expect it to be
> inlined, but the compiler will silently fail.
>
> eg
>
> void myWrapperFunc()
> {
> callSomeFunc(999, 123, "something");
> }
>
> This function will not be inlined if callSomeFunc has a default
> arugment that calls alloca, for example. If a hidden failure becomes
> a compiler error, the user can trivially correct the problem.

+1

i am a simple user writing mostly programs to crunch my scientific data. i'd like to move my C code to D. but i deal with GBs of data that i have to sieve through many times. in C, i have lots of repeating integer stunts in the inner loop that must be inlined. i used macros for this. if i cannot mark small helper function in the inner loop so that they are guaranteed to be inlined, i am screwed. i would have to copy and paste lots of code, making the result worse than the C code.

i am fine with a compilation error when force_inclining fails, if it comes with a brief explanation of why so i get an idea of how to fix it and make it work. i am not writing or reading assembler and i don't plan to. but i also don't want to be in doubt about the inlining. i just want to get stuff done in a convenient way. if D offers no way other than copy&pasting code blocks i cannot use it for my work. sadly.

/det
February 03, 2015
On 2/3/15 9:29 AM, Dicebot wrote:
> On Tuesday, 3 February 2015 at 08:31:24 UTC, Walter Bright wrote:
>> On 2/2/2015 8:36 PM, Daniel Murphy wrote:
>>> The user can modify the code to allow it to be inlined.  There are a
>>> huge number
>>> of constructs that cause dmd's inliner to completely give up. If a
>>> function
>>> _must_ be inlined, the compiler needs to give an error if it fails.
>>
>> A separate message with a pragmatic difficulty with your suggestion.
>>
>> Different compilers will have different inlining capabilities.
>> Different versions of the same compiler may behave differently. This
>> means that sometimes a user may get a compilation failure, sometimes
>> not. It's highly brittle.
>
> This is _exactly_ why error message is needed.

I think the best route here - and the most in-the-spirit-of-D - is to provide introspection on whether a function is being inlined or not. Then we can always have in libraries:

bool uart(ubyte b)
{
    static assert(__traits(inlined),
      "Inlining of uart() must be supported.");
    ...
}


Andrei
February 03, 2015
On Tuesday, 3 February 2015 at 18:16:20 UTC, Andrei Alexandrescu wrote:
>     static assert(__traits(inlined),
>       "Inlining of uart() must be supported.");

This is unworkable:

1. You want to be able to turn off inlining for debugging.

2. You would have to wait with evaluating static_assert until after optimization since the optimizer could decide to inline it at a late stage.

3. You should be able to take the address of the function.

Walter is right when saying that for D inlining is an optimization and should not be part of the semantics (but you could have an enforced hint). Querying optimization effects at compile time creates dependencies that may lead to computations that don't resolve.

February 03, 2015
On Tuesday, 3 February 2015 at 18:16:20 UTC, Andrei Alexandrescu wrote:
> I think the best route here - and the most in-the-spirit-of-D - is to provide introspection on whether a function is being inlined or not. Then we can always have in libraries:
>
> bool uart(ubyte b)
> {
>     static assert(__traits(inlined),
>       "Inlining of uart() must be supported.");
>     ...
> }

That is tempting path but I feel that it creates new issues for little benefit.

Consider:

bool uart(ubyte b)
{
    static if(__traits(inlined))
    {
        // do something that can't be inlined
    }
    else
    {
        // do something that can be inlined
    }
}

And http://wiki.dlang.org/DIP56 is still needed for other purposes - so why create new brittle abstractions when it is possible to use existing dumb ones?
February 03, 2015
On 2015-02-03 at 18:53, captaindet wrote:
> i am a simple user writing mostly programs to crunch my scientific data. i'd like to move my C code to D. but i deal with GBs of data that i have to sieve through many times. in C, i have lots of repeating integer stunts in the inner loop that must be inlined. i used macros for this. if i cannot mark small helper function in the inner loop so that they are guaranteed to be inlined, i am screwed. i would have to copy and paste lots of code, making the result worse than the C code.

Or you'd have to use mixins as you would use C macros.
But that's bending over backwards compared to inlining.