[llvm] [PredicateInfo] Cache ssa.copy declarations (NFC) (PR #145020)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 20 04:08:36 PDT 2025
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/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).
>From 5bd74b24d40223adc032017e12ef143a4dadad03 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Thu, 19 Jun 2025 13:50:02 +0200
Subject: [PATCH] [PredicateInfo] Cache ssa.copy declarations (NFC)
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).
---
.../llvm/Transforms/Utils/PredicateInfo.h | 2 ++
llvm/lib/Transforms/Utils/PredicateInfo.cpp | 27 ++++++++++---------
2 files changed, 17 insertions(+), 12 deletions(-)
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 97f13e3b26746..074b87265e375 100644
--- a/llvm/lib/Transforms/Utils/PredicateInfo.cpp
+++ b/llvm/lib/Transforms/Utils/PredicateInfo.cpp
@@ -499,6 +499,19 @@ 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) {
+ 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
@@ -511,13 +524,8 @@ Value *PredicateInfoBuilder::materializeStack(unsigned int &Counter,
// 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 {
@@ -527,12 +535,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