Bots, Bureaucrats, Interface administrators, smwadministrator, smwcurator, smweditor, Administrators
2,558
edits
Timo.stripf (talk | contribs) No edit summary |
Timo.stripf (talk | contribs) |
||
| Line 39: | Line 39: | ||
It’s worth noting that in C++ programs, GCC automatically treats any function defined ''inside a class definition'' as inline (this is mandated by the C++ standard). GCC will attempt to inline such functions even without the <code>inline</code> keyword <ref name="gcc"/>. Also, if a function is declared <code>inline</code>, GCC still emits a standalone function definition for it ''unless'' it can prove that every call was inlined and no external reference is needed. This means an inline function might not actually be inlined everywhere, but the one-definition rule is respected by outputting one copy if needed (you can prevent outputting unused inline functions with the <code>-fkeep-inline-functions</code> flag, for instance <ref name="gcc"/>). | It’s worth noting that in C++ programs, GCC automatically treats any function defined ''inside a class definition'' as inline (this is mandated by the C++ standard). GCC will attempt to inline such functions even without the <code>inline</code> keyword <ref name="gcc"/>. Also, if a function is declared <code>inline</code>, GCC still emits a standalone function definition for it ''unless'' it can prove that every call was inlined and no external reference is needed. This means an inline function might not actually be inlined everywhere, but the one-definition rule is respected by outputting one copy if needed (you can prevent outputting unused inline functions with the <code>-fkeep-inline-functions</code> flag, for instance <ref name="gcc"/>). | ||
=== Clang/LLVM === | === Clang/LLVM === | ||
| Line 49: | Line 47: | ||
One difference to mention is that Clang’s diagnostics and reports can help understand inlining decisions. For example, Clang has flags like <code>-Rpass=inline</code> and <code>-Rpass-missed=inline</code> which, at compile time, can report which functions were inlined or not inlined and why. This can be useful to tune code for inlining with Clang. The heuristics themselves (function size thresholds, etc.) are continuously refined in LLVM’s development, but generally align with the goal of balancing performance gain against code growth. | One difference to mention is that Clang’s diagnostics and reports can help understand inlining decisions. For example, Clang has flags like <code>-Rpass=inline</code> and <code>-Rpass-missed=inline</code> which, at compile time, can report which functions were inlined or not inlined and why. This can be useful to tune code for inlining with Clang. The heuristics themselves (function size thresholds, etc.) are continuously refined in LLVM’s development, but generally align with the goal of balancing performance gain against code growth. | ||
=== MSVC (Microsoft Visual C++) === | === MSVC (Microsoft Visual C++) === | ||
| Line 56: | Line 52: | ||
MSVC’s approach to inlining in C++ relies on both language keywords and compiler settings. In MSVC, the <code>inline</code> keyword (or its synonym <code>__inline</code>) is also a hint to suggest that a function be inlined. However, as with other compilers, this is not a command – MSVC will perform inline expansion only if it judges the optimization to be worthwhile <ref name="ms_inline">Inline Functions (C++) | Microsoft Learn https://learn.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=msvc-170</ref>. The MSVC compiler evaluates the size and complexity of the function, and certain usage patterns, before deciding to inline. It will not inline functions in some cases (for example, if a function’s address is taken or if the function is too large or has varargs, it won’t be inlined). By default, MSVC’s optimization settings control how much inlining is done: | MSVC’s approach to inlining in C++ relies on both language keywords and compiler settings. In MSVC, the <code>inline</code> keyword (or its synonym <code>__inline</code>) is also a hint to suggest that a function be inlined. However, as with other compilers, this is not a command – MSVC will perform inline expansion only if it judges the optimization to be worthwhile <ref name="ms_inline">Inline Functions (C++) | Microsoft Learn https://learn.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=msvc-170</ref>. The MSVC compiler evaluates the size and complexity of the function, and certain usage patterns, before deciding to inline. It will not inline functions in some cases (for example, if a function’s address is taken or if the function is too large or has varargs, it won’t be inlined). By default, MSVC’s optimization settings control how much inlining is done: | ||
* '''<code>/Ob0</code>''' – ''No inlining''. This is the default in debug builds (<code>/Od</code>). The compiler does not inline any function, regardless of the inline keyword. This setting is used to make debugging easier and ensure the binary closely follows the written code structure. | * '''<code>/Ob0</code>''' – ''No inlining''. This is the default in debug builds (<code>/Od</code>). The compiler does not inline any function, regardless of the inline keyword. This setting is used to make debugging easier and ensure the binary closely follows the written code structure. | ||
* '''<code>/Ob1</code>''' – ''Inline only if marked inline''. With this setting, the compiler will expand functions inline '''only''' if they are explicitly declared <code>inline</code> (or <code>__inline</code> or <code>__forceinline</code>), or if they are C++ member functions defined inside class definitions <ref name="ms_ob">/Ob (Inline Function Expansion) | Microsoft Learn https://learn.microsoft.com/en-us/cpp/build/reference/ob-inline-function-expansion?view=msvc-170</ref>. In other words, it respects the inline hints but does not consider other functions for inlining. This is a moderate level used when some inlining is desired but not aggressive auto-inlining. | * '''<code>/Ob1</code>''' – ''Inline only if marked inline''. With this setting, the compiler will expand functions inline '''only''' if they are explicitly declared <code>inline</code> (or <code>__inline</code> or <code>__forceinline</code>), or if they are C++ member functions defined inside class definitions <ref name="ms_ob">/Ob (Inline Function Expansion) | Microsoft Learn https://learn.microsoft.com/en-us/cpp/build/reference/ob-inline-function-expansion?view=msvc-170</ref>. In other words, it respects the inline hints but does not consider other functions for inlining. This is a moderate level used when some inlining is desired but not aggressive auto-inlining. | ||
* '''<code>/Ob2</code>''' – ''Auto-inlining''. This is the default in release builds (<code>/O1</code> or <code>/O2</code>) and it allows MSVC to inline any function it wants to, at its discretion <ref name="ms_ob">/Ob (Inline Function Expansion) | Microsoft Learn https://learn.microsoft.com/en-us/cpp/build/reference/ob-inline-function-expansion?view=msvc-170</ref>. The compiler will inline functions marked inline or <code>__forceinline</code>, and '''may also inline other functions''' even if they aren’t marked, whenever its heuristics indicate there is a benefit and it’s safe to do so <ref name="ms_ob">/Ob (Inline Function Expansion) | Microsoft Learn https://learn.microsoft.com/en-us/cpp/build/reference/ob-inline-function-expansion?view=msvc-170</ref>. Essentially, <code>/Ob2</code> gives the optimizer freedom to do inlining beyond the programmer’s annotations (similar to GCC’s <code>-finline-functions</code>). Most MSVC optimized builds use this level by default. | * '''<code>/Ob2</code>''' – ''Auto-inlining''. This is the default in release builds (<code>/O1</code> or <code>/O2</code>) and it allows MSVC to inline any function it wants to, at its discretion <ref name="ms_ob">/Ob (Inline Function Expansion) | Microsoft Learn https://learn.microsoft.com/en-us/cpp/build/reference/ob-inline-function-expansion?view=msvc-170</ref>. The compiler will inline functions marked inline or <code>__forceinline</code>, and '''may also inline other functions''' even if they aren’t marked, whenever its heuristics indicate there is a benefit and it’s safe to do so <ref name="ms_ob">/Ob (Inline Function Expansion) | Microsoft Learn https://learn.microsoft.com/en-us/cpp/build/reference/ob-inline-function-expansion?view=msvc-170</ref>. Essentially, <code>/Ob2</code> gives the optimizer freedom to do inlining beyond the programmer’s annotations (similar to GCC’s <code>-finline-functions</code>). Most MSVC optimized builds use this level by default. | ||
* '''<code>/Ob3</code>''' – ''Aggressive inlining''. Introduced in Visual Studio 2019, <code>/Ob3</code> is an undocumented setting that goes beyond <code>/Ob2</code> in aggressiveness <ref name="ms_ob">/Ob (Inline Function Expansion) | Microsoft Learn https://learn.microsoft.com/en-us/cpp/build/reference/ob-inline-function-expansion?view=msvc-170</ref>. It uses the same inlining criteria but increases the compiler’s willingness to inline. This might inline even larger functions or more call sites than <code>/Ob2</code> would. (It’s not available directly in the IDE project settings; it must be set manually, and it’s considered experimental.) | * '''<code>/Ob3</code>''' – ''Aggressive inlining''. Introduced in Visual Studio 2019, <code>/Ob3</code> is an undocumented setting that goes beyond <code>/Ob2</code> in aggressiveness <ref name="ms_ob">/Ob (Inline Function Expansion) | Microsoft Learn https://learn.microsoft.com/en-us/cpp/build/reference/ob-inline-function-expansion?view=msvc-170</ref>. It uses the same inlining criteria but increases the compiler’s willingness to inline. This might inline even larger functions or more call sites than <code>/Ob2</code> would. (It’s not available directly in the IDE project settings; it must be set manually, and it’s considered experimental.) | ||
| Line 69: | Line 65: | ||
Additionally, MSVC supports '''Link-Time Code Generation (LTCG)''', enabled with <code>/GL</code> (compile for whole-program optimization) and <code>/LTCG</code> (link with whole-program optimization). When using LTCG, MSVC’s linker can inline functions across module boundaries (object files) because it has access to the entire program’s intermediate code. This is analogous to GCC/Clang’s LTO. In fact, MSVC will perform cross-module inlining under LTCG even for functions not marked inline, if profitable <ref name="ms_inline">Inline Functions (C++) | Microsoft Learn https://learn.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=msvc-170</ref>. This allows inlining of functions from libraries or other translation units that would not be visible to the compiler otherwise. | Additionally, MSVC supports '''Link-Time Code Generation (LTCG)''', enabled with <code>/GL</code> (compile for whole-program optimization) and <code>/LTCG</code> (link with whole-program optimization). When using LTCG, MSVC’s linker can inline functions across module boundaries (object files) because it has access to the entire program’s intermediate code. This is analogous to GCC/Clang’s LTO. In fact, MSVC will perform cross-module inlining under LTCG even for functions not marked inline, if profitable <ref name="ms_inline">Inline Functions (C++) | Microsoft Learn https://learn.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=msvc-170</ref>. This allows inlining of functions from libraries or other translation units that would not be visible to the compiler otherwise. | ||
== Code Examples == | == Code Examples == | ||
edits