switch UndefValue and ConstantPointerNull over to DenseMap's for uniquing.
authorChris Lattner <sabre@nondot.org>
Mon, 23 Jan 2012 08:52:32 +0000 (08:52 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 23 Jan 2012 08:52:32 +0000 (08:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148693 91177308-0d34-0410-b5e6-96231b3b80d8

lib/VMCore/Constants.cpp
lib/VMCore/ConstantsContext.h
lib/VMCore/LLVMContextImpl.cpp
lib/VMCore/LLVMContextImpl.h

index d04298f14967de9103eda8f499e62820aad6248d..f2d879428480f07d8d9be35891785fc4adcf22e8 100644 (file)
@@ -1127,13 +1127,29 @@ Constant *ConstantVector::getSplatValue() const {
 //
 
 ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {
-  return Ty->getContext().pImpl->NullPtrConstants.getOrCreate(Ty, 0);
+  OwningPtr<ConstantPointerNull> &Entry =
+    Ty->getContext().pImpl->CPNConstants[Ty];
+  if (Entry == 0)
+    Entry.reset(new ConstantPointerNull(Ty));
+  
+  return Entry.get();
 }
 
 // destroyConstant - Remove the constant from the constant table...
 //
 void ConstantPointerNull::destroyConstant() {
-  getType()->getContext().pImpl->NullPtrConstants.remove(this);
+  // Drop ownership of the CPN object before removing the entry so that it
+  // doesn't get double deleted.
+  LLVMContextImpl::CPNMapTy &CPNConstants = getContext().pImpl->CPNConstants;
+  LLVMContextImpl::CPNMapTy::iterator I = CPNConstants.find(getType());
+  assert(I != CPNConstants.end() && "CPN object not in uniquing map");
+  I->second.take();
+  
+  // Actually remove the entry from the DenseMap now, which won't free the
+  // constant.
+  CPNConstants.erase(I);
+  
+  // Free the constant and any dangling references to it.
   destroyConstantImpl();
 }
 
@@ -1142,13 +1158,28 @@ void ConstantPointerNull::destroyConstant() {
 //
 
 UndefValue *UndefValue::get(Type *Ty) {
-  return Ty->getContext().pImpl->UndefValueConstants.getOrCreate(Ty, 0);
+  OwningPtr<UndefValue> &Entry = Ty->getContext().pImpl->UVConstants[Ty];
+  if (Entry == 0)
+    Entry.reset(new UndefValue(Ty));
+  
+  return Entry.get();
 }
 
 // destroyConstant - Remove the constant from the constant table.
 //
 void UndefValue::destroyConstant() {
-  getType()->getContext().pImpl->UndefValueConstants.remove(this);
+  // Drop ownership of the object before removing the entry so that it
+  // doesn't get double deleted.
+  LLVMContextImpl::UVMapTy &UVConstants = getContext().pImpl->UVConstants;
+  LLVMContextImpl::UVMapTy::iterator I = UVConstants.find(getType());
+  assert(I != UVConstants.end() && "UV object not in uniquing map");
+  I->second.take();
+  
+  // Actually remove the entry from the DenseMap now, which won't free the
+  // constant.
+  UVConstants.erase(I);
+  
+  // Free the constant and any dangling references to it.
   destroyConstantImpl();
 }
 
index fec2be58cfce9f619f85d1bbf070caa513e7b541..4bdeaa78302a371d337132695a457f59408bceeb 100644 (file)
@@ -514,37 +514,6 @@ struct ConstantKeyData<ConstantStruct> {
   }
 };
 
-// ConstantPointerNull does not take extra "value" argument...
-template<class ValType>
-struct ConstantCreator<ConstantPointerNull, PointerType, ValType> {
-  static ConstantPointerNull *create(PointerType *Ty, const ValType &V){
-    return new ConstantPointerNull(Ty);
-  }
-};
-
-template<>
-struct ConstantKeyData<ConstantPointerNull> {
-  typedef char ValType;
-  static ValType getValType(ConstantPointerNull *C) {
-    return 0;
-  }
-};
-
-// UndefValue does not take extra "value" argument...
-template<class ValType>
-struct ConstantCreator<UndefValue, Type, ValType> {
-  static UndefValue *create(Type *Ty, const ValType &V) {
-    return new UndefValue(Ty);
-  }
-};
-
-template<>
-struct ConstantKeyData<UndefValue> {
-  typedef char ValType;
-  static ValType getValType(UndefValue *C) {
-    return 0;
-  }
-};
 
 template<>
 struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType> {
index 7ab3ccec62f312d0038a7feadb4c635abae8f2f1..de851ee4bb263c02e96b34179057360a1ecf5423 100644 (file)
@@ -58,6 +58,8 @@ LLVMContextImpl::~LLVMContextImpl() {
   std::vector<Module*> Modules(OwnedModules.begin(), OwnedModules.end());
   DeleteContainerPointers(Modules);
   
+  // Free the constants.  This is important to do here to ensure that they are
+  // freed before the LeakDetector is torn down.
   std::for_each(ExprConstants.map_begin(), ExprConstants.map_end(),
                 DropReferences());
   std::for_each(ArrayConstants.map_begin(), ArrayConstants.map_end(),
@@ -71,8 +73,8 @@ LLVMContextImpl::~LLVMContextImpl() {
   StructConstants.freeConstants();
   VectorConstants.freeConstants();
   CAZConstants.clear();
-  NullPtrConstants.freeConstants();
-  UndefValueConstants.freeConstants();
+  CPNConstants.clear();
+  UVConstants.clear();
   InlineAsms.freeConstants();
   DeleteContainerSeconds(IntConstants);
   DeleteContainerSeconds(FPConstants);
index f963f639211f70523ad865e30ec7f1a251551f82..9d8722b2722bd693f2c71ce8995ff3807e471b36 100644 (file)
@@ -154,9 +154,11 @@ public:
                             VectorType, ConstantVector> VectorConstantsTy;
   VectorConstantsTy VectorConstants;
   
-  ConstantUniqueMap<char, char, PointerType, ConstantPointerNull>
-    NullPtrConstants;
-  ConstantUniqueMap<char, char, Type, UndefValue> UndefValueConstants;
+  typedef DenseMap<PointerType*, OwningPtr<ConstantPointerNull> > CPNMapTy;
+  CPNMapTy CPNConstants;
+
+  typedef DenseMap<Type*, OwningPtr<UndefValue> > UVMapTy;
+  UVMapTy UVConstants;
   
   DenseMap<std::pair<Function*, BasicBlock*> , BlockAddress*> BlockAddresses;
   ConstantUniqueMap<ExprMapKeyType, const ExprMapKeyType&, Type, ConstantExpr>