Do compilers take inline as a hint?
If you’ve spent any time in C or C++ communities online, you’ve probably seen someone say this:
inline
used to be a hint for compilers to inline the definition, but no compilers actually take that into account any more.
You shouldn’t believe everything you see on the internet.
Of course, inline
has mandatory effects on linkage and whatnot, but this post is only interested in whether or not compilers might change the decision to inline a function or not based on whether you write inline
in the declaration.
However, the point of this article isn’t to give you good rules for when to use inline
, because as much as I like to debate technical minutiae, your compiler will likely be a better judge than you anyway. Instead I want to show that if you want to know how compilers or standard libraries implement things, you can just go look! It might be daunting the first time, but getting a knack for finding things in large code bases and understanding your tools can pay off. I’ll be diving into the codebases for Clang and GCC to see how they handle inlining hints and hopefully convince you that you can do the same for questions which you have about your tools.
Clang
Let’s do this bottom-up. Clang is a compiler frontend for LLVM, which means that it takes C-family languages, translates them to LLVM Intermediate Representation, and LLVM handles generating assembly/binaries from that. So we can dig around in LLVM to see if we can find code which deals with inlining. I armed myself with a text editor and grep
and found the following code in llvm/lib/Analysis/InlineCost.cpp
:
By just looking at this code without knowledge of all the other functions, we won’t be able to totally understand what it’s doing. But there’s certainly some information we can gleam here:
So now we know that LLVM takes the presence of an inlinehint
attribute into account in its inlining cost model. But does Clang produce that attribute? Let’s look for that attribute in the Clang sources:
The above code from clang/lib/CodeGen/CodeGenModule.cpp
shows Clang setting the inlinehint
attribute. It will also possibly mark declarations as noinline
if inline
was not supplied (depending on compiler flags). Now we can look for code which affects isInlineSpecified
:
The above snippets show the functions which set and retrieve whether something was specified as inline, and the code in the parser which calls the setter.
So now we know that Clang propagates the presence of the inline
keyword through to LLVM using the inlinehint
attribute, and that LLVM takes this into account in its cost model for inlining. Our detective work has been successful!
GCC
How about GCC? The source for GCC is a fair bit less accessible than that of LLVM, but we can still make an attempt. After a bit of searching, I found that the DECL_DECLARED_INLINE_P
macro seemed to be used lots of places which were relevant. So we can look for where that’s set:
We can then look for uses of this macro which seem to affect the behaviour of the inliner. Here are a few:
That’s some evidence that the keyword is being taken into account. If we want to get a better idea of all of the effects, then we now have a starting point from which to conduct our expectations.
Conclusion
I hope I’ve managed to convince you of two things:
- Some modern compilers still take inline hints into account.
- If you want to understand how your compiler works and it’s open source, you can just go and look.
If you’re actually going to try and optimize your code using inline
then Do The Right Thing And Measure It1. See what your compiler actually generates. Profile your code to make sure you’re opmitizing something that needs optimizing. Don’t guess.
-
DTRTAMI (dee-tee-arr-tamee) kinda has a ring to it. ↩
Let me know what you think of this article on twitter @TartanLlama or leave a comment below!