Skip to content

Conversation

@tbaederr
Copy link
Contributor

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().

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().
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:bytecode Issues for the clang bytecode constexpr interpreter labels Aug 28, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 28, 2025

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

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().


Full diff: https://github.com/llvm/llvm-project/pull/155831.diff

2 Files Affected:

  • (modified) clang/lib/AST/ByteCode/InterpState.cpp (+7-3)
  • (modified) clang/lib/AST/ByteCode/InterpState.h (+8-2)
diff --git a/clang/lib/AST/ByteCode/InterpState.cpp b/clang/lib/AST/ByteCode/InterpState.cpp
index f89967759ff9b..c7c96a31c4b31 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() {
@@ -103,10 +104,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 861e4c38049ab..83acbcef7095e 100644
--- a/clang/lib/AST/ByteCode/InterpState.h
+++ b/clang/lib/AST/ByteCode/InterpState.h
@@ -118,7 +118,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,
@@ -164,7 +170,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.

@tbaederr tbaederr merged commit e96ff45 into llvm:main Sep 2, 2025
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:bytecode Issues for the clang bytecode constexpr interpreter clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants