[clang] [clang][analyzer][NFC] Improve Clang Static Analyzer performance. (PR #138295)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 2 08:28:55 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-static-analyzer-1
Author: None (tigbr)
<details>
<summary>Changes</summary>
This patch improves the performance of the Clang Static Analyzer by passing separate `BumpPtrAllocator` instances to its data structures instead of using the `BumpPtrAllocator` of the ExplodedGraph everywhere.
It greatly reduces the analysis time of [three example translation units](https://github.com/user-attachments/files/17232762/repros.tar.gz) that are particularly affected by disabling node reclamation, as mentioned in [issue #<!-- -->105512](https://github.com/llvm/llvm-project/issues/105512). It also brings a modest improvement in the general case as well, according to my testing on the [vim](https://github.com/vim/vim) repository with `scan-build`.
My measurements are in the [measurements.ods](https://github.com/user-attachments/files/20014809/measurements.ods) file.
---
Full diff: https://github.com/llvm/llvm-project/pull/138295.diff
10 Files Affected:
- (modified) clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (+2-1)
- (modified) clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (+3-1)
- (modified) clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h (+1-1)
- (modified) clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h (+8-5)
- (modified) clang/lib/StaticAnalyzer/Core/CoreEngine.cpp (+2-2)
- (modified) clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (+7-4)
- (modified) clang/lib/StaticAnalyzer/Core/ProgramState.cpp (+4-4)
- (modified) clang/lib/StaticAnalyzer/Core/SValBuilder.cpp (+8-5)
- (modified) clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp (+16-7)
- (modified) clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (+4-1)
``````````diff
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 80b79fd4e928f..6b6a28902092e 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -138,7 +138,8 @@ class CoreEngine {
/// Construct a CoreEngine object to analyze the provided CFG.
CoreEngine(ExprEngine &exprengine,
FunctionSummariesTy *FS,
- AnalyzerOptions &Opts);
+ AnalyzerOptions &Opts,
+ llvm::BumpPtrAllocator &BlockCounterFactoryAllocator);
CoreEngine(const CoreEngine &) = delete;
CoreEngine &operator=(const CoreEngine &) = delete;
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 20c446e33ef9a..4d10335d5a1fb 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -181,7 +181,9 @@ class ExprEngine {
public:
ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr,
SetOfConstDecls *VisitedCalleesIn,
- FunctionSummariesTy *FS, InliningModes HowToInlineIn);
+ FunctionSummariesTy *FS, InliningModes HowToInlineIn,
+ std::array<llvm::BumpPtrAllocator, 7> &ProgramStateAllocators,
+ llvm::BumpPtrAllocator &BlockCounterFactoryAllocator);
virtual ~ExprEngine() = default;
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index a20516b003c7d..a8403d170e896 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -530,7 +530,7 @@ class ProgramStateManager {
ProgramStateManager(ASTContext &Ctx,
StoreManagerCreator CreateStoreManager,
ConstraintManagerCreator CreateConstraintManager,
- llvm::BumpPtrAllocator& alloc,
+ std::array<llvm::BumpPtrAllocator, 7> &Allocators,
ExprEngine *expreng);
~ProgramStateManager();
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index 54430d426a82a..904718eae1843 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -76,8 +76,10 @@ class SValBuilder {
const unsigned ArrayIndexWidth;
public:
- SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
- ProgramStateManager &stateMgr);
+ SValBuilder(llvm::BumpPtrAllocator &BasicValueFactoryAllocator,
+ llvm::BumpPtrAllocator &SymbolManagerAllocator,
+ llvm::BumpPtrAllocator &MemRegionManagerAllocator,
+ ASTContext &context, ProgramStateManager &stateMgr);
virtual ~SValBuilder() = default;
@@ -409,9 +411,10 @@ class SValBuilder {
const StackFrameContext *SFC);
};
-SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
- ASTContext &context,
- ProgramStateManager &stateMgr);
+SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &BasicValueFactoryAllocator,
+ llvm::BumpPtrAllocator &SymbolManagerAllocator,
+ llvm::BumpPtrAllocator &MemRegionManagerAllocator,
+ ASTContext &context, ProgramStateManager &stateMgr);
} // namespace ento
diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
index bf1fd7c2356dc..9fa0211abbbbc 100644
--- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -75,10 +75,10 @@ static std::unique_ptr<WorkList> generateWorkList(AnalyzerOptions &Opts) {
}
CoreEngine::CoreEngine(ExprEngine &exprengine, FunctionSummariesTy *FS,
- AnalyzerOptions &Opts)
+ AnalyzerOptions &Opts, llvm::BumpPtrAllocator &BlockCounterFactoryAllocator)
: ExprEng(exprengine), WList(generateWorkList(Opts)),
CTUWList(Opts.IsNaiveCTUEnabled ? generateWorkList(Opts) : nullptr),
- BCounterFactory(G.getAllocator()), FunctionSummaries(FS) {}
+ BCounterFactory(BlockCounterFactoryAllocator), FunctionSummaries(FS) {}
void CoreEngine::setBlockCounter(BlockCounter C) {
WList->setBlockCounter(C);
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 69cf2dd6fc14e..af410ec5fea5d 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -221,12 +221,15 @@ static const char* TagProviderName = "ExprEngine";
ExprEngine::ExprEngine(cross_tu::CrossTranslationUnitContext &CTU,
AnalysisManager &mgr, SetOfConstDecls *VisitedCalleesIn,
- FunctionSummariesTy *FS, InliningModes HowToInlineIn)
+ FunctionSummariesTy *FS, InliningModes HowToInlineIn,
+ std::array<llvm::BumpPtrAllocator, 7> &ProgramStateAllocators,
+ llvm::BumpPtrAllocator& BlockCounterFactoryAllocator)
: CTU(CTU), IsCTUEnabled(mgr.getAnalyzerOptions().IsNaiveCTUEnabled),
AMgr(mgr), AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
- Engine(*this, FS, mgr.getAnalyzerOptions()), G(Engine.getGraph()),
- StateMgr(getContext(), mgr.getStoreManagerCreator(),
- mgr.getConstraintManagerCreator(), G.getAllocator(), this),
+ Engine(*this, FS, mgr.getAnalyzerOptions(), BlockCounterFactoryAllocator),
+ G(Engine.getGraph()),
+ StateMgr(getContext(), mgr.getStoreManagerCreator(), mgr.getConstraintManagerCreator(),
+ ProgramStateAllocators, this),
SymMgr(StateMgr.getSymbolManager()), MRMgr(StateMgr.getRegionManager()),
svalBuilder(StateMgr.getSValBuilder()), ObjCNoRet(mgr.getASTContext()),
BR(mgr, *this), VisitedCallees(VisitedCalleesIn),
diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
index 34ab2388cbd2f..a7709d6fc62b7 100644
--- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -72,11 +72,11 @@ int64_t ProgramState::getID() const {
ProgramStateManager::ProgramStateManager(ASTContext &Ctx,
StoreManagerCreator CreateSMgr,
ConstraintManagerCreator CreateCMgr,
- llvm::BumpPtrAllocator &alloc,
+ std::array<llvm::BumpPtrAllocator, 7> &Allocators,
ExprEngine *ExprEng)
- : Eng(ExprEng), EnvMgr(alloc), GDMFactory(alloc),
- svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)),
- CallEventMgr(new CallEventManager(alloc)), Alloc(alloc) {
+ : Eng(ExprEng), EnvMgr(Allocators[0]), GDMFactory(Allocators[1]),
+ svalBuilder(createSimpleSValBuilder(Allocators[2], Allocators[3], Allocators[4], Ctx, *this)),
+ CallEventMgr(new CallEventManager(Allocators[5])), Alloc(Allocators[6]) {
StoreMgr = (*CreateSMgr)(*this);
ConstraintMgr = (*CreateCMgr)(*this, ExprEng);
}
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 4f45b24be86c1..c1710df46d22c 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -49,13 +49,16 @@ using namespace ento;
void SValBuilder::anchor() {}
-SValBuilder::SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
+SValBuilder::SValBuilder(llvm::BumpPtrAllocator &BasicValueFactoryAllocator,
+ llvm::BumpPtrAllocator &SymbolManagerAllocator,
+ llvm::BumpPtrAllocator &MemRegionManagerAllocator,
+ ASTContext &context,
ProgramStateManager &stateMgr)
- : Context(context), BasicVals(context, alloc),
- SymMgr(context, BasicVals, alloc), MemMgr(context, alloc),
+ : Context(context), BasicVals(context, BasicValueFactoryAllocator),
+ SymMgr(context, BasicVals, SymbolManagerAllocator),
+ MemMgr(context, MemRegionManagerAllocator),
StateMgr(stateMgr),
- AnOpts(
- stateMgr.getOwningEngine().getAnalysisManager().getAnalyzerOptions()),
+ AnOpts(stateMgr.getOwningEngine().getAnalysisManager().getAnalyzerOptions()),
ArrayIndexTy(context.LongLongTy),
ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {}
diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index afb0273d23bd4..32022bd4d8e62 100644
--- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -64,9 +64,14 @@ class SimpleSValBuilder : public SValBuilder {
SVal simplifySValOnce(ProgramStateRef State, SVal V);
public:
- SimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
- ProgramStateManager &stateMgr)
- : SValBuilder(alloc, context, stateMgr) {}
+ SimpleSValBuilder(llvm::BumpPtrAllocator &BasicValueFactoryAllocator,
+ llvm::BumpPtrAllocator &SymbolManagerAllocator,
+ llvm::BumpPtrAllocator &MemRegionManagerAllocator,
+ ASTContext &context, ProgramStateManager &stateMgr)
+ : SValBuilder(BasicValueFactoryAllocator,
+ SymbolManagerAllocator,
+ MemRegionManagerAllocator,
+ context, stateMgr) {}
~SimpleSValBuilder() override {}
SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op,
@@ -98,10 +103,14 @@ class SimpleSValBuilder : public SValBuilder {
};
} // end anonymous namespace
-SValBuilder *ento::createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
- ASTContext &context,
- ProgramStateManager &stateMgr) {
- return new SimpleSValBuilder(alloc, context, stateMgr);
+SValBuilder *ento::createSimpleSValBuilder(llvm::BumpPtrAllocator &BasicValueFactoryAllocator,
+ llvm::BumpPtrAllocator &SymbolManagerAllocator,
+ llvm::BumpPtrAllocator &MemRegionManagerAllocator,
+ ASTContext &context, ProgramStateManager &stateMgr) {
+ return new SimpleSValBuilder(BasicValueFactoryAllocator,
+ SymbolManagerAllocator,
+ MemRegionManagerAllocator,
+ context, stateMgr);
}
// Checks if the negation the value and flipping sign preserve
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 189d7d6bede8e..1e0030a339ef3 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -752,7 +752,10 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D,
if (!Mgr->getAnalysisDeclContext(D)->getAnalysis<RelaxedLiveVariables>())
return;
- ExprEngine Eng(CTU, *Mgr, VisitedCallees, &FunctionSummaries, IMode);
+ std::array<llvm::BumpPtrAllocator, 7> ProgramStateManagerAllocators;
+ llvm::BumpPtrAllocator BlockCounterFactoryAllocator;
+
+ ExprEngine Eng(CTU, *Mgr, VisitedCallees, &FunctionSummaries, IMode, ProgramStateManagerAllocators, BlockCounterFactoryAllocator);
// Execute the worklist algorithm.
llvm::TimeRecord ExprEngineStartTime;
``````````
</details>
https://github.com/llvm/llvm-project/pull/138295
More information about the cfe-commits
mailing list