Skip to content

Conversation

@tbaederr
Copy link
Contributor

In the case of primitive arrays, we can do this once and reuse the value for all elements.

In the case of primitive arrays, we can do this once and reuse the value
for all elements.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Dec 10, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 10, 2024

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

In the case of primitive arrays, we can do this once and reuse the value for all elements.


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

1 Files Affected:

  • (modified) clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp (+20-20)
diff --git a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
index c9cd113287557b..3a056acff14a7f 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
@@ -33,8 +33,9 @@ using namespace clang::interp;
 //    bytes to/from the buffer.
 
 /// Used to iterate over pointer fields.
-using DataFunc = llvm::function_ref<bool(const Pointer &P, PrimType Ty,
-                                         Bits BitOffset, bool PackedBools)>;
+using DataFunc =
+    llvm::function_ref<bool(const Pointer &P, PrimType Ty, Bits BitOffset,
+                            Bits FullBitWidth, bool PackedBools)>;
 
 #define BITCAST_TYPE_SWITCH(Expr, B)                                           \
   do {                                                                         \
@@ -85,21 +86,25 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, Bits Offset,
   assert(FieldDesc);
 
   // Primitives.
-  if (FieldDesc->isPrimitive())
-    return F(P, FieldDesc->getPrimType(), Offset, /*PackedBools=*/false);
+  if (FieldDesc->isPrimitive()) {
+    Bits FullBitWidth =
+        Bits(Ctx.getASTContext().getTypeSize(FieldDesc->getType()));
+    return F(P, FieldDesc->getPrimType(), Offset, FullBitWidth,
+             /*PackedBools=*/false);
+  }
 
   // Primitive arrays.
   if (FieldDesc->isPrimitiveArray()) {
     QualType ElemType = FieldDesc->getElemQualType();
-    size_t ElemSizeInBits = Ctx.getASTContext().getTypeSize(ElemType);
+    Bits ElemSize = Bits(Ctx.getASTContext().getTypeSize(ElemType));
     PrimType ElemT = *Ctx.classify(ElemType);
     // Special case, since the bools here are packed.
     bool PackedBools = FieldDesc->getType()->isExtVectorBoolType();
     unsigned NumElems = FieldDesc->getNumElems();
     bool Ok = true;
     for (unsigned I = P.getIndex(); I != NumElems; ++I) {
-      Ok = Ok && F(P.atIndex(I), ElemT, Offset, PackedBools);
-      Offset += PackedBools ? 1 : ElemSizeInBits;
+      Ok = Ok && F(P.atIndex(I), ElemT, Offset, ElemSize, PackedBools);
+      Offset += PackedBools ? Bits(1) : ElemSize;
       if (Offset >= BitsToRead)
         break;
     }
@@ -109,10 +114,10 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, Bits Offset,
   // Composite arrays.
   if (FieldDesc->isCompositeArray()) {
     QualType ElemType = FieldDesc->getElemQualType();
-    size_t ElemSizeInBits = Ctx.getASTContext().getTypeSize(ElemType);
+    Bits ElemSize = Bits(Ctx.getASTContext().getTypeSize(ElemType));
     for (unsigned I = 0; I != FieldDesc->getNumElems(); ++I) {
       enumerateData(P.atIndex(I).narrow(), Ctx, Offset, BitsToRead, F);
-      Offset += ElemSizeInBits;
+      Offset += ElemSize;
       if (Offset >= BitsToRead)
         break;
     }
@@ -233,16 +238,14 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
 
   return enumeratePointerFields(
       FromPtr, Ctx, Buffer.size(),
-      [&](const Pointer &P, PrimType T, Bits BitOffset,
+      [&](const Pointer &P, PrimType T, Bits BitOffset, Bits FullBitWidth,
           bool PackedBools) -> bool {
-        CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars(P.getType());
-        Bits BitWidth = Bits(ASTCtx.toBits(ObjectReprChars));
-        Bits FullBitWidth = BitWidth;
+        Bits BitWidth = FullBitWidth;
 
-        if (const FieldDecl *FD = P.getField(); FD && FD->isBitField()) {
+        if (const FieldDecl *FD = P.getField(); FD && FD->isBitField())
           BitWidth = Bits(std::min(FD->getBitWidthValue(ASTCtx),
                                    (unsigned)FullBitWidth.getQuantity()));
-        } else if (T == PT_Bool && PackedBools)
+        else if (T == PT_Bool && PackedBools)
           BitWidth = Bits(1);
 
         if (BitWidth.isZero())
@@ -261,8 +264,7 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
         }
 
         assert(P.isInitialized());
-        auto Buff =
-            std::make_unique<std::byte[]>(ObjectReprChars.getQuantity());
+        auto Buff = std::make_unique<std::byte[]>(FullBitWidth.roundToBytes());
         // Work around floating point types that contain unused padding bytes.
         // This is really just `long double` on x86, which is the only
         // fundamental type with padding bytes.
@@ -357,11 +359,9 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
       ASTCtx.getTargetInfo().isLittleEndian() ? Endian::Little : Endian::Big;
   bool Success = enumeratePointerFields(
       ToPtr, S.getContext(), Buffer.size(),
-      [&](const Pointer &P, PrimType T, Bits BitOffset,
+      [&](const Pointer &P, PrimType T, Bits BitOffset, Bits FullBitWidth,
           bool PackedBools) -> bool {
         QualType PtrType = P.getType();
-        CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars(PtrType);
-        Bits FullBitWidth = Bits(ASTCtx.toBits(ObjectReprChars));
         if (T == PT_Float) {
           const auto &Semantics = ASTCtx.getFloatTypeSemantics(PtrType);
           Bits NumBits = Bits(llvm::APFloatBase::getSizeInBits(Semantics));

@tbaederr tbaederr merged commit 74393f3 into llvm:main Dec 11, 2024
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

2 participants