[llvm] [utils] Fix DenseMap debugger printers for the packed used-bit array (PR #201755)

Dave Lee via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 7 10:45:00 PDT 2026


================
@@ -492,31 +484,16 @@ def update(self):
         if num_entries == 0:
             return
 
-        buckets = self.valobj.GetChildMemberWithName("Buckets")
         num_buckets = self.valobj.GetChildMemberWithName("NumBuckets").unsigned
+        used = self.valobj.GetChildMemberWithName("Used")
 
-        # Bucket entries contain one of the following:
-        #   1. Valid key-value
-        #   2. Empty key
-        #   3. Tombstone key (a deleted entry)
-        #
-        # NumBuckets is always greater than NumEntries. The empty key, and
-        # potentially the tombstone key, will occur multiple times. A key that
-        # is repeated is either the empty key or the tombstone key.
-
-        # For each key, collect a list of buckets it appears in.
-        key_buckets: dict[str, list[int]] = collections.defaultdict(list)
+        # Occupancy is tracked in a packed 1-bit-per-bucket "used" array of
+        # uint32_t words. A bucket holds a valid entry iff its bit is set;
+        # empty and erased buckets are clear.
         for index in range(num_buckets):
-            bucket = buckets.GetValueForExpressionPath(f"[{index}]")
-            key = bucket.GetChildAtIndex(0)
-            key_buckets[str(key.data)].append(index)
-
-        # Heuristic: This is not a multi-map, any repeated (non-unique) keys are
-        # either the the empty key or the tombstone key. Populate child_buckets
-        # with the indexes of entries containing unique keys.
-        for indexes in key_buckets.values():
-            if len(indexes) == 1:
-                self.child_buckets.append(indexes[0])
+            word = used.GetValueForExpressionPath(f"[{index >> 5}]").unsigned
+            if (word >> (index & 31)) & 1:
+                self.child_buckets.append(index)
----------------
kastiglione wrote:

I haven't tested it with the new DenseMap, but I would avoid calling `GetValueForExpressionPath("[N]")` 32 times for each `N`, by doing something like:

```py
used_data = used.GetPointeeData(0, num_buckets // 32)
for word_idx, word in enumerate(used_data.uint32):
    for bit in range(31):
        if (word >> bit) & 1:
            self.child_buckets.append(word_idx * 32 + bit)
```

https://github.com/llvm/llvm-project/pull/201755


More information about the llvm-commits mailing list