llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

If the array is small enough, use the initmap pointer directly for storage 
instead of heap-allocating it.

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


2 Files Affected:

- (modified) clang/lib/AST/ByteCode/Descriptor.h (+27) 
- (modified) clang/lib/AST/ByteCode/Pointer.cpp (+16-10) 


``````````diff
diff --git a/clang/lib/AST/ByteCode/Descriptor.h 
b/clang/lib/AST/ByteCode/Descriptor.h
index 2807f92335dc2..05be3d403cbae 100644
--- a/clang/lib/AST/ByteCode/Descriptor.h
+++ b/clang/lib/AST/ByteCode/Descriptor.h
@@ -278,6 +278,11 @@ struct Descriptor final {
 };
 
 /// Bitfield tracking the initialisation status of elements of primitive 
arrays.
+///
+/// InitMaps are saved for primitive arrays, so we don't have to have a
+/// per-element InlineDescriptor. When the number of elements in the array
+/// is small enough (see InitMap::isInline()), we use the pointer value
+/// directly instead of allocating an InitMap.
 struct alignas(alignof(uint64_t)) InitMap final {
 private:
   /// Type packing bits.
@@ -289,6 +294,28 @@ struct alignas(alignof(uint64_t)) InitMap final {
   /// Initializes the map with no fields set.
   explicit InitMap(unsigned N);
 
+  static bool isInline(size_t N) {
+    return N < (sizeof(uintptr_t) * CHAR_BIT - 1);
+  }
+
+  static bool isInlineElementInitialized(uintptr_t BucketValue, unsigned I) {
+    return BucketValue & (uintptr_t(1) << I);
+  }
+
+  static bool initializeInlineElement(InitMap *&IMPtr, size_t NumElems,
+                                      unsigned I) {
+    assert(isInline(NumElems));
+    assert(I < NumElems);
+    uintptr_t BucketValue = reinterpret_cast<uintptr_t>(IMPtr);
+    uintptr_t Mask = uintptr_t(1) << I;
+    if (!(BucketValue & Mask)) {
+      BucketValue |= Mask;
+      IMPtr = reinterpret_cast<InitMap *>(BucketValue);
+      return static_cast<unsigned>(llvm::popcount(BucketValue)) == NumElems;
+    }
+    return false;
+  }
+
   /// Checks if all elements have been initialized.
   static bool allInitialized(const InitMap *IM) {
     return reinterpret_cast<uintptr_t>(IM) ==
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp 
b/clang/lib/AST/ByteCode/Pointer.cpp
index 8fa17aed29d9e..d2c579a94129b 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -454,17 +454,10 @@ bool Pointer::isInitialized() const {
 
   const Descriptor *Desc = getFieldDesc();
   assert(Desc);
-  if (Desc->isPrimitiveArray()) {
-    InitMap *&IM = getInitMap();
-    if (!IM)
-      return false;
+  if (Desc->isPrimitiveArray())
+    return this->isElementInitialized(getIndex());
 
-    if (InitMap::allInitialized(IM))
-      return true;
-    return IM->isElementInitialized(getIndex());
-  }
-
-  if (asBlockPointer().Base == 0)
+  if (BS.Base == 0)
     return true;
   // Field has its bit in an inline descriptor.
   return getInlineDesc()->IsInitialized;
@@ -477,6 +470,13 @@ bool Pointer::isElementInitialized(unsigned Index) const {
   if (Desc->isPrimitiveArray()) {
     assert(getFieldDesc()->isPrimitiveArray());
     InitMap *&IM = getInitMap();
+    unsigned NumElems = Desc->getNumElems();
+
+    if (InitMap::isInline(NumElems)) {
+      return InitMap::allInitialized(IM) ||
+             InitMap::isInlineElementInitialized(
+                 reinterpret_cast<uintptr_t>(IM), Index);
+    }
     if (!IM)
       return false;
 
@@ -528,6 +528,12 @@ void Pointer::initializeElement(InterpState &S, unsigned 
Index) const {
   if (InitMap::allInitialized(IM))
     return;
 
+  unsigned NumElems = getFieldDesc()->getNumElems();
+  if (InitMap::isInline(NumElems)) {
+    if (InitMap::initializeInlineElement(IM, NumElems, Index))
+      InitMap::markAllInitialized(IM);
+    return;
+  }
   // nullptr means no initmap yet.
   if (!IM) {
     unsigned NumElems = getFieldDesc()->getNumElems();

``````````

</details>


https://github.com/llvm/llvm-project/pull/171093
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to