summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bytecode/Writer/SlotCalculator.cpp
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2007-02-10 14:04:08 +0000
committerReid Spencer <rspencer@reidspencer.com>2007-02-10 14:04:08 +0000
commit6e4c2778585a79feeab8ab2ac85623904d3235b0 (patch)
treed21f238d3919731c71e0d06183b32205fe09c3ec /llvm/lib/Bytecode/Writer/SlotCalculator.cpp
parent16731591255f93c52218fbbc4455bc0a3587d32e (diff)
downloadbcm5719-llvm-6e4c2778585a79feeab8ab2ac85623904d3235b0.tar.gz
bcm5719-llvm-6e4c2778585a79feeab8ab2ac85623904d3235b0.zip
For PR1194:
The bcreader counts on "primitive" types being inserted before they are referenced in other types. With recent changes to the bcwriter, this fact became exposed since IntegerType is no longer "primitive". We can no longer count on all IntegerTypes being inserted early. This patch modifies getOrCreateTypeSlot to insert any sub-type that can't possibly recurse before we create the slot for the type. This has the benefit of reducing the number of OpaqueType objects the reader needs to deal with. llvm-svn: 34147
Diffstat (limited to 'llvm/lib/Bytecode/Writer/SlotCalculator.cpp')
-rw-r--r--llvm/lib/Bytecode/Writer/SlotCalculator.cpp72
1 files changed, 67 insertions, 5 deletions
diff --git a/llvm/lib/Bytecode/Writer/SlotCalculator.cpp b/llvm/lib/Bytecode/Writer/SlotCalculator.cpp
index 0c8ba48be7d..3cd1959b5bd 100644
--- a/llvm/lib/Bytecode/Writer/SlotCalculator.cpp
+++ b/llvm/lib/Bytecode/Writer/SlotCalculator.cpp
@@ -259,14 +259,77 @@ unsigned SlotCalculator::getOrCreateTypeSlot(const Type *Ty) {
TypeMapType::iterator TyIt = TypeMap.find(Ty);
if (TyIt != TypeMap.end()) return TyIt->second;
- // Insert into TypeMap.
+ // Try to reduce the number of opaque types the reader has to process by
+ // first inserting any contained types that can't possibly recurse back to
+ // this type. Making those types concrete before creating the slot number for
+ // this type means the reader will not have to create OpaqueTy placeholders
+ // for the this type's sub-types. If the sub-type is a pointer, function
+ // type, structure with pointer/array/struct, or an array with a pointer
+ // element type, then we defer it. Otherwise, we can either ignore the
+ // primitive types (avoid recursion) or create the slot up front.
+ // Note that this is a trade-off. It slows writing (very slightly) but makes
+ // reading a little faster, especially for large complex types.
+ typedef SmallVector<const Type*, 16> DeferVecType;
+ DeferVecType DeferList;
+ for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
+ I != E; ++I)
+ switch ((*I)->getTypeID()) {
+ default: assert(0 && "Invalid TypeID?");
+ case Type::VoidTyID:
+ case Type::FloatTyID:
+ case Type::DoubleTyID:
+ case Type::LabelTyID:
+ // These are all primitive and have been inserted already, just ignore
+ // to avoid the recursion.
+ break;
+ case Type::FunctionTyID:
+ case Type::PointerTyID:
+ // Pointers and Functions can recurse to us, defer it.
+ DeferList.push_back(*I);
+ break;
+ case Type::StructTyID:
+ case Type::PackedStructTyID: {
+ // if any of the fields of the structure are pointers, structures or
+ // arrays with pointer element type, defer it.
+ const StructType *Ty = &cast<StructType>(*(*I));
+ Type::subtype_iterator EI = Ty->subtype_begin();
+ Type::subtype_iterator EE = Ty->subtype_end();
+ for ( ; EI != EE; ++EI) {
+ const Type* SubTy = *EI;
+ if (isa<PointerType>(SubTy) || isa<StructType>(SubTy) ||
+ (isa<ArrayType>(SubTy) &&
+ isa<PointerType>(cast<ArrayType>(SubTy)->getElementType())))
+ break;
+ }
+ if (EI != EE)
+ DeferList.push_back(*I);
+ else
+ getOrCreateTypeSlot(*I);
+ break;
+ }
+ case Type::ArrayTyID: {
+ const ArrayType* ArrayTy = &cast<ArrayType>(*(*I));
+ if (isa<PointerType>(ArrayTy->getElementType())) {
+ // this might recurse to us, defer it.
+ DeferList.push_back(*I);
+ break;
+ }
+ /* FALL THROUGH (others are okay) */
+ }
+ case Type::OpaqueTyID: // no elements
+ case Type::IntegerTyID: // no elements
+ case Type::PackedTyID: // can only have elements of non-recursing types
+ getOrCreateTypeSlot(*I);
+ break;
+ }
+
+ // Now we must create the slot for this type by inserting into TypeMap.
unsigned ResultSlot = TypeMap[Ty] = Types.size();
Types.push_back(Ty);
SC_DEBUG(" Inserting type [" << ResultSlot << "] = " << *Ty << "\n" );
- // Loop over any contained types in the definition, ensuring they are also
- // inserted.
- for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
+ // Finally, process any deferred sub-types and create their slots.
+ for (DeferVecType::iterator I = DeferList.begin(), E = DeferList.end();
I != E; ++I)
getOrCreateTypeSlot(*I);
@@ -274,7 +337,6 @@ unsigned SlotCalculator::getOrCreateTypeSlot(const Type *Ty) {
}
-
void SlotCalculator::incorporateFunction(const Function *F) {
SC_DEBUG("begin processFunction!\n");
OpenPOWER on IntegriCloud