================ @@ -2538,6 +2541,311 @@ static RValue EmitHipStdParUnsupportedBuiltin(CodeGenFunction *CGF, return RValue::get(CGF->Builder.CreateCall(UBF, Args)); } +namespace { + +struct PaddingClearer { + PaddingClearer(CodeGenFunction &F) + : CGF(F), CharWidth(CGF.getContext().getCharWidth()) {} + + void run(Value *Ptr, QualType Ty) { + OccuppiedIntervals.clear(); + Queue.clear(); + + Queue.push_back(Data{0, Ty, true}); + while (!Queue.empty()) { + auto Current = Queue.front(); + Queue.pop_front(); + Visit(Current); + } + + MergeOccuppiedIntervals(); + auto PaddingIntervals = + GetPaddingIntervals(CGF.getContext().getTypeSize(Ty)); + llvm::dbgs() << "Occuppied Bits:\n"; + for (auto [first, last] : OccuppiedIntervals) { + llvm::dbgs() << "[" << first << ", " << last << ")\n"; + } + llvm::dbgs() << "Padding Bits:\n"; + for (auto [first, last] : PaddingIntervals) { + llvm::dbgs() << "[" << first << ", " << last << ")\n"; + } + + for (const auto &Interval : PaddingIntervals) { + ClearPadding(Ptr, Interval); + } + } + +private: + struct BitInterval { + // [First, Last) + uint64_t First; + uint64_t Last; + }; + + struct Data { + uint64_t StartBitOffset; + QualType Ty; + bool VisitVirtualBase; + }; + + void Visit(Data const &D) { + if (auto *AT = dyn_cast<ConstantArrayType>(D.Ty)) { + VisitArray(AT, D.StartBitOffset); + return; + } + + if (auto *Record = D.Ty->getAsCXXRecordDecl()) { + VisitStruct(Record, D.StartBitOffset, D.VisitVirtualBase); + return; + } + + if (D.Ty->isAtomicType()) { + auto Unwrapped = D; + Unwrapped.Ty = D.Ty.getAtomicUnqualifiedType(); + Queue.push_back(Unwrapped); + return; + } + + if (const auto *Complex = D.Ty->getAs<ComplexType>()) { + VisitComplex(Complex, D.StartBitOffset); + return; + } + + auto *Type = CGF.ConvertTypeForMem(D.Ty); + auto SizeBit = CGF.CGM.getModule() + .getDataLayout() + .getTypeSizeInBits(Type) + .getKnownMinValue(); + llvm::dbgs() << "clear_padding primitive type. adding Interval [" + << D.StartBitOffset << ", " << D.StartBitOffset + SizeBit + << ")\n"; + OccuppiedIntervals.push_back( + BitInterval{D.StartBitOffset, D.StartBitOffset + SizeBit}); + } + + void VisitArray(const ConstantArrayType *AT, uint64_t StartBitOffset) { + llvm::dbgs() << "clear_padding visiting constant array starting from " + << StartBitOffset << "\n"; + for (uint64_t ArrIndex = 0; ArrIndex < AT->getSize().getLimitedValue(); + ++ArrIndex) { + + QualType ElementQualType = AT->getElementType(); + auto ElementSize = CGF.getContext().getTypeSizeInChars(ElementQualType); + auto ElementAlign = CGF.getContext().getTypeAlignInChars(ElementQualType); + auto Offset = ElementSize.alignTo(ElementAlign); + + Queue.push_back( + Data{StartBitOffset + ArrIndex * Offset.getQuantity() * CharWidth, + ElementQualType, true}); + } + } + + void VisitStruct(const CXXRecordDecl *R, uint64_t StartBitOffset, + bool VisitVirtualBase) { + llvm::dbgs() << "clear_padding visiting struct: " + << R->getQualifiedNameAsString() << " starting from offset " + << StartBitOffset << '\n'; + const auto &DL = CGF.CGM.getModule().getDataLayout(); + + const ASTRecordLayout &ASTLayout = CGF.getContext().getASTRecordLayout(R); + if (ASTLayout.hasOwnVFPtr()) { + llvm::dbgs() + << "clear_padding found vtable ptr. Adding occuppied interval [" + << StartBitOffset << ", " + << (StartBitOffset + DL.getPointerSizeInBits()) << ")\n"; + OccuppiedIntervals.push_back(BitInterval{ + StartBitOffset, StartBitOffset + DL.getPointerSizeInBits()}); + } + + const auto VisitBase = [&ASTLayout, StartBitOffset, this]( + const CXXBaseSpecifier &Base, auto GetOffset) { + auto *BaseRecord = Base.getType()->getAsCXXRecordDecl(); + if (!BaseRecord) { + llvm::dbgs() << "Base is not a CXXRecord!\n"; + return; + } + auto BaseOffset = + std::invoke(GetOffset, ASTLayout, BaseRecord).getQuantity(); + + llvm::dbgs() << "visiting base at offset " << StartBitOffset << " + " + << BaseOffset * CharWidth << '\n'; + Queue.push_back( + Data{StartBitOffset + BaseOffset * CharWidth, Base.getType(), false}); ---------------- efriedma-quic wrote:
```suggestion Data{StartBitOffset + BaseOffset * CharWidth, Base.getType(), /*VisitVirtualBase*/false}); ``` https://github.com/llvm/llvm-project/pull/75371 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits