[clang] [clang][FMV] Direct-call FMV callees from FMV callers (PR #80093)

Alexandros Lamprineas via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 31 06:06:33 PDT 2024


labrinea wrote:

@erichkeane while I agree that Clang might not be the best place for such an optimization, I have some concerns about implementing it in LLVM:
* We cannot distinguish a FMV resolver from any other ifunc resolver.
* There is no information at the LLVM IR level about function versions or which resolver they are associated with. 
* We cannot use target-features to determine version priority since this information is encoded via front-end features in the TargetParser. We can only rely on the resolver's basic block layout under the assumption that predecessor basic blocks correspond to versions of higher priority than successor basic blocks. This is fragile and unreliable:
```
void discoverResolvedIFuncsInPriorityOrder(GlobalIFunc *IFunc) {
  DenseMap<GlobalIFunc *, SmallVector<Function *>> ResolvedIFuncs;

  std::function<void(Value *)> visitValue = [&](Value *V) {
    if (auto *Func = dyn_cast<Function>(V)) {
      ResolvedIFuncs[IFunc].push_back(Func);
    } else if (auto *Sel = dyn_cast<SelectInst>(V)) {
      visitValue(Sel->getTrueValue());
      visitValue(Sel->getFalseValue());
    } else if (auto *Phi = dyn_cast<PHINode>(V)) {
      for (unsigned I = 0, E = Phi->getNumIncomingValues(); I != E; ++I)
        visitValue(Phi->getIncomingValue(I));
    }
  };

  for (BasicBlock &BB : *IFunc->getResolverFunction())
    if (auto *Ret = dyn_cast_or_null<ReturnInst>(BB.getTerminator()))
      visitValue(Ret->getReturnValue());
  // discard default
  if (!ResolvedIFuncs[IFunc].empty())
    ResolvedIFuncs[IFunc].pop_back();
}
```

https://github.com/llvm/llvm-project/pull/80093


More information about the cfe-commits mailing list