June 12, 2020
On Fri, Jun 12, 2020 at 11:51 AM Manu <turkeyman@gmail.com> wrote:

> On Fri, Jun 12, 2020 at 8:20 AM Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>
>> On 6/11/2020 8:42 AM, kinke wrote:
>> > My interest in this wasn't triggered by wanting to enforce particular
>> functions
>> > to be emitted into each referencing CU, but by
>> > a) the current emission scheme requiring LTO in order to inline suited
>> little
>> > templated functions when compiling static libs in one go,
>> > b) being able to use linkonce_odr instead of weak_odr linkage for
>> template
>> > stuff, meaning potentially less work for the linker, and potentially
>> quite a bit
>> > less work for the optimizer. Compiling an optimized dub (a single
>> object file)
>> > with LDC using -linkonce-templates reduces the total compile+optimize
>> times by
>> > roughly 25%, simply because LLVM inlines most little template stuff and
>> can then
>> > discard the unused linkonce_odr functions early in the process, without uselessly optimizing them to death (as it currently cannot discard it,
>> as other
>> > libraries/objects might depend on some template instances as mentioned
>> earlier).
>>
>> A library consists of two parts:
>>
>> 1. the "header" file
>> 2. the binary to link with, which may be absent
>>
>> Take some care in what goes in 1, what goes in 2, and you'll be fine.
>>
>> For example, consider core.checkedint. The functions in it are all
>> templates so
>> that they can be used with -betterC which doesn't link with druntime.
>> It's a
>> classic "header only" library. It works fine.
>>
>
> We're not talking about templates.
>

This is another one of those cases is really bizarre resistance to what
seems like a blindingly obvious thing.
Can you please explain why you feel opposed to this, and why our existing
solution, which is 'weird' by all accounts, and satisfies ZERO of the goals
assigned to inline is preferable?
The existing implementation is inline is a COMPLETELY useless thing. If you
can't see where I'm coming from in this thread, then I suggest we remove it
completely.
It's existence solves zero problems, and does actual damage to D by
existing, because people try it and find that it's broken, and then they're
confused and/or lose a little confidence in D.
I mean that seriously; if you deny there's a problem and refuse to fix
this, then I seriously encourage you to deprecate and remove pragma(inline)
from the language. It's worse than nothing.


June 12, 2020
On Friday, 12 June 2020 at 01:55:26 UTC, Manu wrote:
> Can you please explain why you feel opposed to this, and why our existing
> solution, which is 'weird' by all accounts, and satisfies ZERO of the goals
> assigned to inline is preferable?

You won't get a direct answer to this. You can't have a debate if he never presents an argument. Or rather in business, you don't have to deal with a problem if you don't acknowledge there is a problem, management 101.


June 12, 2020
On 6/8/20 2:14 AM, Manu wrote:
> In C/C++, inline says that a function will be emit to the binary only when it is called, and the function is marked with internal linkage (it is not visible to the linker from the symbol table)

By my recollection this is not the case for C++, at all.

* "inline" does NOT change a function's linkage in C++. You may have inline functions with internal linkage (static inline) or (default) external linkage. This is important because e.g. defining a static variable in an extern inline function will have the same address in all calls to the function.

* "inline" in C++ is entirely advisory, meaning a conforming implementation is entirely free to simply ignore it, save it for duplicate symbols (which are ignored for inline functions and cause errors for non-inline functions).

* In fact, all major C++ implementations routinely ignore "inline" in favor of their own heuristics, which are usually better. However, they are not always better, and that in turn has generated demands for an "I really mean inline" directive. Compiler implementers responded to that demand with a trickle of additional nonstandard language features:

- MSVC has __inline, __forceinline, and __declspec(noinline): https://docs.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=vs-2019. As a funny aside, __inline and __forceinline sometimes do not inline, and __declspec(noinline) functions are sometimes inlined.

- g++ and clang have __inline__, __attribute__((always_inline)), and __attribute__ ((noinline)): https://stackoverflow.com/questions/8381293/how-do-i-force-gcc-to-inline-a-function. Needless to say, __inline__ and __attribute__((always_inline)) do not always inline, and __attribute__ ((noinline)) does not always prevent inlining.

If the above is correct, a D language feature dedicated to inlining should do the following:

* Always emit the function body in the .di file if ever asked to generate it.

* Never complain about duplicate symbols if an inline function has duplicate definitions.

Then compilers can decide on specific inlining strategies using the language feature as a hint.

D does ALL of the above already for templates, so this is not a difficult feature to implement. In fact we use this technique (e.g. in druntime) by spelling inline as "()". Consider:

int func(int) { ... body ... }

Let's make this inline:

int func()(int) { ... body ... }

Done.

In D there's one additional implication of body availability - the function is eligible for CTFE. I think any adjustment to the extant inline pragma needs to make this a top-level consideration.
June 12, 2020
On 6/8/20 10:09 AM, Manu wrote:
> It's not a hint at all. It's a mechanical tool; it marks symbols with internal linkage, and it also doesn't emit them if it's never referenced.
> The compiler may not choose to ignore that behaviour, it's absolutely necessary, and very important.

