================
@@ -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
----------------
w2yehia wrote:

"internal" in comment doesn't match code (that uses privatee linkage)

https://github.com/llvm/llvm-project/pull/153049
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to