-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[analyzer] Improve cache locality by using separate allocators #138295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[analyzer] Improve cache locality by using separate allocators #138295
Conversation
Pass in separate BumpPtrAllocators to the different data structures in the analyzer, instead of reusing the BumpPtrAllocator of the ExplodedGraph everywhere, to gain a measurable speedup in analysis.
@llvm/pr-subscribers-clang-static-analyzer-1 Author: None (tigbr) ChangesThis patch improves the performance of the Clang Static Analyzer by passing separate It greatly reduces the analysis time of three example translation units that are particularly affected by disabling node reclamation, as mentioned in issue #105512. It also brings a modest improvement in the general case as well, according to my testing on the vim repository with My measurements are in the measurements.ods file. Full diff: https://github.com/llvm/llvm-project/pull/138295.diff 10 Files Affected:
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;
|
@llvm/pr-subscribers-clang Author: None (tigbr) ChangesThis patch improves the performance of the Clang Static Analyzer by passing separate It greatly reduces the analysis time of three example translation units that are particularly affected by disabling node reclamation, as mentioned in issue #105512. It also brings a modest improvement in the general case as well, according to my testing on the vim repository with My measurements are in the measurements.ods file. Full diff: https://github.com/llvm/llvm-project/pull/138295.diff 10 Files Affected:
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;
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
So is it about cache locality? |
Yes, that is what I have hoped to improve, and based on the measurements it seems that it had positive effects. |
FYI @necto |
FYI, build bots suggests that this PR has build errors. BTW, could you run this under perf stats to demonstrate the reduction of the cache-misses and page-faults? I'd suspect a measurable difference if these separate allocators really help. |
I had a look at the spreadsheet and the numbers for (FYI it usually better to take the minimums of the different analysis attempts than the avg). |
This patch improves the performance of the Clang Static Analyzer by passing separate
BumpPtrAllocator
instances to its data structures instead of using theBumpPtrAllocator
of the ExplodedGraph everywhere.It greatly reduces the analysis time of three example translation units that are particularly affected by disabling node reclamation, as mentioned in issue #105512. It also brings a modest improvement in the general case as well, according to my testing on the vim repository with
scan-build
.My measurements are in the measurements.ods file.