From 457dd0b6c7328a0ff46632826598c7e81bd93c15 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 18 Dec 2003 08:11:56 +0000 Subject: [PATCH] Add a new AliassetTracker::remove method. Because we need to be able to remove a pointer from an AliasSet, maintain the pointer values on a doubly linked list instead of a singly linked list, to permit efficient removal from the middle of the list. llvm-svn: 10506 --- include/llvm/Analysis/AliasSetTracker.h | 42 ++++++++++++++++++----- lib/Analysis/AliasSetTracker.cpp | 44 ++++++++++++++++++++----- 2 files changed, 69 insertions(+), 17 deletions(-) diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index 21952539777..77b17200dee 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -37,15 +37,20 @@ class AliasSet { typedef std::pair HashNodePair; class PointerRec { - HashNodePair *NextInList; + HashNodePair **PrevInList, *NextInList; AliasSet *AS; unsigned Size; public: - PointerRec() : NextInList(0), AS(0), Size(0) {} + PointerRec() : PrevInList(0), NextInList(0), AS(0), Size(0) {} HashNodePair *getNext() const { return NextInList; } bool hasAliasSet() const { return AS != 0; } + HashNodePair** setPrevInList(HashNodePair **PIL) { + PrevInList = PIL; + return &NextInList; + } + void updateSize(unsigned NewSize) { if (NewSize > Size) Size = NewSize; } @@ -68,13 +73,14 @@ class AliasSet { assert(AS == 0 && "Already have an alias set!"); AS = as; } - void setTail(HashNodePair *T) { - assert(NextInList == 0 && "Already have tail!"); - NextInList = T; + + void removeFromList() { + if (NextInList) NextInList->second.PrevInList = PrevInList; + *PrevInList = NextInList; } }; - HashNodePair *PtrListHead, *PtrListTail; // Singly linked list of nodes + HashNodePair *PtrList, **PtrListEnd; // Doubly linked list of nodes AliasSet *Forward; // Forwarding pointer AliasSet *Next, *Prev; // Doubly linked list of AliasSets @@ -135,7 +141,7 @@ public: // Alias Set iteration - Allow access to all of the pointer which are part of // this alias set... class iterator; - iterator begin() const { return iterator(PtrListHead); } + iterator begin() const { return iterator(PtrList); } iterator end() const { return iterator(); } void print(std::ostream &OS) const; @@ -175,11 +181,22 @@ public: private: // Can only be created by AliasSetTracker - AliasSet() : PtrListHead(0), PtrListTail(0), Forward(0), RefCount(0), + AliasSet() : PtrList(0), PtrListEnd(&PtrList), Forward(0), RefCount(0), AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) { } + AliasSet(const AliasSet &AS) { + // AliasSet's only get copy constructed in simple circumstances. In + // particular, they cannot have any pointers in their list. Despite this, + // we have to be sure to update the PtrListEnd to not point to the source + // AliasSet's list. + assert(AS.PtrList == 0 && "AliasSet has pointers in it!"); + PtrList = 0; PtrListEnd = &PtrList; + Forward = AS.Forward; RefCount = AS.RefCount; + AccessTy = AS.AccessTy; AliasTy = AS.AliasTy; Volatile = AS.Volatile; + } + HashNodePair *getSomePointer() const { - return PtrListHead ? PtrListHead : 0; + return PtrList; } /// getForwardedTarget - Return the real alias set this represents. If this @@ -247,6 +264,13 @@ public: void add(BasicBlock &BB); // Add all instructions in basic block void add(const AliasSetTracker &AST); // Add alias relations from another AST + /// remove method - This method is used to remove a pointer value from the + /// AliasSetTracker entirely. It should be used when an instruction is + /// deleted from the program to update the AST. If you don't use this, you + /// would have dangling pointers to deleted instructions. + /// + void remove(Value *PtrVal); + /// getAliasSets - Return the alias sets that are active. const ilist &getAliasSets() const { return AliasSets; } diff --git a/lib/Analysis/AliasSetTracker.cpp b/lib/Analysis/AliasSetTracker.cpp index a3d58d90e9f..67cef76d579 100644 --- a/lib/Analysis/AliasSetTracker.cpp +++ b/lib/Analysis/AliasSetTracker.cpp @@ -47,9 +47,14 @@ void AliasSet::mergeSetIn(AliasSet &AS) { RefCount++; // AS is now pointing to us... // Merge the list of constituent pointers... - PtrListTail->second.setTail(AS.PtrListHead); - PtrListTail = AS.PtrListTail; - AS.PtrListHead = AS.PtrListTail = 0; + if (AS.PtrList) { + *PtrListEnd = AS.PtrList; + AS.PtrList->second.setPrevInList(PtrListEnd); + PtrListEnd = AS.PtrListEnd; + + AS.PtrList = 0; + AS.PtrListEnd = &AS.PtrList; + } } void AliasSetTracker::removeAliasSet(AliasSet *AS) { @@ -82,11 +87,9 @@ void AliasSet::addPointer(AliasSetTracker &AST, HashNodePair &Entry, Entry.second.updateSize(Size); // Add it to the end of the list... - if (PtrListTail) - PtrListTail->second.setTail(&Entry); - else - PtrListHead = &Entry; - PtrListTail = &Entry; + assert(*PtrListEnd == 0 && "End of list is not null?"); + *PtrListEnd = &Entry; + PtrListEnd = Entry.second.setPrevInList(PtrListEnd); RefCount++; // Entry points to alias set... } @@ -253,6 +256,31 @@ void AliasSetTracker::add(const AliasSetTracker &AST) { } } + +// remove method - This method is used to remove a pointer value from the +// AliasSetTracker entirely. It should be used when an instruction is deleted +// from the program to update the AST. If you don't use this, you would have +// dangling pointers to deleted instructions. +// +void AliasSetTracker::remove(Value *PtrVal) { + // First, look up the PointerRec for this pointer... + hash_map::iterator I = PointerMap.find(PtrVal); + if (I == PointerMap.end()) return; // Noop + + // If we found one, remove the pointer from the alias set it is in. + AliasSet::HashNodePair &PtrValEnt = *I; + AliasSet *AS = PtrValEnt.second.getAliasSet(*this); + + // Unlink from the list of values... + PtrValEnt.second.removeFromList(); + // Stop using the alias set + if (--AS->RefCount == 0) + AS->removeFromTracker(*this); + + PointerMap.erase(I); +} + + //===----------------------------------------------------------------------===// // AliasSet/AliasSetTracker Printing Support //===----------------------------------------------------------------------===//