[llvm] Analysis: Move LibcallLoweringInfo from CodeGen to Analysis (PR #210322)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 17 06:11:08 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-selectiondag

@llvm/pr-subscribers-debuginfo

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>

Middle end passes need to be able to reason about library call
availability and potentially emit them without depending on codegen.
TargetLibraryInfo already lives in Analysis, and this is a step towards
the eventual merger. For now this is a mostly mechanical move, type erasing
the reference to TargetSubtargetInfo.

The per-subtarget customization (TargetSubtargetInfo::initLibcallLoweringInfo)
is inverted into a caller-supplied function_ref, so the Analysis types carry
no CodeGen/TargetSubtargetInfo reference. The module map is keyed on an opaque
erased pointer. CodeGen continues looking up based on the subtarget.

It is not yet in a state where it is usable from middle end passes; that will come
later. In principle we should be able to write arbitrary rules based on a function's
ABI attributes for which calls can be used.

Co-authored-by: Claude (Claude Opus 4.8) <noreply@<!-- -->anthropic.com>

---

Patch is 24.69 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/210322.diff


17 Files Affected:

- (added) llvm/include/llvm/Analysis/LibcallLoweringInfo.h (+160) 
- (modified) llvm/include/llvm/CodeGen/LibcallLoweringInfo.h (+13-114) 
- (modified) llvm/lib/Analysis/CMakeLists.txt (+1) 
- (added) llvm/lib/Analysis/LibcallLoweringInfo.cpp (+49) 
- (modified) llvm/lib/CodeGen/AtomicExpandPass.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/DwarfEHPrepare.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/ExpandIRInsts.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/LibcallLoweringInfo.cpp (+23-35) 
- (modified) llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp (+2-2) 
- (modified) llvm/lib/CodeGen/SafeStack.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/StackProtector.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/TargetLoweringBase.cpp (+3-1) 
- (modified) llvm/lib/Passes/PassBuilder.cpp (+1) 
- (modified) llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp (+1-1) 
- (modified) llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp (+1-1) 
- (modified) llvm/unittests/CodeGen/GlobalISel/GISelMITest.h (+4-1) 


``````````diff
diff --git a/llvm/include/llvm/Analysis/LibcallLoweringInfo.h b/llvm/include/llvm/Analysis/LibcallLoweringInfo.h
new file mode 100644
index 0000000000000..efd8a5a13016b
--- /dev/null
+++ b/llvm/include/llvm/Analysis/LibcallLoweringInfo.h
@@ -0,0 +1,160 @@
+//===- LibcallLoweringInfo.h ------------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Tracks which library function implementations to use for depending on a
+// calling context (e.g., which library function a particular subtarget should
+// use).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LIBCALLLOWERINGINFO_H
+#define LLVM_ANALYSIS_LIBCALLLOWERINGINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/Analysis/RuntimeLibcallInfo.h"
+#include "llvm/IR/RuntimeLibcalls.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+/// Tracks which library functions to use for a particular subtarget or
+/// function.
+class LibcallLoweringInfo {
+private:
+  const RTLIB::RuntimeLibcallsInfo &RTLCI;
+  /// Stores the implementation choice for each libcall.
+  RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
+      RTLIB::Unsupported};
+
+public:
+  /// Callback applying the caller's context-specific (e.g. subtarget) libcall
+  /// rules on top of the module-level defaults.
+  using ApplyContextRulesFn = function_ref<void(LibcallLoweringInfo &)>;
+
+  /// Construct the lowering info from the module-level \p RTLCI, seeding the
+  /// default implementation for every available libcall, then applying the
+  /// optional \p ApplyContextRules callback for the caller's context-specific
+  /// libcall rules.
+  LLVM_ABI LibcallLoweringInfo(const RTLIB::RuntimeLibcallsInfo &RTLCI,
+                               ApplyContextRulesFn ApplyContextRules = {});
+
+  const RTLIB::RuntimeLibcallsInfo &getRuntimeLibcallsInfo() const {
+    return RTLCI;
+  }
+
+  /// Get the libcall routine name for the specified libcall.
+  // FIXME: This should be removed. Only LibcallImpl should have a name.
+  const char *getLibcallName(RTLIB::Libcall Call) const {
+    // FIXME: Return StringRef
+    return RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LibcallImpls[Call])
+        .data();
+  }
+
+  /// Return the lowering's selection of implementation call for \p Call
+  RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
+    return LibcallImpls[Call];
+  }
+
+  /// Rename the default libcall routine name for the specified libcall.
+  void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
+    LibcallImpls[Call] = Impl;
+  }
+
+  // FIXME: Remove this wrapper in favor of directly using
+  // getLibcallImplCallingConv
+  CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
+    return RTLCI.LibcallImplCallingConvs[LibcallImpls[Call]];
+  }
+
+  /// Get the CallingConv that should be used for the specified libcall.
+  CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
+    return RTLCI.LibcallImplCallingConvs[Call];
+  }
+
+  /// Return a function impl compatible with RTLIB::MEMCPY, or
+  /// RTLIB::Unsupported if fully unsupported.
+  RTLIB::LibcallImpl getMemcpyImpl() const {
+    RTLIB::LibcallImpl Memcpy = getLibcallImpl(RTLIB::MEMCPY);
+    if (Memcpy == RTLIB::Unsupported) {
+      // Fallback to memmove if memcpy isn't available.
+      return getLibcallImpl(RTLIB::MEMMOVE);
+    }
+
+    return Memcpy;
+  }
+};
+
+/// Records a mapping from an opaque lowering context to its
+/// LibcallLoweringInfo.
+///
+/// The context is identified by an opaque key (which should be
+/// TargetSubtargetInfo*)
+class ModuleLibcallLoweringInfo {
+private:
+  using LibcallLoweringMap = DenseMap<const void *, LibcallLoweringInfo>;
+  mutable LibcallLoweringMap LoweringMap;
+  const RTLIB::RuntimeLibcallsInfo *RTLCI = nullptr;
+
+public:
+  ModuleLibcallLoweringInfo() = default;
+  ModuleLibcallLoweringInfo(RTLIB::RuntimeLibcallsInfo &RTLCI)
+      : RTLCI(&RTLCI) {}
+
+  void init(const RTLIB::RuntimeLibcallsInfo *RT) { RTLCI = RT; }
+
+  void clear() {
+    RTLCI = nullptr;
+    LoweringMap.clear();
+  }
+
+  operator bool() const { return RTLCI != nullptr; }
+
+  LLVM_ABI bool invalidate(Module &, const PreservedAnalyses &,
+                           ModuleAnalysisManager::Invalidator &);
+
+  /// Return the LibcallLoweringInfo for the context identified by \p Key,
+  /// creating it (via \p ApplyContextRules) on first request. \p Key should be
+  /// TargetSubtargetInfo*.
+  template <typename KeyT>
+  const LibcallLoweringInfo &getLibcallLowering(
+      const KeyT *Key,
+      LibcallLoweringInfo::ApplyContextRulesFn ApplyContextRules = {}) const {
+    return getLibcallLoweringForKey(static_cast<const void *>(Key),
+                                    ApplyContextRules);
+  }
+
+private:
+  const LibcallLoweringInfo &getLibcallLoweringForKey(
+      const void *Key,
+      LibcallLoweringInfo::ApplyContextRulesFn ApplyContextRules) const {
+    auto It = LoweringMap.find(Key);
+    if (It != LoweringMap.end())
+      return It->second;
+    return LoweringMap.try_emplace(Key, *RTLCI, ApplyContextRules)
+        .first->second;
+  }
+};
+
+class LibcallLoweringModuleAnalysis
+    : public AnalysisInfoMixin<LibcallLoweringModuleAnalysis> {
+private:
+  friend AnalysisInfoMixin<LibcallLoweringModuleAnalysis>;
+  LLVM_ABI static AnalysisKey Key;
+
+  ModuleLibcallLoweringInfo LibcallLoweringMap;
+
+public:
+  using Result = ModuleLibcallLoweringInfo;
+
+  LLVM_ABI Result run(Module &M, ModuleAnalysisManager &);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_LIBCALLLOWERINGINFO_H
diff --git a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
index 6adf669b10ab2..437627045611e 100644
--- a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
+++ b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
@@ -5,122 +5,27 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+//
+// Legacy-pass-manager wrapper around the Analysis-layer libcall lowering info,
+// which is aware of TargetSubtargetInfo.
+//
+//===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CODEGEN_LIBCALLLOWERINGINFO_H
 #define LLVM_CODEGEN_LIBCALLLOWERINGINFO_H
 
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Analysis/RuntimeLibcallInfo.h"
-#include "llvm/IR/RuntimeLibcalls.h"
+#include "llvm/Analysis/LibcallLoweringInfo.h"
 #include "llvm/Pass.h"
 
 namespace llvm {
 class RuntimeLibraryInfoWrapper;
 class TargetSubtargetInfo;
-class TargetMachine;
-
-/// Tracks which library functions to use for a particular subtarget.
-class LibcallLoweringInfo {
-private:
-  const RTLIB::RuntimeLibcallsInfo &RTLCI;
-  /// Stores the implementation choice for each each libcall.
-  RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
-      RTLIB::Unsupported};
-
-public:
-  LLVM_ABI LibcallLoweringInfo(const RTLIB::RuntimeLibcallsInfo &RTLCI,
-                               const TargetSubtargetInfo &Subtarget);
-
-  const RTLIB::RuntimeLibcallsInfo &getRuntimeLibcallsInfo() const {
-    return RTLCI;
-  }
-
-  /// Get the libcall routine name for the specified libcall.
-  // FIXME: This should be removed. Only LibcallImpl should have a name.
-  const char *getLibcallName(RTLIB::Libcall Call) const {
-    // FIXME: Return StringRef
-    return RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LibcallImpls[Call])
-        .data();
-  }
-
-  /// Return the lowering's selection of implementation call for \p Call
-  RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
-    return LibcallImpls[Call];
-  }
-
-  /// Rename the default libcall routine name for the specified libcall.
-  void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
-    LibcallImpls[Call] = Impl;
-  }
-
-  // FIXME: Remove this wrapper in favor of directly using
-  // getLibcallImplCallingConv
-  CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
-    return RTLCI.LibcallImplCallingConvs[LibcallImpls[Call]];
-  }
-
-  /// Get the CallingConv that should be used for the specified libcall.
-  CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
-    return RTLCI.LibcallImplCallingConvs[Call];
-  }
-
-  /// Return a function impl compatible with RTLIB::MEMCPY, or
-  /// RTLIB::Unsupported if fully unsupported.
-  RTLIB::LibcallImpl getMemcpyImpl() const {
-    RTLIB::LibcallImpl Memcpy = getLibcallImpl(RTLIB::MEMCPY);
-    if (Memcpy == RTLIB::Unsupported) {
-      // Fallback to memmove if memcpy isn't available.
-      return getLibcallImpl(RTLIB::MEMMOVE);
-    }
-
-    return Memcpy;
-  }
-};
 
