[llvm] 86beba9 - [PredicateInfo] Cache ssa.copy declarations (NFC) (#145020)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 23 00:16:48 PDT 2025


Author: Nikita Popov
Date: 2025-06-23T09:16:45+02:00
New Revision: 86beba9301112c6092cbfa3e53bdacc0d68337df

URL: https://github.com/llvm/llvm-project/commit/86beba9301112c6092cbfa3e53bdacc0d68337df
DIFF: https://github.com/llvm/llvm-project/commit/86beba9301112c6092cbfa3e53bdacc0d68337df.diff

LOG: [PredicateInfo] Cache ssa.copy declarations (NFC) (#145020)

This pass creates a lot of ssa.copy intrinsics, typically for a small
set of types. Determining the function type, performing intrinsic name
mangling and looking up the declaration has noticeable overhead in this
case.

Improve this by caching the declarations by type. I've made this a
separate map from CreatedDeclarations, which only tracks the
declarations that were newly inserted (but not pre-existing ones).

Added: 
    

Modified: 
    llvm/include/llvm/Transforms/Utils/PredicateInfo.h
    llvm/lib/Transforms/Utils/PredicateInfo.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Transforms/Utils/PredicateInfo.h b/llvm/include/llvm/Transforms/Utils/PredicateInfo.h
index 670bfaa5ad6fe..1619fa31fb6f4 100644
--- a/llvm/include/llvm/Transforms/Utils/PredicateInfo.h
+++ b/llvm/include/llvm/Transforms/Utils/PredicateInfo.h
@@ -206,6 +206,8 @@ class PredicateInfo {
   DenseMap<const Value *, const PredicateBase *> PredicateMap;
   // The set of ssa_copy declarations we created with our custom mangling.
   SmallSet<AssertingVH<Function>, 20> CreatedDeclarations;
+  // Cache of ssa.copy declaration for a given type.
+  SmallDenseMap<Type *, Function *> DeclarationCache;
 };
 
 /// Printer pass for \c PredicateInfo.

diff  --git a/llvm/lib/Transforms/Utils/PredicateInfo.cpp b/llvm/lib/Transforms/Utils/PredicateInfo.cpp
index 95c125d43dea9..d26707a1361b3 100644
--- a/llvm/lib/Transforms/Utils/PredicateInfo.cpp
+++ b/llvm/lib/Transforms/Utils/PredicateInfo.cpp
@@ -506,25 +506,33 @@ Value *PredicateInfoBuilder::materializeStack(unsigned int &Counter,
     ValInfo->RenamedOp = (RenameStack.end() - Start) == RenameStack.begin()
                              ? OrigOp
                              : (RenameStack.end() - Start - 1)->Def;
+    auto CreateSSACopy = [this](IRBuilderBase &B, Value *Op,
+                                const Twine &Name = "") {
+      auto It = PI.DeclarationCache.try_emplace(Op->getType());
+      if (It.second) {
+        // The number of named values is used to detect if a new declaration
+        // was added. If so, that declaration is tracked so that it can be
+        // removed when the analysis is done. The corner case were a new
+        // declaration results in a name clash and the old name being renamed
+        // is not considered as that represents an invalid module.
+        auto NumDecls = F.getParent()->getNumNamedValues();
+        Function *IF = Intrinsic::getOrInsertDeclaration(
+            F.getParent(), Intrinsic::ssa_copy, Op->getType());
+        if (NumDecls != F.getParent()->getNumNamedValues())
+          PI.CreatedDeclarations.insert(IF);
+        It.first->second = IF;
+      }
+      return B.CreateCall(It.first->second, Op, Name);
+    };
     // For edge predicates, we can just place the operand in the block before
     // the terminator. For assume, we have to place it right after the assume
     // to ensure we dominate all uses except assume itself. Always insert
     // right before the terminator or after the assume, so that we insert in
     // proper order in the case of multiple predicateinfo in the same block.
-    // The number of named values is used to detect if a new declaration was
-    // added. If so, that declaration is tracked so that it can be removed when
-    // the analysis is done. The corner case were a new declaration results in
-    // a name clash and the old name being renamed is not considered as that
-    // represents an invalid module.
     if (isa<PredicateWithEdge>(ValInfo)) {
       IRBuilder<> B(getBranchTerminator(ValInfo));
-      auto NumDecls = F.getParent()->getNumNamedValues();
-      Function *IF = Intrinsic::getOrInsertDeclaration(
-          F.getParent(), Intrinsic::ssa_copy, Op->getType());
-      if (NumDecls != F.getParent()->getNumNamedValues())
-        PI.CreatedDeclarations.insert(IF);
       CallInst *PIC =
-          B.CreateCall(IF, Op, Op->getName() + "." + Twine(Counter++));
+          CreateSSACopy(B, Op, Op->getName() + "." + Twine(Counter++));
       PI.PredicateMap.insert({PIC, ValInfo});
       Result.Def = PIC;
     } else {
@@ -534,12 +542,7 @@ Value *PredicateInfoBuilder::materializeStack(unsigned int &Counter,
       // Insert the predicate directly after the assume. While it also holds
       // directly before it, assume(i1 true) is not a useful fact.
       IRBuilder<> B(PAssume->AssumeInst->getNextNode());
-      auto NumDecls = F.getParent()->getNumNamedValues();
-      Function *IF = Intrinsic::getOrInsertDeclaration(
-          F.getParent(), Intrinsic::ssa_copy, Op->getType());
-      if (NumDecls != F.getParent()->getNumNamedValues())
-        PI.CreatedDeclarations.insert(IF);
-      CallInst *PIC = B.CreateCall(IF, Op);
+      CallInst *PIC = CreateSSACopy(B, Op);
       PI.PredicateMap.insert({PIC, ValInfo});
       Result.Def = PIC;
     }


        


More information about the llvm-commits mailing list