*** Significantly speed up type resultion

This change speeds up type resolution by checking to see if a type is
  recursive, and if it's not, using a more efficient algorithm.

  This dramatically reduces bytecode loading time of kc++, reducing time-to-jit
  kc++ --version to 17s from 33s


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10088 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2003-11-19 19:10:23 +00:00
parent 30263d0c4c
commit 542d991451

View File

@ -14,6 +14,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/SymbolTable.h"
#include "llvm/Constants.h"
#include "Support/DepthFirstIterator.h"
#include "Support/StringExtras.h"
#include "Support/STLExtras.h"
#include <algorithm>
@ -495,7 +496,6 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2,
std::map<const Type *, const Type *> &EqTypes) {
if (Ty == Ty2) return true;
if (Ty->getPrimitiveID() != Ty2->getPrimitiveID()) return false;
if (Ty->isPrimitiveType()) return true;
if (isa<OpaqueType>(Ty))
return false; // Two unequal opaque types are never equal
@ -595,23 +595,61 @@ public:
// updated. Remove the obsolete entry from the map.
Map.erase(TyIt);
// Now we check to see if there is an existing entry in the table which is
// structurally identical to the newly refined type. If so, this type gets
// refined to the pre-existing type.
//
for (iterator I = Map.begin(), E = Map.end(); I != E; ++I)
if (TypesEqual(Ty, I->second)) {
// Determine whether there is a cycle through the type graph which passes
// back through this type. Other cycles are ok,
bool HasTypeCycle = false;
{
std::set<const Type*> VisitedTypes;
for (Type::subtype_iterator I = Ty->subtype_begin(),
E = Ty->subtype_end(); I != E; ++I) {
for (df_ext_iterator<const Type *, std::set<const Type*> >
DFI = df_ext_begin(*I, VisitedTypes),
E = df_ext_end(*I, VisitedTypes); DFI != E; ++DFI)
if (*DFI == Ty) {
HasTypeCycle = true;
goto FoundCycle;
}
}
}
FoundCycle:
ValType Key = ValType::get(Ty);
// If there are no cycles going through this node, we can do a simple,
// efficient lookup in the map, instead of an inefficient nasty linear
// lookup.
if (!HasTypeCycle) {
iterator I = Map.find(ValType::get(Ty));
if (I != Map.end()) {
// We already have this type in the table. Get rid of the newly refined
// type.
assert(Ty->isAbstract() && "Replacing a non-abstract type?");
TypeClass *NewTy = I->second;
// Refined to a different type altogether?
Ty->refineAbstractTypeTo(NewTy);
return;
}
} else {
// Now we check to see if there is an existing entry in the table which is
// structurally identical to the newly refined type. If so, this type
// gets refined to the pre-existing type.
//
for (iterator I = Map.begin(), E = Map.end(); I != E; ++I)
if (TypesEqual(Ty, I->second)) {
assert(Ty->isAbstract() && "Replacing a non-abstract type?");
TypeClass *NewTy = I->second;
// Refined to a different type altogether?
Ty->refineAbstractTypeTo(NewTy);
return;
}
}
// If there is no existing type of the same structure, we reinsert an
// updated record into the map.
Map.insert(std::make_pair(ValType::get(Ty), Ty));
Map.insert(std::make_pair(Key, Ty));
// If the type is currently thought to be abstract, rescan all of our
// subtypes to see if the type has just become concrete!