Reapply r99881 with some fixes: only call destructor in releaseMemory!


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99883 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp
index e207f60..7af25dd 100644
--- a/lib/CodeGen/LiveInterval.cpp
+++ b/lib/CodeGen/LiveInterval.cpp
@@ -305,7 +305,6 @@
             do {
               VNInfo *VNI = valnos.back();
               valnos.pop_back();
-              VNI->~VNInfo();
             } while (!valnos.empty() && valnos.back()->isUnused());
           } else {
             ValNo->setIsUnused(true);
@@ -353,7 +352,6 @@
     do {
       VNInfo *VNI = valnos.back();
       valnos.pop_back();
-      VNI->~VNInfo();
     } while (!valnos.empty() && valnos.back()->isUnused());
   } else {
     ValNo->setIsUnused(true);
@@ -581,7 +579,6 @@
           do {
             VNInfo *VNI = valnos.back();
             valnos.pop_back();
-            VNI->~VNInfo();
           } while (!valnos.empty() && valnos.back()->isUnused());
         } else {
           V1->setIsUnused(true);
@@ -658,7 +655,6 @@
   if (UnusedValNo) {
     // Delete the last unused val#.
     valnos.pop_back();
-    UnusedValNo->~VNInfo();
   }
 }
 
@@ -751,7 +747,6 @@
     do {
       VNInfo *VNI = valnos.back();
       valnos.pop_back();
-      VNI->~VNInfo();
     } while (valnos.back()->isUnused());
   } else {
     V1->setIsUnused(true);
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index e657c46..53366b9 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -82,6 +82,11 @@
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 
+static void VNInfoDTor(void* Ptr)
+{
+   reinterpret_cast<VNInfo*>(Ptr)->~VNInfo();
+}
+
 void LiveIntervals::releaseMemory() {
   // Free the live intervals themselves.
   for (DenseMap<unsigned, LiveInterval*>::iterator I = r2iMap_.begin(),
@@ -91,7 +96,7 @@
   r2iMap_.clear();
 
   // Release VNInfo memroy regions after all VNInfo objects are dtor'd.
-  VNInfoAllocator.Reset();
+  VNInfoAllocator.Reset((unsigned)sizeof(VNInfo), alignof<VNInfo>(), VNInfoDTor);
   while (!CloneMIs.empty()) {
     MachineInstr *MI = CloneMIs.back();
     CloneMIs.pop_back();
diff --git a/lib/Support/Allocator.cpp b/lib/Support/Allocator.cpp
index 31b45c8..7433247 100644
--- a/lib/Support/Allocator.cpp
+++ b/lib/Support/Allocator.cpp
@@ -78,6 +78,21 @@
   End = ((char*)CurSlab) + CurSlab->Size;
 }
 
+void BumpPtrAllocator::Reset(size_t Size, size_t Alignment, DTorFunction DTor) {
+  if (Alignment == 0) Alignment = 1;
+  MemSlab *Slab = CurSlab;
+  while (Slab) {
+    char *End = Slab == CurSlab ? CurPtr : (char*)Slab + Slab->Size;
+    for (char *Ptr = (char*)Slab+1; Ptr < End; Ptr += Size) {
+	Ptr = AlignPtr(Ptr, Alignment);
+	if (Ptr + Size <= End)
+	    DTor(Ptr);
+    }
+    Slab = Slab->NextPtr;
+  }
+  Reset();
+}
+
 /// Allocate - Allocate space at the specified alignment.
 ///
 void *BumpPtrAllocator::Allocate(size_t Size, size_t Alignment) {