[llvm-commits] CVS: llvm/lib/Bytecode/Reader/Reader.cpp Reader.h
Chris Lattner
lattner at cs.uiuc.edu
Mon Oct 3 14:27:05 PDT 2005
Changes in directory llvm/lib/Bytecode/Reader:
Reader.cpp updated: 1.166 -> 1.167
Reader.h updated: 1.24 -> 1.25
---
Log message:
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.
---
Diffs of the changes: (+47 -8)
Reader.cpp | 49 +++++++++++++++++++++++++++++++++++++++++--------
Reader.h | 6 ++++++
2 files changed, 47 insertions(+), 8 deletions(-)
Index: llvm/lib/Bytecode/Reader/Reader.cpp
diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.166 llvm/lib/Bytecode/Reader/Reader.cpp:1.167
--- llvm/lib/Bytecode/Reader/Reader.cpp:1.166 Wed Aug 17 14:22:05 2005
+++ llvm/lib/Bytecode/Reader/Reader.cpp Mon Oct 3 16:26:53 2005
@@ -347,11 +347,25 @@
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 @@
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 @@
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.
//
Index: llvm/lib/Bytecode/Reader/Reader.h
diff -u llvm/lib/Bytecode/Reader/Reader.h:1.24 llvm/lib/Bytecode/Reader/Reader.h:1.25
--- llvm/lib/Bytecode/Reader/Reader.h:1.24 Tue Aug 16 16:59:52 2005
+++ llvm/lib/Bytecode/Reader/Reader.h Mon Oct 3 16:26:53 2005
@@ -333,6 +333,12 @@
/// @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.
More information about the llvm-commits
mailing list