[llvm-commits] [llvm-gcc-4.2] r81399 - in /llvm-gcc-4.2/trunk/gcc: llvm-types.cpp tree.h

Daniel Dunbar daniel at zuster.org
Wed Sep 16 00:06:26 PDT 2009


Nevermind, I see it was the next commit.

On Wed, Sep 16, 2009 at 12:05 AM, Daniel Dunbar <daniel at zuster.org> wrote:
> Hi Dale,
>
> Is there a testcase for this?
>
>  - Daniel
>
> On Wed, Sep 9, 2009 at 4:36 PM, Dale Johannesen <dalej at apple.com> wrote:
>> Author: johannes
>> Date: Wed Sep  9 18:36:04 2009
>> New Revision: 81399
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=81399&view=rev
>> Log:
>> In the presence of #pragma pack, layouts
>> can be created where a base class has different alignments
>> in different derived classes.  The code for dealing with
>> base classes wasn't handling this correctly, leading to
>> assertions.  Rewrite the base class remapper to key off
>> a <type, alignment> pair instead of handling the size and
>> alignment cases separately.
>>
>>
>> Modified:
>>    llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
>>    llvm-gcc-4.2/trunk/gcc/tree.h
>>
>> Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=81399&r1=81398&r2=81399&view=diff
>>
>> ==============================================================================
>> --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
>> +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Wed Sep  9 18:36:04 2009
>> @@ -1685,10 +1685,7 @@
>>  }
>>
>>  /// Mapping from type to type-used-as-base-class and back.
>> -static DenseMap<tree, tree> BaseTypesMap;
>> -
>> -/// Mapping from type to less-aligned-type-used-within-struct and back.
>> -static DenseMap<std::pair<tree, unsigned int>, tree> LessAlignedTypesMap;
>> +static DenseMap<std::pair<tree, unsigned int>, tree > BaseTypesMap;
>>
>>  /// FixBaseClassField - This method is called when we have a field Field
>>  /// of Record type within a Record, and the size of Field is smaller than the
>> @@ -1702,7 +1699,9 @@
>>
>>  static tree FixBaseClassField(tree Field) {
>>   tree oldTy = TREE_TYPE(Field);
>> -  tree newTy = BaseTypesMap[oldTy];
>> +  std::pair<tree, unsigned int> p = std::make_pair(oldTy,
>> +                     std::min(DECL_ALIGN(Field), TYPE_ALIGN(oldTy)));
>> +  tree newTy = BaseTypesMap[p];
>>   // If already in table, reuse.
>>   if (!newTy) {
>>     newTy = copy_node(oldTy);
>> @@ -1727,11 +1726,11 @@
>>     // to the C++ virtual base case to get this far, but these don't have
>>     // the TYPE_DECL sentinel, nor the virtual base class allocation problem.
>>     if (!F || TREE_CODE(F) != TYPE_DECL) {
>> -      BaseTypesMap[oldTy] = oldTy;
>> +      BaseTypesMap[p] = oldTy;
>>       return oldTy;
>>     }
>> -    BaseTypesMap[oldTy] = newTy;
>> -    BaseTypesMap[newTy] = oldTy;
>> +    BaseTypesMap[p] = newTy;
>> +    BaseTypesMap[std::make_pair(newTy, 0U)] = oldTy;
>>     // Prevent gcc's garbage collector from destroying newTy.  The
>>     // GC code doesn't understand DenseMaps:(
>>     llvm_note_type_used(newTy);
>> @@ -1750,57 +1749,8 @@
>>         p = IDENTIFIER_POINTER(TYPE_NAME(oldTy));
>>       else if (DECL_NAME(TYPE_NAME(oldTy)))
>>         p = IDENTIFIER_POINTER(DECL_NAME(TYPE_NAME(oldTy)));
>> -      char *q = (char *)xmalloc(strlen(p)+6);
>> -      strcpy(q,p);
>> -      strcat(q,".base");
>> -      TYPE_NAME(newTy) = get_identifier(q);
>> -      free(q);
>> -    }
>> -  }
>> -  return newTy;
>> -}
>> -
>> -/// FixLessAlignedClassField - This method is called when we have a field Field
>> -/// of Record type within a Record, and the alignment of Field is smaller than
>> -/// alignment of its Record type.  The field may not get as much tail padding
>> -/// as the type would in other contexts.  Replace Field's original
>> -/// type with a modified one that has the Field's alignment.
>> -
>> -static tree FixLessAlignedClassField(tree Field) {
>> -  tree oldTy = TREE_TYPE(Field);
>> -  std::pair<tree, unsigned int> p = std::make_pair(oldTy, DECL_ALIGN(Field));
>> -  tree newTy = LessAlignedTypesMap[p];
>> -  // If already in table, reuse.
>> -  if (!newTy) {
>> -    newTy = copy_node(oldTy);
>> -    tree F2 = 0, prevF2 = 0, F;
>> -    // Copy all the fields.
>> -    for (F = TYPE_FIELDS(oldTy); F; prevF2 = F2, F = TREE_CHAIN(F)) {
>> -      F2 = copy_node(F);
>> -      if (prevF2)
>> -        TREE_CHAIN(prevF2) = F2;
>> -      else
>> -        TYPE_FIELDS(newTy) = F2;
>> -      TREE_CHAIN(F2) = 0;
>> -    }
>> -    LessAlignedTypesMap[p] = newTy;
>> -    LessAlignedTypesMap[std::make_pair(newTy, 0U)] = oldTy;
>> -    /* Prevent gcc's garbage collector from destroying newTy.  The
>> -       GC code doesn't understand DenseMaps:( */
>> -    llvm_note_type_used(newTy);
>> -    TYPE_ALIGN(newTy) = DECL_ALIGN(Field);
>> -    TYPE_MAIN_VARIANT(newTy) = newTy;
>> -    TYPE_STUB_DECL(newTy) = TYPE_STUB_DECL(oldTy);
>> -    // Change the name.
>> -    if (TYPE_NAME(oldTy)) {
>> -      const char *p = "anon";
>> -      if (TREE_CODE(TYPE_NAME(oldTy)) ==IDENTIFIER_NODE)
>> -        p = IDENTIFIER_POINTER(TYPE_NAME(oldTy));
>> -      else if (DECL_NAME(TYPE_NAME(oldTy)))
>> -        p = IDENTIFIER_POINTER(DECL_NAME(TYPE_NAME(oldTy)));
>> -      char *q = (char *)xmalloc(strlen(p)+7);
>> -      strcpy(q,p);
>> -      strcat(q,".align");
>> +      char *q = (char *)xmalloc(strlen(p)+20);
>> +      sprintf(q, "%s.base.%d", p, TYPE_ALIGN(newTy));
>>       TYPE_NAME(newTy) = get_identifier(q);
>>       free(q);
>>     }
>> @@ -1822,12 +1772,12 @@
>>  // node for it, but not when A is a nonvirtual base class.  So we can't
>>  // use that.)
>>  //
>> -// Also alter the types referred to by Field nodes that have greater alignment
>> -// than the Field does; these might not get the tail padding as a Field that
>> -// they get elsewhere.
>> -//
>> -// Both transformations can be needed for the same type (in different contexts),
>> -// so we need two mappings.
>> +// If #pragma pack is involved, different derived classes may use different
>> +// sizes for the base class.  We also alter the types referred to by Field nodes
>> +// that have greater alignment than the Field does; these might not get the
>> +// tail padding as a Field that they get elsewhere. To handle these additional
>> +// cases the size and alignment of the field are used as parts of the index
>> +// into the map of base classes already created.
>>
>>  static void FixUpFields(tree type) {
>>   if (TREE_CODE(type)!=RECORD_TYPE)
>> @@ -1839,29 +1789,17 @@
>>         TREE_CODE(TREE_TYPE(Field))==RECORD_TYPE &&
>>         TYPE_SIZE(TREE_TYPE(Field)) &&
>>         DECL_SIZE(Field) &&
>> -        TREE_CODE(DECL_SIZE(Field))==INTEGER_CST &&
>> -        TREE_CODE(TYPE_SIZE(TREE_TYPE(Field)))==INTEGER_CST &&
>> -        TREE_INT_CST_LOW(DECL_SIZE(Field)) <
>> -              TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(Field)))) {
>> +        ((TREE_CODE(DECL_SIZE(Field))==INTEGER_CST &&
>> +          TREE_CODE(TYPE_SIZE(TREE_TYPE(Field)))==INTEGER_CST &&
>> +          TREE_INT_CST_LOW(DECL_SIZE(Field)) <
>> +              TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(Field)))) ||
>> +         (DECL_ALIGN(Field) < TYPE_ALIGN(TREE_TYPE(Field))))) {
>>       tree newType = FixBaseClassField(Field);
>>       if (newType != TREE_TYPE(Field)) {
>>         TREE_TYPE(Field) = newType;
>>         DECL_FIELD_BASE_REPLACED(Field) = 1;
>>       }
>>     }
>> -    if (TREE_CODE(Field)==FIELD_DECL &&
>> -        !DECL_BIT_FIELD_TYPE(Field) &&
>> -        TREE_CODE(DECL_FIELD_OFFSET(Field))==INTEGER_CST &&
>> -        TREE_CODE(TREE_TYPE(Field))==RECORD_TYPE &&
>> -        TYPE_SIZE(TREE_TYPE(Field)) &&
>> -        DECL_SIZE(Field) &&
>> -        DECL_ALIGN(Field) < TYPE_ALIGN(TREE_TYPE(Field))) {
>> -      tree newType = FixLessAlignedClassField(Field);
>> -      if (newType != TREE_TYPE(Field)) {
>> -        TREE_TYPE(Field) = newType;
>> -        DECL_FIELD_ALIGN_REPLACED(Field) = 1;
>> -      }
>> -    }
>>   }
>>   // Size of the complete type will be a multiple of its alignment.
>>   // In some cases involving empty C++ classes this is not true coming in.
>> @@ -1900,17 +1838,11 @@
>>   for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) {
>>     if (TREE_CODE(Field) == FIELD_DECL) {
>>       if (DECL_FIELD_BASE_REPLACED(Field)) {
>> -        tree &oldTy = BaseTypesMap[TREE_TYPE(Field)];
>> +        tree &oldTy = BaseTypesMap[std::make_pair(TREE_TYPE(Field), 0U)];
>>         assert(oldTy);
>>         TREE_TYPE(Field) = oldTy;
>>         DECL_FIELD_BASE_REPLACED(Field) = 0;
>>       }
>> -      if (DECL_FIELD_ALIGN_REPLACED(Field)) {
>> -        tree &oldTy = LessAlignedTypesMap[std::make_pair(TREE_TYPE(Field), 0U)];
>> -        assert(oldTy);
>> -        TREE_TYPE(Field) = oldTy;
>> -        DECL_FIELD_ALIGN_REPLACED(Field) = 0;
>> -      }
>>     }
>>   }
>>  }
>> @@ -2111,7 +2043,7 @@
>>  // class D : public virtual B, public virtual C { public: int i3; };
>>  //
>>  // The TYPE nodes gcc builds for classes represent that class as it looks
>> -// standing alone.  Thus B is size 12 and looks like { vptr; i2; baseclass A; }
>> +// standing alone.  Thus B is size 12 and looks like { vptr; i1; baseclass A; }
>>  // However, this is not the layout used when that class is a base class for
>>  // some other class, yet the same TYPE node is still used.  D in the above has
>>  // both a BINFO list entry and a FIELD that reference type B, but the virtual
>>
>> Modified: llvm-gcc-4.2/trunk/gcc/tree.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/tree.h?rev=81399&r1=81398&r2=81399&view=diff
>>
>> ==============================================================================
>> --- llvm-gcc-4.2/trunk/gcc/tree.h (original)
>> +++ llvm-gcc-4.2/trunk/gcc/tree.h Wed Sep  9 18:36:04 2009
>> @@ -2751,10 +2751,6 @@
>>  /* In a FIELD_DECL, marks that the type is temporarily replaced in ConvertType
>>    because it is used as a base class of another type. */
>>  #define DECL_FIELD_BASE_REPLACED(NODE) (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_0)
>> -/* In a FIELD_DECL, marks that the type is temporarily replaced in ConvertType
>> -   because it is used as the type of a field with less alignment than the
>> -   type, which means the type may not get tail padding in this case. */
>> -#define DECL_FIELD_ALIGN_REPLACED(NODE) (FIELD_DECL_CHECK (NODE)->decl_common.gimple_reg_flag)
>>  #endif
>>  /* LLVM LOCAL end */
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>




More information about the llvm-commits mailing list