Author: Timm Baeder Date: 2025-09-02T17:57:18+02:00 New Revision: e96ff4530fa0111fccf2687a4e2a55bbe0f73554
URL: https://github.com/llvm/llvm-project/commit/e96ff4530fa0111fccf2687a4e2a55bbe0f73554 DIFF: https://github.com/llvm/llvm-project/commit/e96ff4530fa0111fccf2687a4e2a55bbe0f73554.diff LOG: [clang][bytecode] Lazily create DynamicAllocator (#155831) Due to all the tracking via map(s) and a BumpPtrAllocator, the creating and destroying the DynamicAllocator is rather expensive. Try to do it lazily and only create it when first calling InterpState::getAllocator(). Added: Modified: clang/lib/AST/ByteCode/InterpState.cpp clang/lib/AST/ByteCode/InterpState.h Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/InterpState.cpp b/clang/lib/AST/ByteCode/InterpState.cpp index a2a1e5826d7c5..4bafb89741857 100644 --- a/clang/lib/AST/ByteCode/InterpState.cpp +++ b/clang/lib/AST/ByteCode/InterpState.cpp @@ -59,7 +59,8 @@ InterpState::~InterpState() { void InterpState::cleanup() { // As a last resort, make sure all pointers still pointing to a dead block // don't point to it anymore. - Alloc.cleanup(); + if (Alloc) + Alloc->cleanup(); } Frame *InterpState::getCurrentFrame() { return Current; } @@ -99,10 +100,13 @@ void InterpState::deallocate(Block *B) { } bool InterpState::maybeDiagnoseDanglingAllocations() { - bool NoAllocationsLeft = !Alloc.hasAllocations(); + if (!Alloc) + return true; + + bool NoAllocationsLeft = !Alloc->hasAllocations(); if (!checkingPotentialConstantExpression()) { - for (const auto &[Source, Site] : Alloc.allocation_sites()) { + for (const auto &[Source, Site] : Alloc->allocation_sites()) { assert(!Site.empty()); CCEDiag(Source->getExprLoc(), diag::note_constexpr_memory_leak) diff --git a/clang/lib/AST/ByteCode/InterpState.h b/clang/lib/AST/ByteCode/InterpState.h index f123a1f169c02..1e4c0701723c6 100644 --- a/clang/lib/AST/ByteCode/InterpState.h +++ b/clang/lib/AST/ByteCode/InterpState.h @@ -115,7 +115,13 @@ class InterpState final : public State, public SourceMapper { void setEvalLocation(SourceLocation SL) { this->EvalLocation = SL; } - DynamicAllocator &getAllocator() { return Alloc; } + DynamicAllocator &getAllocator() { + if (!Alloc) { + Alloc = std::make_unique<DynamicAllocator>(); + } + + return *Alloc.get(); + } /// Diagnose any dynamic allocations that haven't been freed yet. /// Will return \c false if there were any allocations to diagnose, @@ -161,7 +167,7 @@ class InterpState final : public State, public SourceMapper { /// Reference to the offset-source mapping. SourceMapper *M; /// Allocator used for dynamic allocations performed via the program. - DynamicAllocator Alloc; + std::unique_ptr<DynamicAllocator> Alloc; public: /// Reference to the module containing all bytecode. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits