From: Benjamin Kramer Date: Tue, 30 Mar 2010 20:16:45 +0000 (+0000) Subject: Introduce SpecificBumpPtrAllocator, a wrapper for BumpPtrAllocator which allows X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=991de14dd62dcbab4b31357ae22dc5b053ba50a0;p=oota-llvm.git Introduce SpecificBumpPtrAllocator, a wrapper for BumpPtrAllocator which allows 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 --- diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 1f198e63252..70e79cebcb1 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -67,7 +67,7 @@ namespace llvm { } cr; public: - + typedef SpecificBumpPtrAllocator Allocator; typedef SmallVector 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(VNInfoAllocator.Allocate((unsigned)sizeof(VNInfo), - alignof())); + 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(VNInfoAllocator.Allocate((unsigned)sizeof(VNInfo), - alignof())); - + 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(); } diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 1a2cc25ba49..8ddcac70599 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -55,7 +55,7 @@ namespace llvm { /// Special pool allocator for VNInfo's (LiveInterval val#). /// - BumpPtrAllocator VNInfoAllocator; + VNInfo::Allocator VNInfoAllocator; typedef DenseMap 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. diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h index e01d1aea7e8..c6af6a1f89c 100644 --- a/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/include/llvm/CodeGen/LiveStackAnalysis.h @@ -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(); diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index a58b9db27fa..bd381807e0c 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -133,8 +133,8 @@ class BumpPtrAllocator { static MallocSlabAllocator DefaultSlabAllocator; + template 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 +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()); + if (Ptr + sizeof(T) <= End) + reinterpret_cast(Ptr)->~T(); + } + Slab = Slab->NextPtr; + } + Allocator.Reset(); + } + + /// Allocate space for a specific count of elements. + T *Allocate(size_t num = 1) { + return Allocator.Allocate(num); + } +}; + } // end namespace llvm inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) { diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 465b3069212..025ad0538f2 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -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 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 Hint = MRI->getRegAllocationHint(RHS.reg); diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 53366b9f074..23cff0786a5 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -82,11 +82,6 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); } -static void VNInfoDTor(void* Ptr) -{ - reinterpret_cast(Ptr)->~VNInfo(); -} - void LiveIntervals::releaseMemory() { // Free the live intervals themselves. for (DenseMap::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(), VNInfoDTor); + VNInfoAllocator.DestroyAll(); while (!CloneMIs.empty()) { MachineInstr *MI = CloneMIs.back(); CloneMIs.pop_back(); diff --git a/lib/CodeGen/LiveStackAnalysis.cpp b/lib/CodeGen/LiveStackAnalysis.cpp index d2f3775288c..798b9b939cd 100644 --- a/lib/CodeGen/LiveStackAnalysis.cpp +++ b/lib/CodeGen/LiveStackAnalysis.cpp @@ -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(); } diff --git a/lib/CodeGen/PreAllocSplitting.cpp b/lib/CodeGen/PreAllocSplitting.cpp index 70e91aa3bd0..2d49beb7d76 100644 --- a/lib/CodeGen/PreAllocSplitting.cpp +++ b/lib/CodeGen/PreAllocSplitting.cpp @@ -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(); diff --git a/lib/Support/Allocator.cpp b/lib/Support/Allocator.cpp index 7433247c237..31b45c8d4aa 100644 --- a/lib/Support/Allocator.cpp +++ b/lib/Support/Allocator.cpp @@ -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) {