-/// Record a mapping from subtarget to LibcallLoweringInfo.
-class ModuleLibcallLoweringInfo {
-private:
-  using LibcallLoweringMap =
-      DenseMap<const TargetSubtargetInfo *, LibcallLoweringInfo>;
-  mutable LibcallLoweringMap LoweringMap;
-  const RTLIB::RuntimeLibcallsInfo *RTLCI = nullptr;
-
-public:
-  ModuleLibcallLoweringInfo() = default;
-  ModuleLibcallLoweringInfo(RTLIB::RuntimeLibcallsInfo &RTLCI)
-      : RTLCI(&RTLCI) {}
-
-  void init(const RTLIB::RuntimeLibcallsInfo *RT) { RTLCI = RT; }
-
-  void clear() {
-    RTLCI = nullptr;
-    LoweringMap.clear();
-  }
-
-  operator bool() const { return RTLCI != nullptr; }
-
-  LLVM_ABI bool invalidate(Module &, const PreservedAnalyses &,
-                           ModuleAnalysisManager::Invalidator &);
-
-  const LibcallLoweringInfo &
-  getLibcallLowering(const TargetSubtargetInfo &Subtarget) const {
-    return LoweringMap.try_emplace(&Subtarget, *RTLCI, Subtarget).first->second;
-  }
-};
-
-class LibcallLoweringModuleAnalysis
-    : public AnalysisInfoMixin<LibcallLoweringModuleAnalysis> {
-private:
-  friend AnalysisInfoMixin<LibcallLoweringModuleAnalysis>;
-  LLVM_ABI static AnalysisKey Key;
-
-  ModuleLibcallLoweringInfo LibcallLoweringMap;
-
-public:
-  using Result = ModuleLibcallLoweringInfo;
-
-  LLVM_ABI Result run(Module &M, ModuleAnalysisManager &);
-};
+/// Resolve the LibcallLoweringInfo for \p Subtarget from the module-level \p
+/// ModuleInfo, applying the subtarget's libcall overrides.
+LLVM_ABI const LibcallLoweringInfo &
+getLibcallLowering(const ModuleLibcallLoweringInfo &ModuleInfo,
+                   const TargetSubtargetInfo &Subtarget);
 
 class LLVM_ABI LibcallLoweringInfoWrapper : public ImmutablePass {
   ModuleLibcallLoweringInfo Result;
@@ -131,15 +36,9 @@ class LLVM_ABI LibcallLoweringInfoWrapper : public ImmutablePass {
   LibcallLoweringInfoWrapper();
 
   const LibcallLoweringInfo &
-  getLibcallLowering(const Module &M, const TargetSubtargetInfo &Subtarget) {
-    return getResult(M).getLibcallLowering(Subtarget);
-  }
+  getLibcallLowering(const Module &M, const TargetSubtargetInfo &Subtarget);
 
-  const ModuleLibcallLoweringInfo &getResult(const Module &M) {
-    if (!Result)
-      Result.init(&RuntimeLibcallsWrapper->getRTLCI(M));
-    return Result;
-  }
+  const ModuleLibcallLoweringInfo &getResult(const Module &M);
 
   void initializePass() override;
   void getAnalysisUsage(AnalysisUsage &AU) const override;
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index f3586c66cb056..6c3996ea8d885 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -103,6 +103,7 @@ add_llvm_component_library(LLVMAnalysis
   LazyBlockFrequencyInfo.cpp
   LazyCallGraph.cpp
   LazyValueInfo.cpp
+  LibcallLoweringInfo.cpp
   Lint.cpp
   Loads.cpp
   Local.cpp
diff --git a/llvm/lib/Analysis/LibcallLoweringInfo.cpp b/llvm/lib/Analysis/LibcallLoweringInfo.cpp
new file mode 100644
index 0000000000000..95b3b0fce6a8d
--- /dev/null
+++ b/llvm/lib/Analysis/LibcallLoweringInfo.cpp
@@ -0,0 +1,49 @@
+//===- LibcallLoweringInfo.cpp - Runtime libcall lowering info ------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/LibcallLoweringInfo.h"
+#include "llvm/Analysis/RuntimeLibcallInfo.h"
+
+using namespace llvm;
+
+LibcallLoweringInfo::LibcallLoweringInfo(
+    const RTLIB::RuntimeLibcallsInfo &RTLCI,
+    ApplyContextRulesFn ApplyContextRules)
+    : RTLCI(RTLCI) {
+  // TODO: This should be generated with lowering predicates, and assert the
+  // call is available.
+  for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {
+    if (RTLCI.isAvailable(Impl)) {
+      RTLIB::Libcall LC = RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(Impl);
+      // FIXME: Hack, assume the first available libcall wins.
+      if (LibcallImpls[LC] == RTLIB::Unsupported)
+        LibcallImpls[LC] = Impl;
+    }
+  }
+
+  // Apply the caller's context-specific (e.g. subtarget) libcall rules.
+  if (ApplyContextRules)
+    ApplyContextRules(*this);
+}
+
+AnalysisKey LibcallLoweringModuleAnalysis::Key;
+
+bool ModuleLibcallLoweringInfo::invalidate(
+    Module &, const PreservedAnalyses &PA,
+    ModuleAnalysisManager::Invalidator &) {
+  // Passes that change the runtime libcall set must explicitly invalidate this
+  // pass.
+  auto PAC = PA.getChecker<LibcallLoweringModuleAnalysis>();
+  return !PAC.preservedWhenStateless();
+}
+
+ModuleLibcallLoweringInfo
+LibcallLoweringModuleAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {
+  LibcallLoweringMap.init(&MAM.getResult<RuntimeLibraryAnalysis>(M));
+  return LibcallLoweringMap;
+}
diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp b/llvm/lib/CodeGen/AtomicExpandPass.cpp
index 8f75462250f82..a2e8e859faa17 100644
--- a/llvm/lib/CodeGen/AtomicExpandPass.cpp
+++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp
@@ -461,7 +461,7 @@ bool AtomicExpandImpl::run(Function &F,
   if (!Subtarget->enableAtomicExpand())
     return false;
   TLI = Subtarget->getTargetLowering();
-  LibcallLowering = &LibcallResult.getLibcallLowering(*Subtarget);
+  LibcallLowering = &getLibcallLowering(LibcallResult, *Subtarget);
   DL = &F.getDataLayout();
 
   bool MadeChange = false;
diff --git a/llvm/lib/CodeGen/DwarfEHPrepare.cpp b/llvm/lib/CodeGen/DwarfEHPrepare.cpp
index f8627727154da..5fa590a88c436 100644
--- a/llvm/lib/CodeGen/DwarfEHPrepare.cpp
+++ b/llvm/lib/CodeGen/DwarfEHPrepare.cpp
@@ -405,7 +405,7 @@ PreservedAnalyses DwarfEHPreparePass::run(Function &F,
 
   const TargetSubtargetInfo *Subtarget = TM->getSubtargetImpl(F);
   const LibcallLoweringInfo &Libcalls =
-      LibcallLowering->getLibcallLowering(*Subtarget);
+      getLibcallLowering(*LibcallLowering, *Subtarget);
 
   bool Changed =
       prepareDwarfEH(OptLevel, F, Libcalls, DT, TTI, TM->getTargetTriple());
diff --git a/llvm/lib/CodeGen/ExpandIRInsts.cpp b/llvm/lib/CodeGen/ExpandIRInsts.cpp
index b8503b958f76b..edbf8b3efaadc 100644
--- a/llvm/lib/CodeGen/ExpandIRInsts.cpp
+++ b/llvm/lib/CodeGen/ExpandIRInsts.cpp
@@ -1469,7 +1469,7 @@ PreservedAnalyses ExpandIRInstsPass::run(Function &F,
   }
 
   const LibcallLoweringInfo &Libcalls =
-      LibcallLowering->getLibcallLowering(*STI);
+      getLibcallLowering(*LibcallLowering, *STI);
 
   return runImpl(F, TLI, Libcalls, AC) ? PreservedAnalyses::none()
                                        : PreservedAnalyses::all();
diff --git a/llvm/lib/CodeGen/LibcallLoweringInfo.cpp b/llvm/lib/CodeGen/LibcallLoweringInfo.cpp
index bb406c7f1a5b2..5d99226924421 100644
--- a/llvm/lib/CodeGen/LibcallLoweringInfo.cpp
+++ b/llvm/lib/CodeGen/LibcallLoweringInfo.cpp
@@ -1,4 +1,4 @@
-//===- LibcallLoweringInfo.cpp - Interface for runtime libcalls -----------===//
+//===- LibcallLoweringInfo.cpp - Legacy wrapper for libcall lowering ------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -10,43 +10,16 @@
 #include "llvm/Analysis/RuntimeLibcallInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/InitializePasses.h"
-#include "llvm/Target/TargetMachine.h"
 
 using namespace llvm;
 
-LibcallLoweringInfo::LibcallLoweringInfo(
-    const RTLIB::RuntimeLibcallsInfo &RTLCI,
-    const TargetSubtargetInfo &Subtarget)
-    : RTLCI(RTLCI) {
-  // TODO: This should be generated with lowering predicates, and assert the
-  // call is available.
-  for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {
-    if (RTLCI.isAvailable(Impl)) {
-      RTLIB::Libcall LC = RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(Impl);
-      // FIXME: Hack, assume the first available libcall wins.
-      if (LibcallImpls[LC] == RTLIB::Unsupported)
-        LibcallImpls[LC] = Impl;
-    }
-  }
-
-  Subtarget.initLibcallLoweringInfo(*this);
-}
-
-AnalysisKey LibcallLoweringModuleAnalysis::Key;
-
-bool ModuleLibcallLoweringInfo::invalidate(
-    Module &, const PreservedAnalyses &PA,
-    ModuleAnalysisManager::Invalidator &) {
-  // Passes that change the runtime libcall set must explicitly invalidate this
-  // pass.
-  auto PAC = PA.getChecker<LibcallLoweringModuleAnalysis>();
-  return !PAC.preservedWhenStateless();
-}
-
-ModuleLibcallLoweringInfo
-LibcallLoweringModuleAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {
-  LibcallLoweringMap.init(&MAM.getResult<RuntimeLibraryAnalysis>(M));
-  return LibcallLoweringMap;
+const LibcallLoweringInfo &
+llvm::getLibcallLowering(const ModuleLibcallLoweringInfo &ModuleInfo,
+                         const TargetSubtargetInfo &Subtarget) {
+  return ModuleInfo.getLibcallLowering(
+      &Subtarget, [&](LibcallLoweringInfo &Info) {
+        Subtarget.initLibcallLoweringInfo(Info);
+      });
 }
 
 INITIALIZE_PASS_BEGIN(LibcallLoweringInfoWrapper, "libcall-lowering-info",
@@ -59,6 +32,21 @@ char LibcallLoweringInfoWrapper::ID = 0;
 
 LibcallLoweringInfoWrapper::LibcallLoweringInfoWrapper() : ImmutablePass(ID) {}
 
+const LibcallLoweringInfo &LibcallLoweringInfoWrapper::getLibcallLowering(
+    const Module &M, const TargetSubtargetInfo &Subtarget) {
+  return getResult(M).getLibcallLowering(
+      &Subtarget, [&](LibcallLoweringInfo &Info) {
+        Subtarget.initLibcallLoweringInfo(Info);
+      });
+}
+
+const ModuleLibcallLoweringInfo &
+LibcallLoweringInfoWrapper::getResult(const Module &M) {
+  if (!Result)
+    Result.init(&RuntimeLibcallsWrapper->getRTLCI(M));
+  return Result;
+}
+
 void LibcallLoweringInfoWrapper::initializePass() {
   RuntimeLibcallsWrapper = &getAnalysis<RuntimeLibraryInfoWrapper>();
 }
diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
index 4b5c97a23b091..24788148b9f15 100644
--- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
@@ -248,7 +248,7 @@ static bool canEmitLibcall(const ModuleLibcallLoweringInfo &ModuleLowering,
   if (!TM)
     return true;
   const LibcallLoweringInfo &Lowering =
-      ModuleLowering.getLibcallLowering(*TM->getSubtargetImpl(*F));
+      getLibcallLowering(ModuleLowering, *TM->getSubtargetImpl(*F));
   return Lowering.getLibcallImpl(LC) != RTLIB::Unsupported;
 }
 
@@ -258,7 +258,7 @@ static bool canEmitMemcpy(const ModuleLibcallLoweringInfo &ModuleLowering,
   if (!TM)
     return true;
   const LibcallLoweringInfo &Lowering =
-      ModuleLowering.getLibcallLowering(*TM->getSubtargetImpl(*F));
+      getLibcallLowering(ModuleLowering, *TM->getSubtargetImpl(*F));
   return Lowering.getMemcpyImpl() != RTLIB::Unsupported;
 }
 
diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp
index f154623879063..ca20503024524 100644
--- a/llvm/lib/CodeGen/SafeStack.cpp
+++ b/llvm/lib/CodeGen/SafeStack.cpp
@@ -980,7 +980,7 @@ PreservedAnalyses SafeStackPass::run(Function &F,
   }
 
   const LibcallLoweringInfo &Libcalls =
-      LibcallLowering->getLibcallLowering(*Subtarget);
+      getLibcallLowering(*LibcallLowering, *Subtarget);
 
   DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
 
diff --git a/llvm/lib/CodeGe...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list