[llvm] 510fb87 - [IR][TLI] Cache getLibFunc() result on Function (NFC) (#72867)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 22 02:18:48 PST 2023


Author: Nikita Popov
Date: 2023-11-22T11:18:43+01:00
New Revision: 510fb8711e9ad68afdf2b9ef0f2bbf312bf9ccf5

URL: https://github.com/llvm/llvm-project/commit/510fb8711e9ad68afdf2b9ef0f2bbf312bf9ccf5
DIFF: https://github.com/llvm/llvm-project/commit/510fb8711e9ad68afdf2b9ef0f2bbf312bf9ccf5.diff

LOG: [IR][TLI] Cache getLibFunc() result on Function (NFC) (#72867)

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 will be invalidated in that case
as well.

I don't believe this increases the size of Function on 64bit (which
currently has a trailing `bool` member), and I don't think we would
particularly care if it did, as Functions are uncommon as Values go.

Added: 
    

Modified: 
    llvm/include/llvm/IR/Function.h
    llvm/lib/Analysis/TargetLibraryInfo.cpp
    llvm/lib/IR/Function.cpp
    llvm/lib/IR/Value.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index 955a4fca6f86f7e..6ac768b51395cc8 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,15 @@ class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject,
   void setIsNewDbgInfoFormat(bool NewVal);
 
 private:
+  friend class TargetLibraryInfoImpl;
+
+  static constexpr LibFunc UnknownLibFunc = LibFunc(-1);
+
+  /// Cache for TLI::getLibFunc() result without prototype validation.
+  /// UnknownLibFunc if uninitialized. NotLibFunc if definitely not lib func.
+  /// Otherwise may be libfunc if prototype validation passes.
+  mutable LibFunc LibFuncCache = UnknownLibFunc;
+
   void CheckLazyArguments() const {
     if (hasLazyArguments())
       BuildLazyArguments();
@@ -239,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/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 7b38583e9bc75f0..20959cf6948f656 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 == Function::UnknownLibFunc)
+    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..c3706dc1b02fc34 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -912,7 +912,8 @@ Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) {
                                                      : Intrinsic::not_intrinsic;
 }
 
-void Function::recalculateIntrinsicID() {
+void Function::updateAfterNameChange() {
+  LibFuncCache = UnknownLibFunc;
   StringRef Name = getName();
   if (!Name.startswith("llvm.")) {
     HasLLVMReservedName = false;

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