forked from OSchip/llvm-project
Use a map to cache the ModuleType information, so we can do logarithmic
lookups instead of linear time lookups. This speeds up bc parsing of a large file from 137.834u 118.256s 4:27.96 to 132.611u 114.436s 4:08.53 with a release build. llvm-svn: 23611
This commit is contained in:
parent
409a6b204e
commit
bad09e71d0
|
@ -347,11 +347,25 @@ unsigned BytecodeReader::getTypeSlot(const Type *Ty) {
|
|||
return Type::FirstDerivedTyID + ModuleTypes.size() +
|
||||
(&*I - &FunctionTypes[0]);
|
||||
|
||||
// Check the module level types now...
|
||||
I = std::find(ModuleTypes.begin(), ModuleTypes.end(), Ty);
|
||||
if (I == ModuleTypes.end())
|
||||
// If we don't have our cache yet, build it now.
|
||||
if (ModuleTypeIDCache.empty()) {
|
||||
unsigned N = 0;
|
||||
ModuleTypeIDCache.reserve(ModuleTypes.size());
|
||||
for (TypeListTy::iterator I = ModuleTypes.begin(), E = ModuleTypes.end();
|
||||
I != E; ++I, ++N)
|
||||
ModuleTypeIDCache.push_back(std::make_pair(*I, N));
|
||||
|
||||
std::sort(ModuleTypeIDCache.begin(), ModuleTypeIDCache.end());
|
||||
}
|
||||
|
||||
// Binary search the cache for the entry.
|
||||
std::vector<std::pair<const Type*, unsigned> >::iterator IT =
|
||||
std::lower_bound(ModuleTypeIDCache.begin(), ModuleTypeIDCache.end(),
|
||||
std::make_pair(Ty, 0U));
|
||||
if (IT == ModuleTypeIDCache.end() || IT->first != Ty)
|
||||
error("Didn't find type in ModuleTypes.");
|
||||
return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]);
|
||||
|
||||
return Type::FirstDerivedTyID + IT->second;
|
||||
}
|
||||
|
||||
/// This is just like getType, but when a compaction table is in use, it is
|
||||
|
@ -375,11 +389,26 @@ const Type *BytecodeReader::getGlobalTableType(unsigned Slot) {
|
|||
unsigned BytecodeReader::getGlobalTableTypeSlot(const Type *Ty) {
|
||||
if (Ty->isPrimitiveType())
|
||||
return Ty->getTypeID();
|
||||
TypeListTy::iterator I = std::find(ModuleTypes.begin(),
|
||||
ModuleTypes.end(), Ty);
|
||||
if (I == ModuleTypes.end())
|
||||
|
||||
// If we don't have our cache yet, build it now.
|
||||
if (ModuleTypeIDCache.empty()) {
|
||||
unsigned N = 0;
|
||||
ModuleTypeIDCache.reserve(ModuleTypes.size());
|
||||
for (TypeListTy::iterator I = ModuleTypes.begin(), E = ModuleTypes.end();
|
||||
I != E; ++I, ++N)
|
||||
ModuleTypeIDCache.push_back(std::make_pair(*I, N));
|
||||
|
||||
std::sort(ModuleTypeIDCache.begin(), ModuleTypeIDCache.end());
|
||||
}
|
||||
|
||||
// Binary search the cache for the entry.
|
||||
std::vector<std::pair<const Type*, unsigned> >::iterator IT =
|
||||
std::lower_bound(ModuleTypeIDCache.begin(), ModuleTypeIDCache.end(),
|
||||
std::make_pair(Ty, 0U));
|
||||
if (IT == ModuleTypeIDCache.end() || IT->first != Ty)
|
||||
error("Didn't find type in ModuleTypes.");
|
||||
return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]);
|
||||
|
||||
return Type::FirstDerivedTyID + IT->second;
|
||||
}
|
||||
|
||||
/// Retrieve a value of a given type and slot number, possibly creating
|
||||
|
@ -1309,6 +1338,10 @@ void BytecodeReader::ParseTypes(TypeListTy &Tab, unsigned NumEntries){
|
|||
if (Handler)
|
||||
Handler->handleTypeList(NumEntries);
|
||||
|
||||
// If we are about to resolve types, make sure the type cache is clear.
|
||||
if (NumEntries)
|
||||
ModuleTypeIDCache.clear();
|
||||
|
||||
// Loop through reading all of the types. Forward types will make use of the
|
||||
// opaque types just inserted.
|
||||
//
|
||||
|
|
|
@ -333,6 +333,12 @@ private:
|
|||
/// @brief This vector is used to deal with forward references to types in
|
||||
/// a module.
|
||||
TypeListTy ModuleTypes;
|
||||
|
||||
/// @brief This is an inverse mapping of ModuleTypes from the type to an
|
||||
/// index. Because refining types causes the index of this map to be
|
||||
/// invalidated, any time we refine a type, we clear this cache and recompute
|
||||
/// it next time we need it. These entries are ordered by the pointer value.
|
||||
std::vector<std::pair<const Type*, unsigned> > ModuleTypeIDCache;
|
||||
|
||||
/// @brief This vector is used to deal with forward references to types in
|
||||
/// a function.
|
||||
|
|
Loading…
Reference in New Issue