This initial code is meant to convert TargetData to use an AbstractTypesUser so
authorBill Wendling <isanbard@gmail.com>
Thu, 3 Dec 2009 00:17:12 +0000 (00:17 +0000)
committerBill Wendling <isanbard@gmail.com>
Thu, 3 Dec 2009 00:17:12 +0000 (00:17 +0000)
that it doesn't have dangling pointers when abstract types are resolved. This
modifies it somewhat to address comments: making the "StructLayoutMap" an
anonymous structure, calling "removeAbstractTypeUser" when appropriate, and
adding asserts where helpful.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90362 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetData.h
lib/Target/TargetData.cpp

index e1d052edbe1ca5b94c5c76298be7be63eee34ccb..5ed0f13ef0f671e50a15778564654959de6c1cce 100644 (file)
@@ -30,7 +30,6 @@ class Type;
 class IntegerType;
 class StructType;
 class StructLayout;
-class StructLayoutMap;
 class GlobalVariable;
 class LLVMContext;
 
@@ -86,7 +85,7 @@ private:
   static const TargetAlignElem InvalidAlignmentElem;
 
   // The StructType -> StructLayout map.
-  mutable StructLayoutMap *LayoutMap;
+  mutable void *LayoutMap;
 
   //! Set/initialize target alignments
   void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
index fc71bc3ab1fe06de9a704bc0c8cd98d465d93bc6..ec00f9e2e9abb480cf5a49d689e95211aaeaaf1d 100644 (file)
@@ -325,7 +325,7 @@ unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType,
 
 typedef DenseMap<const StructType*, StructLayout*> LayoutInfoTy;
 
-namespace llvm {
+namespace {
 
 class StructLayoutMap : public AbstractTypeUser {
   LayoutInfoTy LayoutInfo;
@@ -337,18 +337,12 @@ class StructLayoutMap : public AbstractTypeUser {
   virtual void refineAbstractType(const DerivedType *OldTy,
                                   const Type *) {
     const StructType *STy = dyn_cast<const StructType>(OldTy);
-    if (!STy) {
-      OldTy->removeAbstractTypeUser(this);
-      return;
-    }
-
-    StructLayout *SL = LayoutInfo[STy];
-    if (SL) {
-      SL->~StructLayout();
-      free(SL);
-      LayoutInfo[STy] = NULL;
-    }
+    assert(STy && "This can only track struct types.");
 
+    LayoutInfoTy::iterator Iter = LayoutInfo.find(STy);
+    Iter->second->~StructLayout();
+    free(Iter->second);
+    LayoutInfo.erase(Iter);
     OldTy->removeAbstractTypeUser(this);
   }
 
@@ -359,69 +353,46 @@ class StructLayoutMap : public AbstractTypeUser {
   ///
   virtual void typeBecameConcrete(const DerivedType *AbsTy) {
     const StructType *STy = dyn_cast<const StructType>(AbsTy);
-    if (!STy) {
-      AbsTy->removeAbstractTypeUser(this);
-      return;
-    }
-
-    StructLayout *SL = LayoutInfo[STy];
-    if (SL) {
-      SL->~StructLayout();
-      free(SL);
-      LayoutInfo[STy] = NULL;
-    }
+    assert(STy && "This can only track struct types.");
 
+    LayoutInfoTy::iterator Iter = LayoutInfo.find(STy);
+    Iter->second->~StructLayout();
+    free(Iter->second);
+    LayoutInfo.erase(Iter);
     AbsTy->removeAbstractTypeUser(this);
   }
 
-  bool insert(const Type *Ty) {
-    if (Ty->isAbstract())
-      Ty->addAbstractTypeUser(this);
-    return true;
-  }
-
 public:
   virtual ~StructLayoutMap() {
     // Remove any layouts.
     for (LayoutInfoTy::iterator
-           I = LayoutInfo.begin(), E = LayoutInfo.end(); I != E; ++I)
-      if (StructLayout *SL = I->second) {
-        SL->~StructLayout();
-        free(SL);
+           I = LayoutInfo.begin(), E = LayoutInfo.end(); I != E; ++I) {
+      const Type *Key = I->first;
+      StructLayout *Value = I->second;
+
+      if (Key && Key->isAbstract())
+        Key->removeAbstractTypeUser(this);
+
+      if (Value) {
+        Value->~StructLayout();
+        free(Value);
       }
+    }
   }
 
-  inline LayoutInfoTy::iterator begin() {
-    return LayoutInfo.begin();
-  }
-  inline LayoutInfoTy::iterator end() {
-    return LayoutInfo.end();
-  }
-  inline LayoutInfoTy::const_iterator begin() const {
-    return LayoutInfo.begin();
-  }
-  inline LayoutInfoTy::const_iterator end() const {
+  LayoutInfoTy::iterator end() {
     return LayoutInfo.end();
   }
 
   LayoutInfoTy::iterator find(const StructType *&Val) {
     return LayoutInfo.find(Val);
   }
-  LayoutInfoTy::const_iterator find(const StructType *&Val) const {
-    return LayoutInfo.find(Val);
-  }
 
-  bool erase(const StructType *&Val) {
-    return LayoutInfo.erase(Val);
-  }
   bool erase(LayoutInfoTy::iterator I) {
     return LayoutInfo.erase(I);
   }
 
-  StructLayout *&operator[](const Type *Key) {
-    const StructType *STy = dyn_cast<const StructType>(Key);
-    assert(STy && "Trying to access the struct layout map with a non-struct!");
-    insert(STy);
+  StructLayout *&operator[](const StructType *STy) {
     return LayoutInfo[STy];
   }
 
@@ -432,14 +403,15 @@ public:
 } // end namespace llvm
 
 TargetData::~TargetData() {
-  delete LayoutMap;
+  delete static_cast<StructLayoutMap*>(LayoutMap);
 }
 
 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
   if (!LayoutMap)
     LayoutMap = new StructLayoutMap();
   
-  StructLayout *&SL = (*LayoutMap)[Ty];
+  StructLayoutMap *STM = static_cast<StructLayoutMap*>(LayoutMap);
+  StructLayout *&SL = (*STM)[Ty];
   if (SL) return SL;
 
   // Otherwise, create the struct layout.  Because it is variable length, we 
@@ -453,6 +425,10 @@ const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
   SL = L;
   
   new (L) StructLayout(Ty, *this);
+
+  if (Ty->isAbstract())
+    Ty->addAbstractTypeUser(STM);
+
   return L;
 }
 
@@ -463,14 +439,17 @@ const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
 void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
   if (!LayoutMap) return;  // No cache.
   
-  DenseMap<const StructType*, StructLayout*>::iterator I = LayoutMap->find(Ty);
-  if (I == LayoutMap->end()) return;
+  StructLayoutMap *STM = static_cast<StructLayoutMap*>(LayoutMap);
+  LayoutInfoTy::iterator I = STM->find(Ty);
+  if (I == STM->end()) return;
   
   I->second->~StructLayout();
   free(I->second);
-  LayoutMap->erase(I);
-}
+  STM->erase(I);
 
+  if (Ty->isAbstract())
+    Ty->removeAbstractTypeUser(STM);
+}
 
 std::string TargetData::getStringRepresentation() const {
   std::string Result;