[cfe-commits] r118491 - in /cfe/trunk/lib/CodeGen: CGRecordLayout.h CGRecordLayoutBuilder.cpp

Nick Lewycky nlewycky at google.com
Mon Nov 8 21:45:57 PST 2010


On 8 November 2010 21:25, Anders Carlsson <andersca at mac.com> wrote:

> Author: andersca
> Date: Mon Nov  8 23:25:47 2010
> New Revision: 118491
>
> URL: http://llvm.org/viewvc/llvm-project?rev=118491&view=rev
> Log:
> Introduce the concept of a non-virtual base type to CGRecordLayoutBuilder
> as a first step towards fixing PR6995.
>

I don't think you meant to commit the printfs.

Nick


> Modified:
>    cfe/trunk/lib/CodeGen/CGRecordLayout.h
>    cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
>
> Modified: cfe/trunk/lib/CodeGen/CGRecordLayout.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayout.h?rev=118491&r1=118490&r2=118491&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGRecordLayout.h (original)
> +++ cfe/trunk/lib/CodeGen/CGRecordLayout.h Mon Nov  8 23:25:47 2010
> @@ -172,9 +172,13 @@
>   void operator=(const CGRecordLayout&); // DO NOT IMPLEMENT
>
>  private:
> -  /// The LLVMType corresponding to this record layout.
> +  /// The LLVM type corresponding to this record layout.
>   const llvm::Type *LLVMType;
>
> +  /// The LLVM type for the non-virtual part of this record layout, used
> for
> +  /// laying out the record as a base.
> +  const llvm::Type *BaseLLVMType;
> +
>   /// Map from (non-bit-field) struct field to the corresponding llvm
> struct
>   /// type field no. This info is populated by record builder.
>   llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
> @@ -192,14 +196,20 @@
>   bool IsZeroInitializable : 1;
>
>  public:
> -  CGRecordLayout(const llvm::Type *T, bool IsZeroInitializable)
> -    : LLVMType(T), IsZeroInitializable(IsZeroInitializable) {}
> +  CGRecordLayout(const llvm::Type *LLVMType, const llvm::Type
> *BaseLLVMType,
> +                 bool IsZeroInitializable)
> +    : LLVMType(LLVMType), BaseLLVMType(BaseLLVMType),
> +    IsZeroInitializable(IsZeroInitializable) {}
>
>   /// \brief Return the LLVM type associated with this record.
>   const llvm::Type *getLLVMType() const {
>     return LLVMType;
>   }
>
> +  const llvm::Type *getBaseLLVMType() const {
> +      return BaseLLVMType;
> +  }
> +
>   /// \brief Check whether this struct can be C++ zero-initialized
>   /// with a zeroinitializer.
>   bool isZeroInitializable() const {
>
> Modified: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp?rev=118491&r1=118490&r2=118491&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Mon Nov  8 23:25:47
> 2010
> @@ -35,6 +35,24 @@
>   /// FieldTypes - Holds the LLVM types that the struct is created from.
>   std::vector<const llvm::Type *> FieldTypes;
>
> +  /// NonVirtualBaseFieldTypes - Holds the LLVM types for the non-virtual
> part
> +  /// of the struct. For example, consider:
> +  ///
> +  /// struct A { int i; };
> +  /// struct B { void *v; };
> +  /// struct C : virtual A, B { };
> +  ///
> +  /// The LLVM type of C will be
> +  /// %struct.C = type { i32 (...)**, %struct.A, i32, %struct.B }
> +  ///
> +  /// And the LLVM type of the non-virtual base struct will be
> +  /// %struct.C.base = type { i32 (...)**, %struct.A, i32 }
> +  std::vector<const llvm::Type *> NonVirtualBaseFieldTypes;
> +
> +  /// NonVirtualBaseTypeIsSameAsCompleteType - Whether the non-virtual
> part of
> +  /// the struct is equivalent to the complete struct.
> +  bool NonVirtualBaseTypeIsSameAsCompleteType;
> +
>   /// LLVMFieldInfo - Holds a field and its corresponding LLVM field
> number.
>   typedef std::pair<const FieldDecl *, unsigned> LLVMFieldInfo;
>   llvm::SmallVector<LLVMFieldInfo, 16> LLVMFields;
> @@ -92,6 +110,9 @@
>   void LayoutNonVirtualBases(const CXXRecordDecl *RD,
>                              const ASTRecordLayout &Layout);
>
> +  /// ComputeNonVirtualBaseType - Compute the non-virtual base field
> types.
> +  void ComputeNonVirtualBaseType(const CXXRecordDecl *RD);
> +
>   /// LayoutField - layout a single field. Returns false if the operation
> failed
>   /// because the current struct is not packed.
>   bool LayoutField(const FieldDecl *D, uint64_t FieldOffset);
> @@ -106,6 +127,10 @@
>   /// struct size is a multiple of the field alignment.
>   void AppendPadding(uint64_t FieldOffsetInBytes, unsigned FieldAlignment);
>
> +  /// getByteArrayType - Returns a byte array type with the given number
> of
> +  /// elements.
> +  const llvm::Type *getByteArrayType(uint64_t NumBytes);
> +
>   /// AppendBytes - Append a given number of bytes to the record.
>   void AppendBytes(uint64_t NumBytes);
>
> @@ -122,8 +147,8 @@
>
>  public:
>   CGRecordLayoutBuilder(CodeGenTypes &Types)
> -    : IsZeroInitializable(true), Packed(false), Types(Types),
> -      Alignment(0), AlignmentAsLLVMStruct(1),
> +    : NonVirtualBaseTypeIsSameAsCompleteType(false),
> IsZeroInitializable(true),
> +      Packed(false), Types(Types), Alignment(0), AlignmentAsLLVMStruct(1),
>       BitsAvailableInLastField(0), NextFieldOffsetInBytes(0) { }
>
>   /// Layout - Will layout a RecordDecl.
> @@ -520,13 +545,50 @@
>   }
>  }
>
> +void
> +CGRecordLayoutBuilder::ComputeNonVirtualBaseType(const CXXRecordDecl *RD)
> {
> +  const ASTRecordLayout &Layout =
> Types.getContext().getASTRecordLayout(RD);
> +
> +  uint64_t AlignedNonVirtualTypeSize =
> +    llvm::RoundUpToAlignment(Layout.getNonVirtualSize(),
> +                             Layout.getNonVirtualAlign()) / 8;
> +
> +
> +  // First check if we can use the same fields as for the complete class.
> +  if (AlignedNonVirtualTypeSize == Layout.getSize() / 8) {
> +    NonVirtualBaseTypeIsSameAsCompleteType = true;
> +    return;
> +  }
> +
> +  NonVirtualBaseFieldTypes = FieldTypes;
> +
> +  // Check if we need padding.
> +  uint64_t AlignedNextFieldOffset =
> +    llvm::RoundUpToAlignment(NextFieldOffsetInBytes,
> AlignmentAsLLVMStruct);
> +
> +  assert(AlignedNextFieldOffset <= AlignedNonVirtualTypeSize &&
> +         "Size mismatch!");
> +
> +  if (AlignedNonVirtualTypeSize == AlignedNextFieldOffset) {
> +    // We don't need any padding.
> +    return;
> +  }
> +
> +  uint64_t NumBytes = AlignedNonVirtualTypeSize - AlignedNextFieldOffset;
> +  NonVirtualBaseFieldTypes.push_back(getByteArrayType(NumBytes));
> +
> +  printf("nvts: %llu, aligned nfo: %llu\n",
> +         AlignedNonVirtualTypeSize, AlignedNextFieldOffset);
> +}
> +
>  bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
>   assert(!D->isUnion() && "Can't call LayoutFields on a union!");
>   assert(Alignment && "Did not set alignment!");
>
>   const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D);
>
> -  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
> +  const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
> +  if (RD)
>     LayoutNonVirtualBases(RD, Layout);
>
>   unsigned FieldNo = 0;
> @@ -540,6 +602,14 @@
>     }
>   }
>
> +  // We've laid out the non-virtual bases and the fields, now compute the
> +  // non-virtual base field types.
> +  if (RD)
> +    ComputeNonVirtualBaseType(RD);
> +
> +  // FIXME: Lay out the virtual bases instead of just treating them as
> tail
> +  // padding.
> +
>   // Append tail padding if necessary.
>   AppendTailPadding(Layout.getSize());
>
> @@ -595,16 +665,22 @@
>   }
>  }
>
> -void CGRecordLayoutBuilder::AppendBytes(uint64_t NumBytes) {
> -  if (NumBytes == 0)
> -    return;
> +const llvm::Type *CGRecordLayoutBuilder::getByteArrayType(uint64_t
> NumBytes) {
> +  assert(NumBytes != 0 && "Empty byte array's aren't allowed.");
>
>   const llvm::Type *Ty = llvm::Type::getInt8Ty(Types.getLLVMContext());
>   if (NumBytes > 1)
>     Ty = llvm::ArrayType::get(Ty, NumBytes);
>
> +  return Ty;
> +}
> +
> +void CGRecordLayoutBuilder::AppendBytes(uint64_t NumBytes) {
> +  if (NumBytes == 0)
> +    return;
> +
>   // Append the padding field
> -  AppendField(NextFieldOffsetInBytes, Ty);
> +  AppendField(NextFieldOffsetInBytes, getByteArrayType(NumBytes));
>  }
>
>  unsigned CGRecordLayoutBuilder::getTypeAlignment(const llvm::Type *Ty)
> const {
> @@ -658,8 +734,18 @@
>                                                Builder.FieldTypes,
>                                                Builder.Packed);
>
> +  const llvm::Type *BaseTy = 0;
> +  if (isa<CXXRecordDecl>(D)) {
> +    if (Builder.NonVirtualBaseTypeIsSameAsCompleteType)
> +      BaseTy = Ty;
> +    else if (!Builder.NonVirtualBaseFieldTypes.empty())
> +      BaseTy = llvm::StructType::get(getLLVMContext(),
> +                                     Builder.NonVirtualBaseFieldTypes,
> +                                     Builder.Packed);
> +  }
> +
>   CGRecordLayout *RL =
> -    new CGRecordLayout(Ty, Builder.IsZeroInitializable);
> +    new CGRecordLayout(Ty, BaseTy, Builder.IsZeroInitializable);
>
>   // Add all the non-virtual base field numbers.
>   RL->NonVirtualBaseFields.insert(Builder.LLVMNonVirtualBases.begin(),
> @@ -684,10 +770,22 @@
>
>  #ifndef NDEBUG
>   // Verify that the computed LLVM struct size matches the AST layout size.
> -  uint64_t TypeSizeInBits = getContext().getASTRecordLayout(D).getSize();
> +  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(D);
> +
> +  uint64_t TypeSizeInBits = Layout.getSize();
>   assert(TypeSizeInBits == getTargetData().getTypeAllocSizeInBits(Ty) &&
>          "Type size mismatch!");
>
> +  if (BaseTy) {
> +    uint64_t AlignedNonVirtualTypeSizeInBits =
> +      llvm::RoundUpToAlignment(Layout.getNonVirtualSize(),
> +                               Layout.getNonVirtualAlign());
> +
> +    assert(AlignedNonVirtualTypeSizeInBits ==
> +           getTargetData().getTypeAllocSizeInBits(BaseTy) &&
> +           "Type size mismatch!");
> +  }
> +
>   // Verify that the LLVM and AST field offsets agree.
>   const llvm::StructType *ST =
>     dyn_cast<llvm::StructType>(RL->getLLVMType());
> @@ -730,6 +828,8 @@
>  void CGRecordLayout::print(llvm::raw_ostream &OS) const {
>   OS << "<CGRecordLayout\n";
>   OS << "  LLVMType:" << *LLVMType << "\n";
> +  if (BaseLLVMType)
> +    OS << "  BaseLLVMType:" << *BaseLLVMType << "\n";
>   OS << "  IsZeroInitializable:" << IsZeroInitializable << "\n";
>   OS << "  BitFields:[\n";
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20101108/aa765bed/attachment.html>


More information about the cfe-commits mailing list