mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-02 00:36:36 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10506 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
45ab10cb6e
commit
2cffeec014
@ -37,15 +37,20 @@ class AliasSet {
|
||||
typedef std::pair<Value* const, PointerRec> 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<AliasSet> &getAliasSets() const { return AliasSets; }
|
||||
|
||||
|
@ -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<Value*, AliasSet::PointerRec>::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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user