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:
- 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.
- 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