www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - pragma(inline, true) not very useful in its current state?

reply David Nadlinger <code klickverbot.at> writes:
Hi all,

I'm not even referring to the multitude of restrictions in the 
DMD frontend inliner here. When looking into the remaining 2.068 
test failures for LDC, I was surprised to find out that DMD only 
honors pragma(inline, true) when -inline is actually passed on 
the command line.

This seems to be completely against what many people I spoke to 
(including, of course, our resident Mr. 
Why-Can't-D-Be-More-Like-C++, Manu Evans) cite as one of the 
primary use cases for the feature, which is to force inlining of 
certain functions even in debug builds.

What were the reasons behind this decision?

  — David
Sep 24 2015
next sibling parent reply John Colvin <john.loughran.colvin gmail.com> writes:
On Thursday, 24 September 2015 at 15:47:45 UTC, David Nadlinger 
wrote:
 Hi all,

 I'm not even referring to the multitude of restrictions in the 
 DMD frontend inliner here. When looking into the remaining 
 2.068 test failures for LDC, I was surprised to find out that 
 DMD only honors pragma(inline, true) when -inline is actually 
 passed on the command line.

 This seems to be completely against what many people I spoke to 
 (including, of course, our resident Mr. 
 Why-Can't-D-Be-More-Like-C++, Manu Evans) cite as one of the 
 primary use cases for the feature, which is to force inlining 
 of certain functions even in debug builds.

 What were the reasons behind this decision?

  — David
Can't ldc and gdc just be sane and let dmd carry on being (ahem) odd.
Sep 24 2015
parent Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 25 September 2015 at 04:10, John Colvin via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Thursday, 24 September 2015 at 15:47:45 UTC, David Nadlinger wrote:
 Hi all,

 I'm not even referring to the multitude of restrictions in the DMD
 frontend inliner here. When looking into the remaining 2.068 test failures
 for LDC, I was surprised to find out that DMD only honors pragma(inline,
 true) when -inline is actually passed on the command line.

 This seems to be completely against what many people I spoke to
 (including, of course, our resident Mr. Why-Can't-D-Be-More-Like-C++, Manu
 Evans) cite as one of the primary use cases for the feature, which is to
 force inlining of certain functions even in debug builds.

 What were the reasons behind this decision?

  — David
Can't ldc and gdc just be sane and let dmd carry on being (ahem) odd.
This. Please.
Sep 25 2015
prev sibling next sibling parent Jack Stouffer <jack jackstouffer.com> writes:
On Thursday, 24 September 2015 at 15:47:45 UTC, David Nadlinger 
wrote:
 which is to force inlining of certain functions even in debug 
 builds.
I don't understand what the problem is. Just pass -inline in your debug build.
Sep 24 2015
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 9/24/2015 8:47 AM, David Nadlinger wrote:
 What were the reasons behind this decision?
The trouble is the compiler does inlining as a top down traversal, whereas forcing inline with no -inline would be a bottom up thing. The compiler could always do the top down traversal, but it would make compilations slower, whether any force inlines exist or not.
Sep 24 2015
parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 24 Sep 2015 9:46 pm, "Walter Bright via Digitalmars-d" <
digitalmars-d puremagic.com> wrote:
 On 9/24/2015 8:47 AM, David Nadlinger wrote:
 What were the reasons behind this decision?
The trouble is the compiler does inlining as a top down traversal,
whereas forcing inline with no -inline would be a bottom up thing. The compiler could always do the top down traversal, but it would make compilations slower, whether any force inlines exist or not. Isn't this just a problem with dmd's inliner/inlining strategy? (Mixed in with its need for speed)
Sep 25 2015
prev sibling next sibling parent reply Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 25 September 2015 at 01:47, David Nadlinger via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 Hi all,

 [...]
 our resident Mr. Why-Can't-D-Be-More-Like-C++, Manu Evans
Bah, I'm not sure what this means. If you mean I advocate for things that are perfect how they are in C/C++, precedented by decades of use and millions of developers, remaining as people expect them to be... then yes. C++ didn't get *everything* wrong, otherwise D wouldn't be so much like C++ to begin with. __forceinline in C++ is exactly what people want here. The behaviour is useful, and well understood; compiler will always inline if possible, and warn if it can't. There's nothing wrong with C++ in this case, and I wish D would just be the same. I'm happy for DMD to not inline anything in debug if it's technically impossible due to compiler architecture, but it's not useful as an error, that just forces you to remove it from your code if you want it to compile. We don't have any tools in D at all to control whether attributes like inline should or shouldn't be present between different build configurations. We _really_ need attribute aliasing in some form, especially since LDC/GDC have compiler-specific attributes that DMD doesn't recognise.
Sep 25 2015
next sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 26-Sep-2015 07:27, Manu via Digitalmars-d wrote:
 On 25 September 2015 at 01:47, David Nadlinger via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 Hi all,

 [...]
 our resident Mr. Why-Can't-D-Be-More-Like-C++, Manu Evans
Bah, I'm not sure what this means. If you mean I advocate for things that are perfect how they are in C/C++,
 precedented by decades of use
 and millions of developers,
Technically millions could be wrong as easily as a single individual, in fact more likely so due to collective bias.
 remaining as people expect them to be...
 then yes.
 C++ didn't get *everything* wrong, otherwise D wouldn't be so much
 like C++ to begin with. __forceinline in C++ is exactly what people
 want here. The behaviour is useful, and well understood; compiler will
 always inline if possible, and warn if it can't. There's nothing wrong
 with C++ in this case, and I wish D would just be the same.
Agreed. -- Dmitry Olshansky
Sep 26 2015
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2015-09-26 06:27, Manu via Digitalmars-d wrote:

 We _really_ need attribute aliasing in
 some form, especially since LDC/GDC have compiler-specific attributes
 that DMD doesn't recognise.
I'm not sure how much this helps but can't you use a dummy UDA on DMD for the GDC/LDC attributes? -- /Jacob Carlborg
Sep 26 2015
parent reply Marco Leise <Marco.Leise gmx.de> writes:
Am Sat, 26 Sep 2015 12:21:15 +0200
schrieb Jacob Carlborg <doob me.com>:

 On 2015-09-26 06:27, Manu via Digitalmars-d wrote:
 
 We _really_ need attribute aliasing in
 some form, especially since LDC/GDC have compiler-specific attributes
 that DMD doesn't recognise.
I'm not sure how much this helps but can't you use a dummy UDA on DMD for the GDC/LDC attributes?
pragma(inline, true) void foo() gcc.attribute.attribute("forceinline") ldc.attribute.attribute("alwaysinline") safe pure nothrow nogc { // Ok, what did I want this to do again ... ? } Maybe the compiler devs can decide on more common syntax like a generic core.attribute or just use pragma for inlining, but extend it so that it offers more options: * no * force * flatten (And maybe an additional 'allow' that convinces the compiler that inlining is safe.) -- Marco
Sep 26 2015
next sibling parent Johannes Pfau <nospam example.com> writes:
Am Sat, 26 Sep 2015 18:42:03 +0200
schrieb Marco Leise <Marco.Leise gmx.de>:

 Am Sat, 26 Sep 2015 12:21:15 +0200
 schrieb Jacob Carlborg <doob me.com>:
 
 On 2015-09-26 06:27, Manu via Digitalmars-d wrote:
 
 We _really_ need attribute aliasing in
 some form, especially since LDC/GDC have compiler-specific
 attributes that DMD doesn't recognise.
I'm not sure how much this helps but can't you use a dummy UDA on DMD for the GDC/LDC attributes?
pragma(inline, true) void foo() gcc.attribute.attribute("forceinline") ldc.attribute.attribute("alwaysinline") safe pure nothrow nogc { // Ok, what did I want this to do again ... ? }
module myinline; static if(WhateverConditionIWant || SomeOtherCondition) { struct forceinline {} //no-op } else { version (GNU) { alias forceinline = gcc.attribute.attribute("forceinline"); } else version (LDC) { alias forceinline = ldc.attribute.attribute("alwaysinline"); } else version (DMD) { alias forceinline = pragma... //Damn, DMD! } } forceinline safe pure nothrow nogc foo() { }
 Maybe the compiler devs can decide on more common syntax like
 a generic core.attribute or just use pragma for inlining, but
 extend it so that it offers more options:
 
 * no
 * force
 * flatten
 (And maybe an additional 'allow' that convinces the compiler
  that inlining is safe.)
 
We proposed implementing a generic core.attribute for some time now but the DMD devs weren't very enthusiastic about this. If you ask me, we should get rid of pragmas wherever possible. UDAs do look better, are composable and just like pragmas do not pollute namespaces. ( mangle("foo") instead of pragma(mangle, "foo")... One thing missing though is UDAs for modules.
Sep 26 2015
prev sibling next sibling parent reply Artur Skawina via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 09/26/15 18:42, Marco Leise via Digitalmars-d wrote:
 Am Sat, 26 Sep 2015 12:21:15 +0200
 schrieb Jacob Carlborg <doob me.com>:
 
 On 2015-09-26 06:27, Manu via Digitalmars-d wrote:

 We _really_ need attribute aliasing in
 some form, especially since LDC/GDC have compiler-specific attributes
 that DMD doesn't recognise.
I'm not sure how much this helps but can't you use a dummy UDA on DMD for the GDC/LDC attributes?
pragma(inline, true) void foo() gcc.attribute.attribute("forceinline") ldc.attribute.attribute("alwaysinline") safe pure nothrow nogc { // Ok, what did I want this to do again ... ? }
It's more like: pragma(inline, true) void foo() inline safe pure nothrow nogc { // Ok, what did I want this to do again ... ? } where `inline` would be aliased to the right LDC/GDC attribute.
 Maybe the compiler devs can decide on more common syntax like
 a generic core.attribute or just use pragma for inlining, but
No, `pragma` can not be conditionally enabled or aliased. It does not work well in D, except in cases it's used to extend the language in a non-implementation-specific way. (C/C++ have the preprocessor, that's why it works there)
 extend it so that it offers more options:
 
 * no
 * force
 * flatten
 (And maybe an additional 'allow' that convinces the compiler
  that inlining is safe.)
`allow` is the default state and always safe; for the cases where it's /undesirable/, there is noinline. artur
Sep 26 2015
parent reply Marco Leise <Marco.Leise gmx.de> writes:
Am Sat, 26 Sep 2015 19:58:14 +0200
schrieb Artur Skawina via Digitalmars-d
<digitalmars-d puremagic.com>:

 `allow` is the default state and always safe; for the cases
 where it's /undesirable/, there is noinline.
 
 artur
No what I meant was when the compiler sees inline assembly or anything else it deems not safe to inline, you can convice it anyways. It is more like trusted on otherwise system functions. I just mentioned it so it is under consideration, as I have seen it in LLVM. -- Marco
Sep 27 2015
parent reply Artur Skawina via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 09/27/15 13:48, Marco Leise via Digitalmars-d wrote:
 Am Sat, 26 Sep 2015 19:58:14 +0200
 schrieb Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com>:
 
 `allow` is the default state and always safe; for the cases
 where it's /undesirable/, there is noinline.
No what I meant was when the compiler sees inline assembly or anything else it deems not safe to inline, you can convice it anyways. It is more like trusted on otherwise system functions. I just mentioned it so it is under consideration, as I have seen it in LLVM.
The problem with this would be that it would soon lead to a C-like mess -- a lot of function marked with `allow` just-in-case. Failure to inline is a compiler implementation problem, it shouldn't affect the language, which already has enough annotation noise. What would be the cases for `allow`, that are /not/ caused by compiler limitations? (dmd's legacy inline asm hack is not part of the language in practice, so that does not count) Also keep in mind that `noinline` will often not come alone, but be accompanied by other annotations like `noclone`. `noinline` often means that the functions identity matters, so you have to disable cross-function constant propagation etc too. It can all be done by bundling the attributes via alias, but the defaults must be sane, so that most code does not need annotations (for example: a templated function containing a mixin must not require inlinable clonable etc just because the mixed in code, that is not locally known, /might/ silently turn off inlining). artur
Sep 27 2015
parent Marco Leise <Marco.Leise gmx.de> writes:
Am Sun, 27 Sep 2015 16:48:21 +0200
schrieb Artur Skawina via Digitalmars-d
<digitalmars-d puremagic.com>:

 On 09/27/15 13:48, Marco Leise via Digitalmars-d wrote:
 Am Sat, 26 Sep 2015 19:58:14 +0200
 schrieb Artur Skawina via Digitalmars-d
 <digitalmars-d puremagic.com>:
 
 `allow` is the default state and always safe; for the cases
 where it's /undesirable/, there is noinline.
No what I meant was when the compiler sees inline assembly or anything else it deems not safe to inline, you can convice it anyways. It is more like trusted on otherwise system functions. I just mentioned it so it is under consideration, as I have seen it in LLVM.
The problem with this would be that it would soon lead to a C-like mess -- a lot of function marked with `allow` just-in-case. Failure to inline is a compiler implementation problem, it shouldn't affect the language, which already has enough annotation noise. What would be the cases for `allow`, that are /not/ caused by compiler limitations? (dmd's legacy inline asm hack is not part of the language in practice, so that does not count)
I have no idea, ask the LLVM team for more information. At least as I understood it would be a rare need. A stupid example would be alloca(). Functions that contain it are not inlined and that is not a compiler limitation. Now you might manipulate the stack pointer in asm and the compiler could stop inlining although you know it is safe. Something like that maybe.
 Also keep in mind that `noinline` will often not come alone,
 but be accompanied by other annotations like `noclone`.
 `noinline` often means that the functions identity matters,
 so you have to disable cross-function constant propagation
 etc too. It can all be done by bundling the attributes via
 alias, but the defaults must be sane, so that most code
 does not need annotations (for example: a templated function
 containing a mixin must not require  inlinable  clonable  etc
 just because the mixed in code, that is not locally known,
 /might/ silently turn off inlining).
 
 artur
In general I don't see inlining attributes much used at all because of the sane defaults we already have and the aggressive inlining performed by modern compilers. For me the option to build a release version and mark a single function "noinline" is interesting to see it as a separate item in a profiler or to set a breakpoint on it in a debugger and see all the assembly as one block. But first we need to agree on names in core.attribute. I find the GCC names pretty good. "force" is stronger than "always". Unless, to support DMD, we want a more fuzzy thing that doesn't really enforce anything unless -inline is active. -- Marco
Sep 27 2015
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2015-09-26 18:42, Marco Leise wrote:

 Maybe the compiler devs can decide on more common syntax like
 a generic core.attribute or just use pragma for inlining, but
 extend it so that it offers more options:
Yeah, we already have core.attribute. Now they just have to agree on the name :) -- /Jacob Carlborg
Sep 26 2015
parent Marco Leise <Marco.Leise gmx.de> writes:
Am Sat, 26 Sep 2015 21:11:07 +0200
schrieb Jacob Carlborg <doob me.com>:

 On 2015-09-26 18:42, Marco Leise wrote:
 
 Maybe the compiler devs can decide on more common syntax like
 a generic core.attribute or just use pragma for inlining, but
 extend it so that it offers more options:
Yeah, we already have core.attribute. Now they just have to agree on the name :)
*nods* So ... agree already guys. Guys?! -- Marco
Sep 27 2015
prev sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 26 Sep 2015 6:27 am, "Manu via Digitalmars-d" <
digitalmars-d puremagic.com> wrote:
 On 25 September 2015 at 01:47, David Nadlinger via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 Hi all,

 [...]
 our resident Mr. Why-Can't-D-Be-More-Like-C++, Manu Evans
Bah, I'm not sure what this means. If you mean I advocate for things that are perfect how they are in C/C++, precedented by decades of use and millions of developers, remaining as people expect them to be... then yes. C++ didn't get *everything* wrong, otherwise D wouldn't be so much like C++ to begin with. __forceinline in C++ is exactly what people want here. The behaviour is useful, and well understood; compiler will always inline if possible, and warn if it can't. There's nothing wrong with C++ in this case, and I wish D would just be the same. I'm happy for DMD to not inline anything in debug if it's technically impossible due to compiler architecture, but it's not useful as an error, that just forces you to remove it from your code if you want it to compile.
Not sure of oddness of dmd, but there should be only a few reasons why a function is uninlinable, all of them being low level things such as inline assembly, calls to alloca. Assuming that the function body is available at compile-time too. ;-)
Sep 25 2015