[Inline][FMV] Inlining multi-versioned functions

Hi, the inliner doesn’t attempt to inline calls to ifunc functions because in general the resolver function can be user defined (available to examine but can have arbitrary logic).
However, multi-versioned functions (via the target, target_clones or target_version GNU attributes) have a compiler generated resolver.
So code like the following can in theory be inlined with some analysis:

__attribute__((target_clones("default","arch=x86-64-v2")))
int foo(int a) { return a & a-1; }

__attribute__((target("arch=x86-64-v2")))
int bar(int b) { return foo(b + 1); }

=>

int bar.arch_x86-64-v2.0(int b) { 
  // inlined body of foo.arch_x86-64-v2.0(b+1)
}

I can think of multiple ways this can be done:

  1. without changing clang codegen, the inliner can examine foo’s resolver to get a list of it’s clones, and use bar’s TTI to check if one of those candidates is guaranteed to be selected at runtime.
  2. add more info in the IR, to make it easier and catch more cases where we can fold the resolver call to one candidate.

I want to get people’s thoughts if this is legal and whether there’s interest in implementing such a transformation.
Thank you.

@echristo FYI

So there is some support for inlining, but you are correct that you’ll need to be able to check for compatible target features (or a strict superset) in order to inline due to our need to codegen at the function rather than basic block or instruction level. A couple of the backends have support for being able to do this that hooks into the inliner and cost.

I’m away from sources at the moment so a vague description is the best I’ve got, but I’m happy to work through this with you and make sure it’s inlining what it (and you) need. :slight_smile:

Thanks!

-eric

Thanks Eric. Given that there’s light at the end of the tunnel, I’ll work on this in the next few weeks. Will post an update here.

Full disclosure: I’m enabling target_clones on AIX (PowerPC) now, which requires some work due to lack of linker support for ifunc and we want this to be fast. Afterwards, I will address the inlining issue.
Thank you for your time.

FYI I have filed an issue last year: `target_clone` attribute blocks function inlining · Issue #94949 · llvm/llvm-project · GitHub.
Candidate patch: [FMV][Clang][CodeGen] Resolves corresponding callee for multi-versioning callers by dtcxzyw · Pull Request #107822 · llvm/llvm-project · GitHub

1 Like

See also: [FMV] Multi Versioned Inlining · Issue #71714 · llvm/llvm-project · GitHub

cc: @labrinea

2 Likes