question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

An annotation to either prevent or force inlining of a function

See original GitHub issue

We’ve been using GCC in the simple mode for compiling React for a few months, and are really happy with its heuristics. However, recently I’ve been noticing a minor pain point.

Problem

In some cases, as library authors we want to have more control over whether a function should be inlined or not. In particular, there are two scenarios:

  1. Some functions are in a very hot path, and we have determined that not inlining them would hurt the runtime performance. Usually at this point we just inline them manually in the code. However, that often produces duplicate code that is hard to work with. Ideally, we’d love to have a way to tell GCC that it has to either inline a function or fail the build (if it’s impossible). This way we know that we won’t regress on this particular function.

  2. There is an opposite problem as well. Sometimes we split a function into several to have tighter control over the argument types. For example, if some path is very hot, and we need to ensure a function is called with monomorphic arguments. However, GCC can break these optimizations by inlining the separated function (and thus preventing engines from optimizing that code due to deopts). For this use case, we’d like to have a way to tell GCC to not inline a function, even if the resulting code size will be larger.

Prior Art

The other GCC 🙂

Proposal

New @inline annotation forces inlining

/** @inline */
function someHelper() {
  // ...
}

// We want to fail the build if these couldn't be inlined.
someHelper();
someHelper();

This forces the function to be inlined even if the code size becomes bigger. If it can’t be inlined, the build fails.

Alternative possible naming: @always-inline, @force-inline.

New @noinline annotation prevents inlining

/** @noinline */
function doSomethingWithString(stringValue) {
  // ...
}

/** @noinline */
function doSomethingWithNumber(numberValue) {
  // ...
}

function doSomething(mixedValue) {
  // It is important that these calls never get inlined
  if (typeof mixedValue === 'string') {
    doSomethingWithString(mixedValue);
  } else if (typeof mixedValue === 'number') {
    doSomethingWithNumber(mixedValue);
  }
}

This forces a function to never be considered for inlining, even if there is a size win.

Alternative possible naming: @never-inline, @prevent-inline.

Other hint formats?

I don’t have a strong opinion about how to supply these hints. A comment, a JSDoc annotation, special function name, etc, would all work for me. Please let me know if this is something you would consider!

Current Workarounds

In case anyone’s curious, I’ve thought a bit about how to achieve this today.

Forcing inlining

There’s no way to force inlining, but we could plausibly adopt a special naming convention (e.g. *Inline). We already have a special build where we disable the renaming pass (#2707) so we could analyze the bundle, and fail the build if any *Inline function still exists. This wouldn’t force GCC to inline it, but at least we’d know if it was inlined but then started bailing.

Preventing inlining

This file might contain some hints. For example attaching function to an object would prevent inlining that function.

Of course it would be nice to have an official solution for this, as both options are hacky and incomplete.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:9
  • Comments:15 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
ChadKillingsworthcommented, Jan 22, 2019

Since the @noinline annotation exists, I’m closing this issue.

1reaction
brad4dcommented, Dec 21, 2017

I’ve now done enough work for @noinline to work for $jscomp.polyfill, and that was my primary motivation to work on it. There are a few more *Inline*.java classes I haven’t touched, so there are probably cases where it still gets ignored. I volunteer to be the primary person to handle issues related to it being ignored and PRs to fix them, but I don’t plan to work on it further for now other than that.

Read more comments on GitHub >

github_iconTop Results From Across the Web

c++ - Is it possible to force a function not to be inlined?
In Visual Studio 2010, __declspec(noinline) tells the compiler to never inline a particular member function, for instance: class X { __declspec(noinline) ...
Read more >
Method Inlining in the JVM - Baeldung
Basically, inlining is a way to optimize compiled source code at runtime by replacing the invocations of the most often executed methods with ......
Read more >
Inline Function - an overview | ScienceDirect Topics
When a programmer defines a function with the inline keyword (or defines it inside a class definition, thereby making it inline by default),...
Read more >
Inline - Scala 3 - EPFL
The Config object contains a definition of the inline value logging . This means that logging is treated as a constant value, equivalent...
Read more >
Inline functions | Kotlin
If an inline function has no inlinable function parameters and no reified type parameters, the compiler will issue a warning, since inlining ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found