[llvm] [IR][TLI] Cache getLibFunc() result on Function (NFC) (PR #72867)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 22 00:22:53 PST 2023


https://github.com/nikic updated https://github.com/llvm/llvm-project/pull/72867

>From ca1de086971bcb7094f5066f867957af36455a4f Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 20 Nov 2023 12:08:39 +0100
Subject: [PATCH 1/3] [IR][TLI] Cache getLibFunc() result on Function (NFC)

Cache the result of the TLI libfunc lookup in the Function object.
This only caches the actual lookup of the LibFunc in the TLI map,
but not the prototype validation, as that might differ between
different TLI instances.

This uses the existing mechanism for invalidating the intrinsic
ID when the function name changes. The libfunc wil be invalidated
in that case as well.
---
 llvm/include/llvm/IR/Function.h         |  9 +++++++++
 llvm/lib/Analysis/TargetLibraryInfo.cpp | 11 +++++++++--
 llvm/lib/IR/Function.cpp                |  1 +
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index 955a4fca6f86f7e..0089fd7d5d8788d 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -48,9 +48,11 @@ class AssemblyAnnotationWriter;
 class Constant;
 struct DenormalMode;
 class DISubprogram;
+enum LibFunc : unsigned;
 class LLVMContext;
 class Module;
 class raw_ostream;
+class TargetLibraryInfoImpl;
 class Type;
 class User;
 class BranchProbabilityInfo;
@@ -120,6 +122,13 @@ class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject,
   void setIsNewDbgInfoFormat(bool NewVal);
 
 private:
+  friend class TargetLibraryInfoImpl;
+
+  /// Cache for TLI::getLibFunc() result without prototype validation.
+  /// -1 if uninitialized. NotLibFunc if definitely not lib func.
+  /// Otherwise may be libfunc if prototype validation passes.
+  mutable LibFunc LibFuncCache = LibFunc(-1);
+
   void CheckLazyArguments() const {
     if (hasLazyArguments())
       BuildLazyArguments();
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 7b38583e9bc75f0..1037368169bbaad 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -1138,8 +1138,15 @@ bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl,
   const Module *M = FDecl.getParent();
   assert(M && "Expecting FDecl to be connected to a Module.");
 
-  return getLibFunc(FDecl.getName(), F) &&
-         isValidProtoForLibFunc(*FDecl.getFunctionType(), F, *M);
+  if (FDecl.LibFuncCache == LibFunc(-1))
+    if (!getLibFunc(FDecl.getName(), FDecl.LibFuncCache))
+      FDecl.LibFuncCache = NotLibFunc;
+
+  if (FDecl.LibFuncCache == NotLibFunc)
+    return false;
+
+  F = FDecl.LibFuncCache;
+  return isValidProtoForLibFunc(*FDecl.getFunctionType(), F, *M);
 }
 
 void TargetLibraryInfoImpl::disableAllFunctions() {
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 49e0c1c5883c265..bff36b02c20246f 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -913,6 +913,7 @@ Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) {
 }
 
 void Function::recalculateIntrinsicID() {
+  LibFuncCache = LibFunc(-1);
   StringRef Name = getName();
   if (!Name.startswith("llvm.")) {
     HasLLVMReservedName = false;

>From f7dd251b2afbafdff5bb69491931fc68284523eb Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 21 Nov 2023 10:07:59 +0100
Subject: [PATCH 2/3] Add UnknownLibFunc alias for LibFunc(-1)

---
 llvm/include/llvm/IR/Function.h         | 6 ++++--
 llvm/lib/Analysis/TargetLibraryInfo.cpp | 2 +-
 llvm/lib/IR/Function.cpp                | 2 +-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index 0089fd7d5d8788d..aa36a2dd12a7e87 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -124,10 +124,12 @@ class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject,
 private:
   friend class TargetLibraryInfoImpl;
 
+  static constexpr LibFunc UnknownLibFunc = LibFunc(-1);
+
   /// Cache for TLI::getLibFunc() result without prototype validation.
-  /// -1 if uninitialized. NotLibFunc if definitely not lib func.
+  /// UnknownLibFunc if uninitialized. NotLibFunc if definitely not lib func.
   /// Otherwise may be libfunc if prototype validation passes.
-  mutable LibFunc LibFuncCache = LibFunc(-1);
+  mutable LibFunc LibFuncCache = UnknownLibFunc;
 
   void CheckLazyArguments() const {
     if (hasLazyArguments())
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 1037368169bbaad..20959cf6948f656 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -1138,7 +1138,7 @@ bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl,
   const Module *M = FDecl.getParent();
   assert(M && "Expecting FDecl to be connected to a Module.");
 
-  if (FDecl.LibFuncCache == LibFunc(-1))
+  if (FDecl.LibFuncCache == Function::UnknownLibFunc)
     if (!getLibFunc(FDecl.getName(), FDecl.LibFuncCache))
       FDecl.LibFuncCache = NotLibFunc;
 
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index bff36b02c20246f..64b48897485e32f 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -913,7 +913,7 @@ Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) {
 }
 
 void Function::recalculateIntrinsicID() {
-  LibFuncCache = LibFunc(-1);
+  LibFuncCache = UnknownLibFunc;
   StringRef Name = getName();
   if (!Name.startswith("llvm.")) {
     HasLLVMReservedName = false;

>From 99eb0f60b03e079b7d71fb655aa3af58b3e3ee21 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Wed, 22 Nov 2023 09:17:44 +0100
Subject: [PATCH 3/3] recalculateIntrinsicID -> updateAfterNameChange

---
 llvm/include/llvm/IR/Function.h | 7 +++----
 llvm/lib/IR/Function.cpp        | 2 +-
 llvm/lib/IR/Value.cpp           | 2 +-
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index aa36a2dd12a7e87..6ac768b51395cc8 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -250,12 +250,11 @@ class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject,
 
   static Intrinsic::ID lookupIntrinsicID(StringRef Name);
 
-  /// Recalculate the ID for this function if it is an Intrinsic defined
-  /// in llvm/Intrinsics.h.  Sets the intrinsic ID to Intrinsic::not_intrinsic
-  /// if the name of this function does not match an intrinsic in that header.
+  /// Update internal caches that depend on the function name (such as the
+  /// intrinsic ID and libcall cache).
   /// Note, this method does not need to be called directly, as it is called
   /// from Value::setName() whenever the name of this function changes.
-  void recalculateIntrinsicID();
+  void updateAfterNameChange();
 
   /// getCallingConv()/setCallingConv(CC) - These method get and set the
   /// calling convention of this function.  The enum values for the known
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 64b48897485e32f..c3706dc1b02fc34 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -912,7 +912,7 @@ Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) {
                                                      : Intrinsic::not_intrinsic;
 }
 
-void Function::recalculateIntrinsicID() {
+void Function::updateAfterNameChange() {
   LibFuncCache = UnknownLibFunc;
   StringRef Name = getName();
   if (!Name.startswith("llvm.")) {
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index c05f9ac5a0fe024..b6e25c46b514d84 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -377,7 +377,7 @@ void Value::setNameImpl(const Twine &NewName) {
 void Value::setName(const Twine &NewName) {
   setNameImpl(NewName);
   if (Function *F = dyn_cast<Function>(this))
-    F->recalculateIntrinsicID();
+    F->updateAfterNameChange();
 }
 
 void Value::takeName(Value *V) {



More information about the llvm-commits mailing list