[clang] [compiler-rt] [llvm] [AIX] Implement the ifunc attribute. (PR #153049)
Wael Yehia via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 10 08:31:51 PDT 2025
================
@@ -0,0 +1,123 @@
+//===-- PPCPrepareIFuncsOnAIX.cpp - Prepare for ifunc lowering in codegen ===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass generates...
+//
+//===----------------------------------------------------------------------===//
+
+#include "PPC.h"
+#include "PPCSubtarget.h"
+#include "PPCTargetMachine.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include <cassert>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "ppc-prep-ifunc-aix"
+
+STATISTIC(NumIFuncs, "Number of IFuncs prepared");
+
+namespace {
+class PPCPrepareIFuncsOnAIX : public ModulePass {
+public:
+ static char ID;
+
+ PPCPrepareIFuncsOnAIX() : ModulePass(ID) {}
+
+ bool runOnModule(Module &M) override;
+
+ StringRef getPassName() const override {
+ return "PPC Prepare for AIX IFunc lowering";
+ }
+};
+} // namespace
+
+char PPCPrepareIFuncsOnAIX::ID = 0;
+
+INITIALIZE_PASS(PPCPrepareIFuncsOnAIX, DEBUG_TYPE,
+ "PPC Prepare for AIX IFunc lowering", false, false)
+
+ModulePass *llvm::createPPCPrepareIFuncsOnAIXPass() {
+ return new PPCPrepareIFuncsOnAIX();
+}
+
+// @foo = ifunc i32 (), ptr @foo_resolver, !associated !0
+// define ptr @foo_resolver() {
+// ...
+//
+// %struct.IFUNC_PAIR = type { ptr, ptr }
+// @update_foo = internal global %struct.IFUNC_PAIR { ptr @foo, ptr
+// @foo_resolver }, section "ifunc_sec", align 8, !associated !1 declare void
+// @__init_ifuncs(...)
+//
+// !0 = !{ptr @update_foo}
+// !1 = !{ptr @__init_ifuncs}
+bool PPCPrepareIFuncsOnAIX::runOnModule(Module &M) {
+ if (M.ifuncs().empty())
+ return false;
+
+ const DataLayout &DL = M.getDataLayout();
+ LLVMContext &Ctx = M.getContext();
+ auto *PtrTy = PointerType::getUnqual(Ctx);
+ StringRef IFuncUpdatePrefix = "__update_";
+ StringRef IFuncUpdateSectionName = "ifunc_sec";
+ StructType *IFuncPairType = StructType::get(PtrTy, PtrTy);
+
+ StringRef IFuncConstructorName = "__init_ifuncs";
+ auto *IFuncConstructorFnType =
+ FunctionType::get(Type::getVoidTy(Ctx), {}, /*isVarArg=*/false);
+ auto *IFuncConstructorDecl =
+ Function::Create(IFuncConstructorFnType, GlobalValue::ExternalLinkage,
+ IFuncConstructorName, M);
+
+ for (GlobalIFunc &IFunc : M.ifuncs()) {
+ LLVM_DEBUG(dbgs() << "doing ifunc " << IFunc.getName() << "\n");
+ // @update_foo = internal global { ptr @foo, ptr @foo_resolver }, section
+ // "ifunc_sec", align 8
+ std::string Name = (Twine(IFuncUpdatePrefix) + IFunc.getName()).str();
+ auto *GV = new GlobalVariable(M, IFuncPairType, /*isConstant*/ false,
+ GlobalValue::PrivateLinkage, nullptr, Name);
+ GV->setAlignment(DL.getPointerPrefAlignment());
+ GV->setVisibility(GlobalValue::DefaultVisibility);
----------------
w2yehia wrote:
this might not be necessary if it's set by default
https://github.com/llvm/llvm-project/pull/153049
More information about the llvm-commits
mailing list