steakhal created this revision.
steakhal added reviewers: NoQ, xazax.hun, Szelethus, vsavchenko, ASDenysPetrov.
Herald added subscribers: cfe-commits, martong, Charusso, dkrupp, donat.nagy, 
mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware, whisperity.
Herald added a project: clang.
steakhal requested review of this revision.

By the time working on the gdb pretty-printers for the Analyzer classes,
I observed that the `MemRegion` class has an inefficient memory layout.

Each and every object which's has a `MemRegion` as a subobject would benefit 
from this change.
We could spare 8 bytes for each case.

As a downside, I had to substitute the `llvm::Optional`, since that alone 
consumes 16 bytes (even if the wrapped object would consume 8 bytes :| ).

Before the patch: `sizeof(MemRegion) == 48`

  (gdb) ptype /o class MemRegion
  /* offset    |  size */  type = class clang::ento::MemRegion : public 
llvm::FoldingSetBase::Node {
                           private:
  /*   16      |     4 */    const clang::ento::MemRegion::Kind kind;
  /* XXX  4-byte hole  */
  /*   24      |    24 */    class llvm::Optional<clang::ento::RegionOffset> 
[with T = clang::ento::RegionOffset] {
                               private:
  /*   24      |    24 */        class 
llvm::optional_detail::OptionalStorage<T, true> [with T = T] {
                                   private:
  /*   24      |    16 */            union {
  /*                 1 */                char empty;
  /*                16 */                T value;
  
                                         /* total size (bytes):   16 */
                                     };
  /*   40      |     1 */            bool hasVal;
  
                                     /* total size (bytes):   24 */
                                 } Storage;
  
                                 /* total size (bytes):   24 */
                             } cachedOffset;
  
                             /* total size (bytes):   48 */
                           }

After the patch: `sizeof(MemRegion) == 40`

  (gdb) ptype /o MemRegion
  /* offset    |  size */  type = class clang::ento::MemRegion : public 
llvm::FoldingSetBase::Node {
                           private:
  /*   16      |    16 */    class clang::ento::RegionOffset {
                               private:
  /*   16      |     8 */        const clang::ento::MemRegion *R;
  /*   24      |     8 */        int64_t Offset;
                               public:
                                 static const int64_t Symbolic;
  
                                 /* total size (bytes):   16 */
                             } cachedOffset;
  /*   32      |     4 */    const clang::ento::MemRegion::Kind kind;
  /*   36      |     1 */    bool hasCachedOffset;
  
                             /* total size (bytes):   40 */
                           }


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D86295

Files:
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
  clang/lib/StaticAnalyzer/Core/MemRegion.cpp


Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -1579,9 +1579,11 @@
 }
 
 RegionOffset MemRegion::getAsOffset() const {
-  if (!cachedOffset)
+  if (!hasCachedOffset) {
     cachedOffset = calculateOffset(this);
-  return *cachedOffset;
+    hasCachedOffset = true;
+  }
+  return cachedOffset;
 }
 
 
//===----------------------------------------------------------------------===//
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -100,8 +100,9 @@
   };
 
 private:
+  mutable RegionOffset cachedOffset;
   const Kind kind;
-  mutable Optional<RegionOffset> cachedOffset;
+  mutable bool hasCachedOffset = false;
 
 protected:
   MemRegion(Kind k) : kind(k) {}


Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -1579,9 +1579,11 @@
 }
 
 RegionOffset MemRegion::getAsOffset() const {
-  if (!cachedOffset)
+  if (!hasCachedOffset) {
     cachedOffset = calculateOffset(this);
-  return *cachedOffset;
+    hasCachedOffset = true;
+  }
+  return cachedOffset;
 }
 
 //===----------------------------------------------------------------------===//
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -100,8 +100,9 @@
   };
 
 private:
+  mutable RegionOffset cachedOffset;
   const Kind kind;
-  mutable Optional<RegionOffset> cachedOffset;
+  mutable bool hasCachedOffset = false;
 
 protected:
   MemRegion(Kind k) : kind(k) {}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to