llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

So we can short-circuit the checking in `EvaluationResult::collectBlock()`. 
This improves the compile time of `X86Disassembler.cpp` by roughly 3.8%: 
https://llvm-compile-time-tracker.com/compare_clang.php?from=d69c6a8528c60a8f8013651ff18ed4882f6e6836&amp;to=b8b6333551d7c644e3c1b00ed19aceea09da40cc&amp;stat=instructions%3Au

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


4 Files Affected:

- (modified) clang/lib/AST/ByteCode/EvaluationResult.cpp (+18-6) 
- (modified) clang/lib/AST/ByteCode/Program.cpp (+7-2) 
- (modified) clang/lib/AST/ByteCode/Record.cpp (+11-4) 
- (modified) clang/lib/AST/ByteCode/Record.h (+5-1) 


``````````diff
diff --git a/clang/lib/AST/ByteCode/EvaluationResult.cpp 
b/clang/lib/AST/ByteCode/EvaluationResult.cpp
index 7c3c21cf28251..039848f00764e 100644
--- a/clang/lib/AST/ByteCode/EvaluationResult.cpp
+++ b/clang/lib/AST/ByteCode/EvaluationResult.cpp
@@ -157,6 +157,15 @@ bool EvaluationResult::checkFullyInitialized(InterpState 
&S,
   return true;
 }
 