Manu, your understanding of inlining is very wrong. Maybe you refer to C's __inline__ (with which I'm not familiar)?
June 12, 2020
On 6/8/20 10:59 AM, Steven Schveighoffer wrote:
> I think Manu's description is accurate

Most of Manu's description is flat wrong or confuses behavior of specific implementations with standard guarantees.
June 12, 2020
On Friday, 12 June 2020 at 13:27:23 UTC, Andrei Alexandrescu wrote:
> On 6/8/20 10:09 AM, Manu wrote:
>> It's not a hint at all. It's a mechanical tool; it marks symbols with internal linkage, and it also doesn't emit them if it's never referenced.
>> The compiler may not choose to ignore that behaviour, it's absolutely necessary, and very important.
>
> Manu, your understanding of inlining is very wrong. Maybe you refer to C's __inline__ (with which I'm not familiar)?

Since C99 it's as you've described above. Before that it was implementation defined as it was not part of the language but compiler dependent.
The behaviour was very different between gcc 3 and gcc 4, after that it was as you described above.
I came up with a complex scheme of macros to be able to handle inlining efficiently, and portably for our project that was (and still is) pure C.

The issue with inlining for a project like ours, is that we have a set of libraries and binaries that a linked against these libraries. Some of the apps have to be linked to static versions of the libs, other to .so version of them, this is 3 variants, optimized for deployment, debug with a lot of diagnistics and profiling.

This requires that all inline functions have their code emitted exactly once in exactly one library, regardless if the caller inlined it or not. Not as easy as people think.


June 12, 2020
On 6/12/20 9:29 AM, Andrei Alexandrescu wrote:
> On 6/8/20 10:59 AM, Steven Schveighoffer wrote:
>> I think Manu's description is accurate
> 
> Most of Manu's description is flat wrong or confuses behavior of specific implementations with standard guarantees.

Yeah, I read the inline documentation for C++, and it's quite different from what Manu said, and from my experience (this was a long time ago). I think the code I had dealt with that used inline was not correct.

-Steve
June 12, 2020
On 6/12/20 9:57 AM, Patrick Schluter wrote:
> On Friday, 12 June 2020 at 13:27:23 UTC, Andrei Alexandrescu wrote:
>> On 6/8/20 10:09 AM, Manu wrote:
>>> It's not a hint at all. It's a mechanical tool; it marks symbols with internal linkage, and it also doesn't emit them if it's never referenced.
>>> The compiler may not choose to ignore that behaviour, it's absolutely necessary, and very important.
>>
>> Manu, your understanding of inlining is very wrong. Maybe you refer to C's __inline__ (with which I'm not familiar)?
> 
> Since C99 it's as you've described above. Before that it was implementation defined as it was not part of the language but compiler dependent.
> The behaviour was very different between gcc 3 and gcc 4, after that it was as you described above.
> I came up with a complex scheme of macros to be able to handle inlining efficiently, and portably for our project that was (and still is) pure C.
> 
> The issue with inlining for a project like ours, is that we have a set of libraries and binaries that a linked against these libraries. Some of the apps have to be linked to static versions of the libs, other to .so version of them, this is 3 variants, optimized for deployment, debug with a lot of diagnistics and profiling.
> 
> This requires that all inline functions have their code emitted exactly once in exactly one library, regardless if the caller inlined it or not. Not as easy as people think.

Yes, such batteries of macros are the norm in large projects. I'm familiar with those in the HHVM project: https://github.com/facebook/hhvm/blob/a0ca1ffa9a3d690ad57feadf27031886f8eeb2f7/hphp/util/portability.h

June 12, 2020
On 6/11/20 11:01 PM, Avrina wrote:
> On Friday, 12 June 2020 at 01:55:26 UTC, Manu wrote:
>> Can you please explain why you feel opposed to this, and why our existing
>> solution, which is 'weird' by all accounts, and satisfies ZERO of the goals
>> assigned to inline is preferable?
> 
> You won't get a direct answer to this. You can't have a debate if he never presents an argument. Or rather in business, you don't have to deal with a problem if you don't acknowledge there is a problem, management 101.

It seems to me the problem lies with the way the problem is formulated.


June 12, 2020
On 6/11/20 9:55 PM, Manu wrote:
> This is another one of those cases is really bizarre resistance to what seems like a blindingly obvious thing.

After perusing this entire thread, I must confess I'm unclear of what the request is. I'm sure it's something reasonable, and that the misunderstanding is mine.

Can someone summarize what the matter is and what the motivation behind it is?

Also, starting from the pragma definition: https://dlang.org/spec/pragma.html#inline. It's very thin! There's definitely a need to improve it. It would need at least enough detail to describe what the linkage of inline function is.