[llvm-commits] [gcc-plugin] r76227 - /gcc-plugin/trunk/llvm-types.cpp

Duncan Sands baldrick at free.fr
Fri Jul 17 13:31:27 PDT 2009


Author: baldrick
Date: Fri Jul 17 15:31:00 2009
New Revision: 76227

URL: http://llvm.org/viewvc/llvm-project?rev=76227&view=rev
Log:
Remove all the code which works around gcc bugs by
correcting gcc type trees.  If these gcc bugs still
exist then they can be fixed in gcc mainline.

Modified:
    gcc-plugin/trunk/llvm-types.cpp

Modified: gcc-plugin/trunk/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/llvm-types.cpp?rev=76227&r1=76226&r2=76227&view=diff

==============================================================================
--- gcc-plugin/trunk/llvm-types.cpp (original)
+++ gcc-plugin/trunk/llvm-types.cpp Fri Jul 17 15:31:00 2009
@@ -1632,237 +1632,6 @@
 
 }
 
-/// 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;
-
-/// 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
-/// size of its Record type.  This may indicate the situation where a base class
-/// has virtual base classes which are not allocated.  Replace Field's original
-/// type with a modified one reflecting what actually gets allocated.
-///
-/// This can also occur when a class has an empty base class; the class will
-/// have size N+4 and the field size N+1.  In this case the fields will add
-/// up to N+4, so we haven't really changed anything.
-
-static tree FixBaseClassField(tree Field) {
-  tree oldTy = TREE_TYPE(Field);
-  tree &newTy = BaseTypesMap[oldTy];
-  // If already in table, reuse.
-  if (!newTy) {
-    newTy = copy_node(oldTy);
-    tree F2 = 0, prevF2 = 0, F;
-    // Copy the fields up to the TYPE_DECL separator.
-    // VAR_DECLs can also appear, representing static members.  Possibly some
-    // other junk I haven't hit yet, just skip anything that's not a FIELD:(
-    for (F = TYPE_FIELDS(oldTy); F; prevF2 = F2, F = TREE_CHAIN(F)) {
-      if (TREE_CODE(F) == TYPE_DECL)
-        break;
-      if (TREE_CODE(F) == FIELD_DECL) {
-        F2 = copy_node(F);
-        if (prevF2)
-          TREE_CHAIN(prevF2) = F2;
-        else
-          TYPE_FIELDS(newTy) = F2;
-        TREE_CHAIN(F2) = 0;
-      }
-    }
-    // If we didn't find a TYPE_DECL this isn't the virtual base class case.
-    // The ObjC trees for bitfield instance variables can look similar enough
-    // 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;
-      return oldTy;
-    }
-    BaseTypesMap[oldTy] = newTy;
-    BaseTypesMap[newTy] = oldTy;
-    // Prevent gcc's garbage collector from destroying newTy.  The
-    // GC code doesn't understand DenseMaps:(
-    llvm_note_type_used(newTy);
-    TYPE_SIZE(newTy) = DECL_SIZE(Field);
-    TYPE_SIZE_UNIT(newTy) = DECL_SIZE_UNIT(Field);
-    // If the alignment of the field is smaller than the alignment of the type,
-    // we may not need tail padding in this context.
-    if (DECL_ALIGN(Field) < TYPE_ALIGN(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)+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");
-      TYPE_NAME(newTy) = get_identifier(q);
-      free(q);
-    }
-  }
-  return newTy;
-}
-
-/// FixUpFields - alter the types referred to by Field nodes that
-/// represent base classes to reflect reality. 
-//
-// Suppose we're converting type T.  Look for the case where a base class A
-// of T contains a virtual base class B, and B is not allocated when A is 
-// used as the base class of T.  This is indicated by the FIELD node for A
-// having a size smaller than the size of A, and the chain of fields for A
-// having a TYPE_DECL node in the middle of it; that node comes after the
-// allocated fields and before the unallocated virtual base classes.  Create
-// a new type A.base for LLVM purposes which does not contain the virtual
-// base classes.  (Where A is a virtual base class of T, there is also a BINFO
-// 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.
-
-static void FixUpFields(tree type) {
-  if (TREE_CODE(type)!=RECORD_TYPE)
-    return;
-  for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) {
-    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) &&
-        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 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.
-  // Earlier, the sizes in the field types were also wrong in a way that
-  // compensated as far as LLVM's translation code is concerned; now we
-  // have fixed that, and have to fix the size also.
-  if (TYPE_SIZE (type) && TREE_CODE(TYPE_SIZE(type)) == INTEGER_CST) {
-    // This computes (size+align-1) & ~(align-1)
-    // NB "sizetype" is #define'd in one of the gcc headers.  Gotcha!
-    tree size_type = TREE_TYPE(TYPE_SIZE(type));
-    tree alignm1 = fold_build2(PLUS_EXPR, size_type,
-                                build_int_cst(size_type, TYPE_ALIGN(type)),
-                                fold_build1(NEGATE_EXPR, size_type,
-                                          build_int_cst(size_type, 1)));
-    tree lhs = fold_build2(PLUS_EXPR, size_type, TYPE_SIZE(type), alignm1);
-    tree rhs = fold_build1(BIT_NOT_EXPR, size_type, alignm1);
-    TYPE_SIZE(type) = fold_build2(BIT_AND_EXPR, size_type, lhs, rhs);
-
-    size_type = TREE_TYPE(TYPE_SIZE_UNIT(type));
-    alignm1 = fold_build2(PLUS_EXPR, size_type,
-                                build_int_cst(size_type, TYPE_ALIGN_UNIT(type)),
-                                fold_build1(NEGATE_EXPR, size_type,
-                                        build_int_cst(size_type, 1)));
-    lhs = fold_build2(PLUS_EXPR, size_type, TYPE_SIZE_UNIT(type), alignm1);
-    rhs = fold_build1(BIT_NOT_EXPR, size_type, alignm1);
-    TYPE_SIZE_UNIT(type) = fold_build2(BIT_AND_EXPR, size_type, lhs, rhs);
-  }
-}
-
-// RestoreOriginalFields - put things back the way they were so the C++FE
-// code continues to work (there are pointers stashed away in there).
-
-static void RestoreOriginalFields(tree type) {
-  if (TREE_CODE(type)!=RECORD_TYPE)
-    return;
-  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)];
-        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;
-      }
-    }
-  }
-}
-
 /// DecodeStructFields - This method decodes the specified field, if it is a
 /// FIELD_DECL, adding or updating the specified StructTypeConversionInfo to
 /// reflect it.  Return tree if field is decoded correctly. Otherwise return
@@ -2099,12 +1868,6 @@
     new StructTypeConversionInfo(*TheTarget, TYPE_ALIGN(type) / 8,
                                  TYPE_PACKED(type));
 
-  // Alter any fields that appear to represent base classes so their lists
-  // of fields bear some resemblance to reality.  Also alter any fields that
-  // are less aligned than their type, as the type may not get tail padding
-  // in this case.
-  FixUpFields(type);
-
   // Convert over all of the elements of the struct.
   bool retryAsPackedStruct = false;
   for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) {
@@ -2210,10 +1973,6 @@
              "Wrong LLVM field offset!");
     }
 
-  // Put the original gcc struct back the way it was; necessary to prevent the
-  // binfo-walking code in cp/class from getting confused.
-  RestoreOriginalFields(type);
-
   const Type *ResultTy = Info->getLLVMType();
   StructTypeInfoMap[type] = Info;
 





More information about the llvm-commits mailing list