llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> 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 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)); `````````` </details> https://github.com/llvm/llvm-project/pull/119392 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits