[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