always_inline and noinline attributes

With plain gcc I assume?

Yes.

I was thinking of doing this stripping in the tool generating the LLVM module,
so opt (or perhaps clang?). It should always be able to just throw away the
always_inline global and the function should then be just a normal function.

I'm not sure if having such a strip-always_inline option is needed, at least
not if the default is to preserve always_inline information.

What I'm worried is - if always_inline info is not stripped away the LTO inliner will obey always_inline. In this case, it is not appropriate to say "LTO may not inline functions, marked as always_inline", across translation unit".

I was proposing
this option, because IIRC someone proposed or implied throwing away the
always_inline info by default.

Devang, if I see this right, you agree with me that the combination of 2) and
b) are the "right" ones?

Yes. Otherwise, if we want to restrict enforcing always_inline across translation unit then we need to encode "always_inline in module XYZ" in LLVM IR, not just "always_inline".

Hi Devang,

What I'm worried is - if always_inline info is not stripped away the LTO
inliner will obey always_inline. In this case, it is not appropriate to say
"LTO may not inline functions, marked as always_inline", across translation
unit".

Ah, I see your point now. It's not easy to guarantee that all LLVM IR
producing tools will strip always_inline, because they might not know the next
step is linking, for example.

Gr.

Matthijs

Hi Chris,

I think that Chris is really in favour of option b) here, because "inlining
can sometimes change semantics". However, I still don't really understand what
kind of cases we are talking about. Chris, could you give an example? Also, is
this changing of semantics specific to always_inline? From what you wrote, I
would assume that this changing of semantics can happen with any inline, so
you shouldn't be doing any inlining at all at link time. Nor at optimization
time, for that matter, so I'm probably missing an essential point here :slight_smile:

I did mean in favour of option a) here, actually :slight_smile:

Gr.

Matthijs

I haven't been following the full thread, but Matthijs asked me to opine :).

I think there are two equally reasonable approaches:

1) always_inline only affects the "front-end inliner" and gets stripped out by that inliner. This means it would not survive to LTO (if run). This would be extremely compatible with GCC.

2) always_inline persists in the IR and any inliner pass would inline any direct calls to always_inline functions whenever possible.

I don't have a strong opinion on which approach is taken,

-Chris

Hi Devang,

1) always_inline only affects the "front-end inliner" and gets stripped out
by that inliner. This means it would not survive to LTO (if run). This
would be extremely compatible with GCC.

2) always_inline persists in the IR and any inliner pass would inline any
direct calls to always_inline functions whenever possible.

I don't have a strong opinion on which approach is taken,

I think both of us agree on going for option 2)? You once said you would write
a proposal on how to implement this? Does that offer still stand? I'm afraid I
won't be able to invest too much time in this, currently.

Gr.

Matthijs

We discussed this at length. I've done some work on this front in llvm and llvm-gcc. Now,

1) always_inline and noinline attributes are encoded in llvm IR as function notes.
2) llvm-gcc encodes these attribute in llvm IR
3) The standard LLVM inliner respects these notes.
4) A new special purpose inliner (AlwaysInliner), that handles only functions that are marked as always_inline, is available.
5) llvm-gcc inserts AlwaysInliner pass in the pipeline if
         A) Regular inliner is not inserted in the pipeline
         B) AND, at least one always_inline function is seen

Hi Devang,

cool to see the Function notes working. Now, only clang needs to be converted,
because I don't think you have been working on that?

Gr.

Matthijs

Hi Devang,

cool to see the Function notes working. Now, only clang needs to be converted,
because I don't think you have been working on that?

yes.