mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-18 12:29:21 +00:00
Dramatically simplify DerivedType::refineAbstractTypeToInternal
This makes use of the new PATypeHolder's to keep types from being deleted prematurely, instead of the wierd "self reference" garbage. This is easier to understand and more efficient as well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8834 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1c5164e9cf
commit
8ef852f4ea
@ -1032,13 +1032,9 @@ void DerivedType::refineAbstractTypeToInternal(const Type *NewType, bool inMap){
|
||||
cast<DerivedType>(NewType)->addRef();
|
||||
|
||||
// Add a self use of the current type so that we don't delete ourself until
|
||||
// after this while loop. We are careful to never invoke refine on ourself,
|
||||
// so this extra reference shouldn't be a problem. Note that we must only
|
||||
// remove a single reference at the end, but we must tolerate multiple self
|
||||
// references because we could be refineAbstractTypeTo'ing recursively on the
|
||||
// same type.
|
||||
// after the function exits.
|
||||
//
|
||||
addAbstractTypeUser(this);
|
||||
PATypeHolder CurrentTy(this);
|
||||
|
||||
// To make the situation simpler, we ask the subclass to remove this type from
|
||||
// the type map, and to replace any type uses with uses of non-abstract types.
|
||||
@ -1046,22 +1042,15 @@ void DerivedType::refineAbstractTypeToInternal(const Type *NewType, bool inMap){
|
||||
// ourselves in.
|
||||
dropAllTypeUses(inMap);
|
||||
|
||||
// Count the number of self uses. Stop looping when sizeof(list) == NSU.
|
||||
unsigned NumSelfUses = 0;
|
||||
|
||||
// Iterate over all of the uses of this type, invoking callback. Each user
|
||||
// should remove itself from our use list automatically. We have to check to
|
||||
// make sure that NewTy doesn't _become_ 'this'. If it does, resolving types
|
||||
// will not cause users to drop off of the use list. If we resolve to ourself
|
||||
// we succeed!
|
||||
//
|
||||
while (AbstractTypeUsers.size() > NumSelfUses && NewTy != this) {
|
||||
while (!AbstractTypeUsers.empty() && NewTy != this) {
|
||||
AbstractTypeUser *User = AbstractTypeUsers.back();
|
||||
|
||||
if (User == this) {
|
||||
// Move self use to the start of the list. Increment NSU.
|
||||
std::swap(AbstractTypeUsers.back(), AbstractTypeUsers[NumSelfUses++]);
|
||||
} else {
|
||||
unsigned OldSize = AbstractTypeUsers.size();
|
||||
#ifdef DEBUG_MERGE_TYPES
|
||||
std::cerr << " REFINING user " << OldSize-1 << "[" << (void*)User
|
||||
@ -1086,19 +1075,11 @@ void DerivedType::refineAbstractTypeToInternal(const Type *NewType, bool inMap){
|
||||
assert(AbstractTypeUsers.size() != OldSize &&
|
||||
"AbsTyUser did not remove self from user list!");
|
||||
}
|
||||
}
|
||||
|
||||
// Remove a single self use, even though there may be several here. This will
|
||||
// probably 'delete this', so no instance variables may be used after this
|
||||
// occurs...
|
||||
//
|
||||
assert((NewTy == this || AbstractTypeUsers.back() == this) &&
|
||||
"Only self uses should be left!");
|
||||
|
||||
#if 0
|
||||
assert(AbstractTypeUsers.size() == 1 && "This type should get deleted!");
|
||||
#endif
|
||||
removeAbstractTypeUser(this);
|
||||
// If we were successful removing all users from the type, 'this' will be
|
||||
// deleted when the last PATypeHolder is destroyed or updated from this type.
|
||||
// This may occur on exit of this function, as the CurrentTy object is
|
||||
// destroyed.
|
||||
}
|
||||
|
||||
// typeIsRefined - Notify AbstractTypeUsers of this type that the current type
|
||||
|
Loading…
Reference in New Issue
Block a user