[llvm] [llvm][GlobalOpt] Optimize statically resolvable IFuncs (PR #80606)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 5 05:30:24 PST 2024
================
@@ -2404,6 +2405,42 @@ static bool OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) {
return Changed;
}
+static Function *hasSideeffectFreeStaticResolution(GlobalIFunc &IF) {
+ Function *Resolver = IF.getResolverFunction();
+ if (!Resolver)
+ return nullptr;
+
+ Function *Callee = nullptr;
+ for (BasicBlock &BB : *Resolver) {
+ if (any_of(BB, [](Instruction &I) { return I.mayHaveSideEffects(); }))
+ return nullptr;
+
+ if (auto *Ret = dyn_cast<ReturnInst>(BB.getTerminator()))
+ if (auto *F = dyn_cast<Function>(Ret->getReturnValue())) {
+ if (!Callee)
+ Callee = F;
+ if (F != Callee)
+ return nullptr;
+ }
+ }
+
+ return Callee;
+}
+
+/// Find IFuncs that have resolvers that always point at the same statically
+/// known callee, and replace their callers with a direct call.
+static bool OptimizeStaticIFuncs(Module &M) {
+ bool Changed = false;
+ for (GlobalIFunc &IF : M.ifuncs())
+ if (Function *Callee = hasSideeffectFreeStaticResolution(IF))
+ if (!IF.use_empty()) {
+ IF.replaceAllUsesWith(Callee);
+ NumIFuncsResolved++;
----------------
nikic wrote:
That depends on stuff like linkage and comdats. Probably the deleteIfDead() will handle it correctly?
https://github.com/llvm/llvm-project/pull/80606
More information about the llvm-commits
mailing list