[cfe-commits] r101155 - in /cfe/trunk:lib/CodeGen/CGExprConstant.cpp test/CodeGen/decl.c
Chris Lattner
clattner at apple.com
Tue Apr 13 15:43:42 PDT 2010
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" <sabre at nondot.org>
> To: <cfe-commits at cs.uiuc.edu>
> 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
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list