On Apr 13, 2010, at 3:04 PM, Nuno Lopes wrote: > Thanks! > I assume it's now ok to turn padding into undef again? (btw, do you want to > review the patch before commit?)
Yes, iff it doesn't break anything. Please verify that sqlite works in the jit etc, -Chris > > Nuno > > ----- Original Message ----- > From: "Chris Lattner" <[email protected]> > To: <[email protected]> > Sent: Tuesday, April 13, 2010 7:16 PM > Subject: [cfe-commits] r101155 - in > /cfe/trunk:lib/CodeGen/CGExprConstant.cpp test/CodeGen/decl.c > > >> Author: lattner >> Date: Tue Apr 13 13:16:19 2010 >> New Revision: 101155 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=101155&view=rev >> Log: >> Rework the ConstStructBuilder code to emit missing initializer >> elements with explicit zero values instead of with tail padding. >> On an example like this: >> >> struct foo { int a; int b; }; >> >> struct foo fooarray[] = { >> {1, 2}, >> {4}, >> }; >> >> We now lay this out as: >> >> @fooarray = global [2 x %struct.foo] [%struct.foo { i32 1, i32 2 }, >> %struct.foo { i32 4, i32 0 }] >> >> instead of as: >> >> @fooarray = global %0 <{ %struct.foo { i32 1, i32 2 }, %1 { i32 4, [4 x >> i8] zeroinitializer } }> >> >> Preserving both the struct type of the second element, but also the array >> type of the entire thing. >> >> >> Modified: >> cfe/trunk/lib/CodeGen/CGExprConstant.cpp >> cfe/trunk/test/CodeGen/decl.c >> >> Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=101155&r1=101154&r2=101155&view=diff >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original) >> +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Apr 13 13:16:19 2010 >> @@ -50,10 +50,10 @@ >> LLVMStructAlignment(1) { } >> >> bool AppendField(const FieldDecl *Field, uint64_t FieldOffset, >> - const Expr *InitExpr); >> + llvm::Constant *InitExpr); >> >> bool AppendBitField(const FieldDecl *Field, uint64_t FieldOffset, >> - const Expr *InitExpr); >> + llvm::Constant *InitExpr); >> >> void AppendPadding(uint64_t NumBytes); >> >> @@ -74,18 +74,18 @@ >> }; >> >> bool ConstStructBuilder:: >> -AppendField(const FieldDecl *Field, uint64_t FieldOffset, const Expr >> *InitExpr){ >> +AppendField(const FieldDecl *Field, uint64_t FieldOffset, >> + llvm::Constant *InitCst) { >> uint64_t FieldOffsetInBytes = FieldOffset / 8; >> >> assert(NextFieldOffsetInBytes <= FieldOffsetInBytes >> && "Field offset mismatch!"); >> >> // Emit the field. >> - llvm::Constant *C = CGM.EmitConstantExpr(InitExpr, Field->getType(), >> CGF); >> - if (!C) >> + if (!InitCst) >> return false; >> >> - unsigned FieldAlignment = getAlignment(C); >> + unsigned FieldAlignment = getAlignment(InitCst); >> >> // Round up the field offset to the alignment of the field type. >> uint64_t AlignedNextFieldOffsetInBytes = >> @@ -111,8 +111,9 @@ >> } >> >> // Add the field. >> - Elements.push_back(C); >> - NextFieldOffsetInBytes = AlignedNextFieldOffsetInBytes + >> getSizeInBytes(C); >> + Elements.push_back(InitCst); >> + NextFieldOffsetInBytes = AlignedNextFieldOffsetInBytes + >> + getSizeInBytes(InitCst); >> >> if (Packed) >> assert(LLVMStructAlignment == 1 && "Packed struct not byte-aligned!"); >> @@ -124,11 +125,8 @@ >> >> bool ConstStructBuilder:: >> AppendBitField(const FieldDecl *Field, uint64_t FieldOffset, >> - const Expr *InitExpr) { >> - llvm::ConstantInt *CI = >> - cast_or_null<llvm::ConstantInt>(CGM.EmitConstantExpr(InitExpr, >> - >> Field->getType(), >> - CGF)); >> + llvm::Constant *InitCst) { >> + llvm::ConstantInt *CI = cast_or_null<llvm::ConstantInt>(InitCst); >> // FIXME: Can this ever happen? >> if (!CI) >> return false; >> @@ -323,26 +321,34 @@ >> unsigned FieldNo = 0; >> unsigned ElementNo = 0; >> for (RecordDecl::field_iterator Field = RD->field_begin(), >> - FieldEnd = RD->field_end(); >> - ElementNo < ILE->getNumInits() && Field != FieldEnd; >> - ++Field, ++FieldNo) { >> + FieldEnd = RD->field_end(); Field != FieldEnd; ++Field, ++FieldNo) >> { >> + >> + // If this is a union, skip all the fields that aren't being >> initialized. >> if (RD->isUnion() && ILE->getInitializedFieldInUnion() != *Field) >> continue; >> >> - if (Field->isBitField()) { >> - if (!Field->getIdentifier()) >> - continue; >> + // Don't emit anonymous bitfields, they just affect layout. >> + if (Field->isBitField() && !Field->getIdentifier()) >> + continue; >> >> - if (!AppendBitField(*Field, Layout.getFieldOffset(FieldNo), >> - ILE->getInit(ElementNo))) >> + // Get the initializer. A struct can include fields without >> initializers, >> + // we just use explicit null values for them. >> + llvm::Constant *EltInit; >> + if (ElementNo < ILE->getNumInits()) >> + EltInit = CGM.EmitConstantExpr(ILE->getInit(ElementNo++), >> + Field->getType(), CGF); >> + else >> + EltInit = CGM.EmitNullConstant(Field->getType()); >> + >> + if (!Field->isBitField()) { >> + // Handle non-bitfield members. >> + if (!AppendField(*Field, Layout.getFieldOffset(FieldNo), EltInit)) >> return false; >> } else { >> - if (!AppendField(*Field, Layout.getFieldOffset(FieldNo), >> - ILE->getInit(ElementNo))) >> + // Otherwise we have a bitfield. >> + if (!AppendBitField(*Field, Layout.getFieldOffset(FieldNo), >> EltInit)) >> return false; >> } >> - >> - ElementNo++; >> } >> >> uint64_t LayoutSizeInBytes = Layout.getSize() / 8; >> >> Modified: cfe/trunk/test/CodeGen/decl.c >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/decl.c?rev=101155&r1=101154&r2=101155&view=diff >> ============================================================================== >> --- cfe/trunk/test/CodeGen/decl.c (original) >> +++ cfe/trunk/test/CodeGen/decl.c Tue Apr 13 13:16:19 2010 >> @@ -5,7 +5,10 @@ >> // CHECK: @test5w = global %0 { i32 2, [4 x i8] zeroinitializer } >> // CHECK: @test5y = global %union.test5u { double 7.300000e+0{{[0]*}}1 } >> >> -// CHECK: @test6.x = internal constant %1 { i8 1, i8 2, i32 3, [4 x i8] >> zeroinitializer } >> +// CHECK: @test6.x = internal constant %struct.SelectDest { i8 1, i8 2, >> i32 3, i32 0 } >> + >> +// CHECK: @test7 = global [2 x %struct.test7s] [%struct.test7s { i32 1, >> i32 2 }, %struct.test7s { i32 4, i32 0 }] >> + >> void test1() { >> // This should codegen as a "@test1.x" global. >> const int x[] = { 1, 2, 3, 4, 6, 8, 9, 10, 123, 231, 123,23 }; >> @@ -74,3 +77,10 @@ >> struct SelectDest x = {1, 2, 3}; >> test6f(&x); >> } >> + >> +// rdar://7657600 >> +struct test7s { int a; int b; } test7[] = { >> + {1, 2}, >> + {4}, >> +}; >> + >> >> >> _______________________________________________ >> cfe-commits mailing list >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
