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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to