+static bool isOrHasPtr(const Descriptor *D) {
+  if ((D->isPrimitive() || D->isPrimitiveArray()) && D->getPrimType() == 
PT_Ptr)
+    return true;
+
+  if (D->ElemRecord)
+    return D->ElemRecord->hasPtrField();
+  return false;
+}
+
 static void collectBlocks(const Pointer &Ptr,
                           llvm::SetVector<const Block *> &Blocks) {
   auto isUsefulPtr = [](const Pointer &P) -> bool {
@@ -173,26 +182,29 @@ static void collectBlocks(const Pointer &Ptr,
   if (!Desc)
     return;
 
-  if (const Record *R = Desc->ElemRecord) {
+  if (const Record *R = Desc->ElemRecord; R && R->hasPtrField()) {
+
     for (const Record::Field &F : R->fields()) {
-      const Pointer &FieldPtr = Ptr.atField(F.Offset);
+      if (!isOrHasPtr(F.Desc))
+        continue;
+      Pointer FieldPtr = Ptr.atField(F.Offset);
       assert(FieldPtr.block() == Ptr.block());
       collectBlocks(FieldPtr, Blocks);
     }
   } else if (Desc->isPrimitive() && Desc->getPrimType() == PT_Ptr) {
-    const Pointer &Pointee = Ptr.deref<Pointer>();
+    Pointer Pointee = Ptr.deref<Pointer>();
     if (isUsefulPtr(Pointee) && !Blocks.contains(Pointee.block()))
       collectBlocks(Pointee, Blocks);
 
   } else if (Desc->isPrimitiveArray() && Desc->getPrimType() == PT_Ptr) {
     for (unsigned I = 0; I != Desc->getNumElems(); ++I) {
-      const Pointer &ElemPointee = Ptr.elem<Pointer>(I);
+      Pointer ElemPointee = Ptr.elem<Pointer>(I);
       if (isUsefulPtr(ElemPointee) && !Blocks.contains(ElemPointee.block()))
         collectBlocks(ElemPointee, Blocks);
     }
-  } else if (Desc->isCompositeArray()) {
+  } else if (Desc->isCompositeArray() && isOrHasPtr(Desc->ElemDesc)) {
     for (unsigned I = 0; I != Desc->getNumElems(); ++I) {
-      const Pointer &ElemPtr = Ptr.atIndex(I).narrow();
+      Pointer ElemPtr = Ptr.atIndex(I).narrow();
       collectBlocks(ElemPtr, Blocks);
     }
   }
diff --git a/clang/lib/AST/ByteCode/Program.cpp 
b/clang/lib/AST/ByteCode/Program.cpp
index 9a7b38d4d828e..7eebb303d8553 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -356,6 +356,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
   // Reserve space for fields.
   Record::FieldList Fields;
   Fields.reserve(RD->getNumFields());
+  bool HasPtrField = false;
   for (const FieldDecl *FD : RD->fields()) {
     FD = FD->getFirstDecl();
     // Note that we DO create fields and descriptors
@@ -374,9 +375,12 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
     if (OptPrimType T = Ctx.classify(FT)) {
       Desc = createDescriptor(FD, *T, nullptr, std::nullopt, IsConst,
                               /*isTemporary=*/false, IsMutable, IsVolatile);
+      HasPtrField = HasPtrField || (T == PT_Ptr);
     } else {
       Desc = createDescriptor(FD, FT.getTypePtr(), std::nullopt, IsConst,
                               /*isTemporary=*/false, IsMutable, IsVolatile);
+      HasPtrField = HasPtrField || (Desc && Desc->isPrimitiveArray() &&
+                                    Desc->getPrimType() == PT_Ptr);
     }
     if (!Desc)
       return nullptr;
@@ -384,8 +388,9 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
     BaseSize += align(Desc->getAllocSize());
   }
 
-  Record *R = new (Allocator) Record(RD, std::move(Bases), std::move(Fields),
-                                     std::move(VirtBases), VirtSize, BaseSize);
+  Record *R = new (Allocator)
+      Record(RD, std::move(Bases), std::move(Fields), std::move(VirtBases),
+             VirtSize, BaseSize, HasPtrField);
   Records[RD] = R;
   return R;
 }
diff --git a/clang/lib/AST/ByteCode/Record.cpp 
b/clang/lib/AST/ByteCode/Record.cpp
index 17cf629a91b60..f3ee2fa35a3f5 100644
--- a/clang/lib/AST/ByteCode/Record.cpp
+++ b/clang/lib/AST/ByteCode/Record.cpp
@@ -14,17 +14,24 @@ using namespace clang::interp;
 
 Record::Record(const RecordDecl *Decl, BaseList &&SrcBases,
                FieldList &&SrcFields, VirtualBaseList &&SrcVirtualBases,
-               unsigned VirtualSize, unsigned BaseSize)
+               unsigned VirtualSize, unsigned BaseSize, bool HasPtrField)
     : Decl(Decl), Bases(std::move(SrcBases)), Fields(std::move(SrcFields)),
       BaseSize(BaseSize), VirtualSize(VirtualSize), IsUnion(Decl->isUnion()),
-      IsAnonymousUnion(IsUnion && Decl->isAnonymousStructOrUnion()) {
+      IsAnonymousUnion(IsUnion && Decl->isAnonymousStructOrUnion()),
+      HasPtrField(HasPtrField) {
   for (Base &V : SrcVirtualBases)
     VirtualBases.emplace_back(V.Decl, V.Desc, V.R, V.Offset + BaseSize);
 
-  for (Base &B : Bases)
+  for (Base &B : Bases) {
     BaseMap[B.Decl] = &B;
-  for (Base &V : VirtualBases)
+    if (!HasPtrField)
+      HasPtrField |= B.R->hasPtrField();
+  }
+  for (Base &V : VirtualBases) {
     VirtualBaseMap[V.Decl] = &V;
+    if (!HasPtrField)
+      HasPtrField |= B.R->hasPtrField();
+  }
 }
 
 std::string Record::getName() const {
diff --git a/clang/lib/AST/ByteCode/Record.h b/clang/lib/AST/ByteCode/Record.h
index 29c500b9c29d5..e43f683364e26 100644
--- a/clang/lib/AST/ByteCode/Record.h
+++ b/clang/lib/AST/ByteCode/Record.h
@@ -75,6 +75,8 @@ class Record final {
       return CXXDecl->getDestructor();
     return nullptr;
   }
+  /// If this record (or any of its bases) contains a field of type PT_Ptr.
+  bool hasPtrField() const { return HasPtrField; }
 
   /// Returns true for anonymous unions and records
   /// with no destructor or for those with a trivial destructor.
@@ -125,7 +127,7 @@ class Record final {
   /// Constructor used by Program to create record descriptors.
   Record(const RecordDecl *, BaseList &&Bases, FieldList &&Fields,
          VirtualBaseList &&VirtualBases, unsigned VirtualSize,
-         unsigned BaseSize);
+         unsigned BaseSize, bool HasPtrField = true);
 
 private:
   friend class Program;
@@ -151,6 +153,8 @@ class Record final {
   bool IsUnion;
   /// If this is an anonymous union.
   bool IsAnonymousUnion;
+  /// If any of the fields are pointers (or references).
+  bool HasPtrField = false;
 };
 
 } // namespace interp

``````````

</details>


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

Reply via email to