Introduce SpecificBumpPtrAllocator, a wrapper for BumpPtrAllocator which allows
authorBenjamin Kramer <benny.kra@googlemail.com>
Tue, 30 Mar 2010 20:16:45 +0000 (20:16 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Tue, 30 Mar 2010 20:16:45 +0000 (20:16 +0000)
only a single type of object to be allocated. Use it to make VNInfo destruction
typesafe.

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

include/llvm/CodeGen/LiveInterval.h
include/llvm/CodeGen/LiveIntervalAnalysis.h
include/llvm/CodeGen/LiveStackAnalysis.h
include/llvm/Support/Allocator.h
lib/CodeGen/LiveInterval.cpp
lib/CodeGen/LiveIntervalAnalysis.cpp
lib/CodeGen/LiveStackAnalysis.cpp
lib/CodeGen/PreAllocSplitting.cpp
lib/Support/Allocator.cpp

index 1f198e6325263712bf4490ac42c490d15fb22390..70e79cebcb1b83c1d7e400ea41e9410e19b00f8d 100644 (file)
@@ -67,7 +67,7 @@ namespace llvm {
     } cr;
 
   public:
-
+    typedef SpecificBumpPtrAllocator<VNInfo> Allocator;
     typedef SmallVector<SlotIndex, 4> KillSet;
 
     /// The ID number of this value.
@@ -365,10 +365,8 @@ namespace llvm {
     /// getNextValue - Create a new value number and return it.  MIIdx specifies
     /// the instruction that defines the value number.
     VNInfo *getNextValue(SlotIndex def, MachineInstr *CopyMI,
-                         bool isDefAccurate, BumpPtrAllocator &VNInfoAllocator){
-      VNInfo *VNI =
-        static_cast<VNInfo*>(VNInfoAllocator.Allocate((unsigned)sizeof(VNInfo),
-                                                      alignof<VNInfo>()));
+                       bool isDefAccurate, VNInfo::Allocator &VNInfoAllocator) {
+      VNInfo *VNI = VNInfoAllocator.Allocate();
       new (VNI) VNInfo((unsigned)valnos.size(), def, CopyMI);
       VNI->setIsDefAccurate(isDefAccurate);
       valnos.push_back(VNI);
@@ -378,11 +376,8 @@ namespace llvm {
     /// Create a copy of the given value. The new value will be identical except
     /// for the Value number.
     VNInfo *createValueCopy(const VNInfo *orig,
-                            BumpPtrAllocator &VNInfoAllocator) {
-      VNInfo *VNI =
-        static_cast<VNInfo*>(VNInfoAllocator.Allocate((unsigned)sizeof(VNInfo),
-                                                      alignof<VNInfo>()));
-    
+                            VNInfo::Allocator &VNInfoAllocator) {
+      VNInfo *VNI = VNInfoAllocator.Allocate();
       new (VNI) VNInfo((unsigned)valnos.size(), *orig);
       valnos.push_back(VNI);
       return VNI;
@@ -422,14 +417,14 @@ namespace llvm {
     /// VNInfoAllocator since it will create a new val#.
     void MergeInClobberRanges(LiveIntervals &li_,
                               const LiveInterval &Clobbers,
-                              BumpPtrAllocator &VNInfoAllocator);
+                              VNInfo::Allocator &VNInfoAllocator);
 
     /// MergeInClobberRange - Same as MergeInClobberRanges except it merge in a
     /// single LiveRange only.
     void MergeInClobberRange(LiveIntervals &li_,
                              SlotIndex Start,
                              SlotIndex End,
-                             BumpPtrAllocator &VNInfoAllocator);
+                             VNInfo::Allocator &VNInfoAllocator);
 
     /// MergeValueInAsValue - Merge all of the live ranges of a specific val#
     /// in RHS into this live interval as the specified value number.
@@ -449,7 +444,7 @@ namespace llvm {
     /// Copy - Copy the specified live interval. This copies all the fields
     /// except for the register of the interval.
     void Copy(const LiveInterval &RHS, MachineRegisterInfo *MRI,
-              BumpPtrAllocator &VNInfoAllocator);
+              VNInfo::Allocator &VNInfoAllocator);
     
     bool empty() const { return ranges.empty(); }
 
index 1a2cc25ba490f1a1dda0ed7340e0cd72cef5bd2f..8ddcac705990ca0754a3d655f1b6c33071ebcf06 100644 (file)
@@ -55,7 +55,7 @@ namespace llvm {
 
     /// Special pool allocator for VNInfo's (LiveInterval val#).
     ///
-    BumpPtrAllocator VNInfoAllocator;
+    VNInfo::Allocator VNInfoAllocator;
 
     typedef DenseMap<unsigned, LiveInterval*> Reg2IntervalMap;
     Reg2IntervalMap r2iMap_;
@@ -221,7 +221,7 @@ namespace llvm {
       indexes_->renumberIndexes();
     }
 
-    BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; }
+    VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
 
     /// getVNInfoSourceReg - Helper function that parses the specified VNInfo
     /// copy field and returns the source register that defines it.
index e01d1aea7e83b2c0d062da08c3b0ec2589e53333..c6af6a1f89ce5ebe4edbba337cc82fde6de60bb0 100644 (file)
@@ -27,7 +27,7 @@ namespace llvm {
   class LiveStacks : public MachineFunctionPass {
     /// Special pool allocator for VNInfo's (LiveInterval val#).
     ///
-    BumpPtrAllocator VNInfoAllocator;
+    VNInfo::Allocator VNInfoAllocator;
 
     /// S2IMap - Stack slot indices to live interval mapping.
     ///
@@ -91,7 +91,7 @@ namespace llvm {
       return I->second;
     }
 
-    BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; }
+    VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
 
     virtual void getAnalysisUsage(AnalysisUsage &AU) const;
     virtual void releaseMemory();
index a58b9db27faafc3b4aa58adb3c5ae9f75eb17ee7..bd381807e0c6d2dfb2fea8870f4ae32c4a8f24aa 100644 (file)
@@ -133,8 +133,8 @@ class BumpPtrAllocator {
 
   static MallocSlabAllocator DefaultSlabAllocator;
 
+  template<typename T> friend class SpecificBumpPtrAllocator;
 public:
-  typedef void (*DTorFunction)(void*);
   BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
                    SlabAllocator &allocator = DefaultSlabAllocator);
   ~BumpPtrAllocator();
@@ -143,11 +143,6 @@ public:
   /// to the beginning of it, freeing all memory allocated so far.
   void Reset();
 
-  /// Reset - like Reset(), but call DTorFunction for each allocated
-  /// object. This assumes that all objects allocated with this allocator
-  /// had the same size and alignment specified here.
-  void Reset(size_t Size, size_t Alignment, DTorFunction DTor);
-
   /// Allocate - Allocate space at the specified alignment.
   ///
   void *Allocate(size_t Size, size_t Alignment);
@@ -182,6 +177,45 @@ public:
   void PrintStats() const;
 };
 
+/// SpecificBumpPtrAllocator - Same as BumpPtrAllocator but allows only
+/// elements of one type to be allocated. This allows calling the destructor
+/// in DestroyAll() and when the allocator is destroyed.
+template <typename T>
+class SpecificBumpPtrAllocator {
+  BumpPtrAllocator Allocator;
+public:
+  SpecificBumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
+              SlabAllocator &allocator = BumpPtrAllocator::DefaultSlabAllocator)
+    : Allocator(size, threshold, allocator) {}
+
+  ~SpecificBumpPtrAllocator() {
+    DestroyAll();
+  }
+
+  /// Call the destructor of each allocated object and deallocate all but the
+  /// current slab and reset the current pointer to the beginning of it, freeing
+  /// all memory allocated so far.
+  void DestroyAll() {
+    MemSlab *Slab = Allocator.CurSlab;
+    while (Slab) {
+      char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr :
+                                              (char *)Slab + Slab->Size;
+      for (char *Ptr = (char*)Slab+1; Ptr < End; Ptr += sizeof(T)) {
+        Ptr = Allocator.AlignPtr(Ptr, alignof<T>());
+       if (Ptr + sizeof(T) <= End)
+          reinterpret_cast<T*>(Ptr)->~T();
+      }
+      Slab = Slab->NextPtr;
+    }
+    Allocator.Reset();
+  }
+
+  /// Allocate space for a specific count of elements.
+  T *Allocate(size_t num = 1) {
+    return Allocator.Allocate<T>(num);
+  }
+};
+
 }  // end namespace llvm
 
 inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) {
index 465b30692129db0b2c11e896c5ecb4cef565e306..025ad0538f2c9fa8799a9ecd3241884da715bfbb 100644 (file)
@@ -591,7 +591,7 @@ void LiveInterval::MergeValueInAsValue(
 /// used with an unknown definition value.
 void LiveInterval::MergeInClobberRanges(LiveIntervals &li_,
                                         const LiveInterval &Clobbers,
-                                        BumpPtrAllocator &VNInfoAllocator) {
+                                        VNInfo::Allocator &VNInfoAllocator) {
   if (Clobbers.empty()) return;
   
   DenseMap<VNInfo*, VNInfo*> ValNoMaps;
@@ -658,7 +658,7 @@ void LiveInterval::MergeInClobberRanges(LiveIntervals &li_,
 void LiveInterval::MergeInClobberRange(LiveIntervals &li_,
                                        SlotIndex Start,
                                        SlotIndex End,
-                                       BumpPtrAllocator &VNInfoAllocator) {
+                                       VNInfo::Allocator &VNInfoAllocator) {
   // Find a value # to use for the clobber ranges.  If there is already a value#
   // for unknown values, use it.
   VNInfo *ClobberValNo =
@@ -753,7 +753,7 @@ VNInfo* LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
 
 void LiveInterval::Copy(const LiveInterval &RHS,
                         MachineRegisterInfo *MRI,
-                        BumpPtrAllocator &VNInfoAllocator) {
+                        VNInfo::Allocator &VNInfoAllocator) {
   ranges.clear();
   valnos.clear();
   std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(RHS.reg);
index 53366b9f0741349a6b3e3474f756a8c5223b9197..23cff0786a5e02d31d2dd126ff2e0f01d40f6066 100644 (file)
@@ -82,11 +82,6 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
   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(),
@@ -96,7 +91,7 @@ void LiveIntervals::releaseMemory() {
   r2iMap_.clear();
 
   // Release VNInfo memroy regions after all VNInfo objects are dtor'd.
-  VNInfoAllocator.Reset((unsigned)sizeof(VNInfo), alignof<VNInfo>(), VNInfoDTor);
+  VNInfoAllocator.DestroyAll();
   while (!CloneMIs.empty()) {
     MachineInstr *MI = CloneMIs.back();
     CloneMIs.pop_back();
index d2f3775288c545cc6b43b617ed4b7bb6abdc6d53..798b9b939cd356e25b830d0b1da446a844681462 100644 (file)
@@ -36,7 +36,7 @@ void LiveStacks::getAnalysisUsage(AnalysisUsage &AU) const {
 
 void LiveStacks::releaseMemory() {
   // Release VNInfo memroy regions after all VNInfo objects are dtor'd.
-  VNInfoAllocator.Reset();
+  VNInfoAllocator.DestroyAll();
   S2IMap.clear();
   S2RCMap.clear();
 }
index 70e91aa3bd09934523ca3c615c4d46b194760599..2d49beb7d7615dc1fb826a33d7067cb6ea61da0c 100644 (file)
@@ -665,7 +665,7 @@ PreAllocSplitting::PerformPHIConstructionFallBack(MachineBasicBlock::iterator Us
 
 /// ReconstructLiveInterval - Recompute a live interval from scratch.
 void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) {
-  BumpPtrAllocator& Alloc = LIs->getVNInfoAllocator();
+  VNInfo::Allocator& Alloc = LIs->getVNInfoAllocator();
   
   // Clear the old ranges and valnos;
   LI->clear();
index 7433247c23796de3b94198bd19640654f89280b7..31b45c8d4aae77538940f8f1b9e948f7f2726e23 100644 (file)
@@ -78,21 +78,6 @@ void BumpPtrAllocator::Reset() {
   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) {