diff options
Diffstat (limited to 'llvm/lib/Bitcode/Writer')
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 113 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 114 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.h | 3 |
3 files changed, 80 insertions, 150 deletions
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 24b5e2d52a8..85d67ce62b9 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -21,7 +21,6 @@ #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Operator.h" -#include "llvm/TypeSymbolTable.h" #include "llvm/ValueSymbolTable.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/ErrorHandling.h" @@ -29,6 +28,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Program.h" #include <cctype> +#include <map> using namespace llvm; /// These are manifest constants used by the bitcode writer. They do not need to @@ -101,13 +101,16 @@ static unsigned GetEncodedBinaryOpcode(unsigned Opcode) { } } -static void WriteStringRecord(unsigned Code, const std::string &Str, +static void WriteStringRecord(unsigned Code, StringRef Str, unsigned AbbrevToUse, BitstreamWriter &Stream) { SmallVector<unsigned, 64> Vals; // Code: [strchar x N] - for (unsigned i = 0, e = Str.size(); i != e; ++i) + for (unsigned i = 0, e = Str.size(); i != e; ++i) { + if (AbbrevToUse && !BitCodeAbbrevOp::isChar6(Str[i])) + AbbrevToUse = 0; Vals.push_back(Str[i]); + } // Emit the finished record. Stream.EmitRecord(Code, Vals, AbbrevToUse); @@ -151,7 +154,7 @@ static void WriteAttributeTable(const ValueEnumerator &VE, static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { const ValueEnumerator::TypeList &TypeList = VE.getTypes(); - Stream.EnterSubblock(bitc::TYPE_BLOCK_ID, 4 /*count from # abbrevs */); + Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */); SmallVector<uint64_t, 64> TypeVals; // Abbrev for TYPE_CODE_POINTER. @@ -172,15 +175,32 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { Log2_32_Ceil(VE.getTypes().size()+1))); unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv); - // Abbrev for TYPE_CODE_STRUCT. + // Abbrev for TYPE_CODE_STRUCT_ANON. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_ANON)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + Log2_32_Ceil(VE.getTypes().size()+1))); + unsigned StructAnonAbbrev = Stream.EmitAbbrev(Abbv); + + // Abbrev for TYPE_CODE_STRUCT_NAME. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAME)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); + unsigned StructNameAbbrev = Stream.EmitAbbrev(Abbv); + + // Abbrev for TYPE_CODE_STRUCT_NAMED. Abbv = new BitCodeAbbrev(); - Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT)); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAMED)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(VE.getTypes().size()+1))); - unsigned StructAbbrev = Stream.EmitAbbrev(Abbv); + unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv); + // Abbrev for TYPE_CODE_ARRAY. Abbv = new BitCodeAbbrev(); Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY)); @@ -202,16 +222,15 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { switch (T->getTypeID()) { default: llvm_unreachable("Unknown type!"); - case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break; - case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break; - case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break; - case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break; - case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break; + case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break; + case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break; + case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break; + case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break; + case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break; case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break; - case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break; - case Type::OpaqueTyID: Code = bitc::TYPE_CODE_OPAQUE; break; - case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break; - case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break; + case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break; + case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break; + case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break; case Type::IntegerTyID: // INTEGER: [width] Code = bitc::TYPE_CODE_INTEGER; @@ -242,13 +261,28 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { case Type::StructTyID: { const StructType *ST = cast<StructType>(T); // STRUCT: [ispacked, eltty x N] - Code = bitc::TYPE_CODE_STRUCT; TypeVals.push_back(ST->isPacked()); // Output all of the element types. for (StructType::element_iterator I = ST->element_begin(), E = ST->element_end(); I != E; ++I) TypeVals.push_back(VE.getTypeID(*I)); - AbbrevToUse = StructAbbrev; + + if (ST->isAnonymous()) { + Code = bitc::TYPE_CODE_STRUCT_ANON; + AbbrevToUse = StructAnonAbbrev; + } else { + if (ST->isOpaque()) { + Code = bitc::TYPE_CODE_OPAQUE; + } else { + Code = bitc::TYPE_CODE_STRUCT_NAMED; + AbbrevToUse = StructNamedAbbrev; + } + + // Emit the name if it is present. + if (!ST->getName().empty()) + WriteStringRecord(bitc::TYPE_CODE_STRUCT_NAME, ST->getName(), + StructNameAbbrev, Stream); + } break; } case Type::ArrayTyID: { @@ -1278,46 +1312,6 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, Stream.ExitBlock(); } -/// WriteTypeSymbolTable - Emit a block for the specified type symtab. -static void WriteTypeSymbolTable(const TypeSymbolTable &TST, - const ValueEnumerator &VE, - BitstreamWriter &Stream) { - if (TST.empty()) return; - - Stream.EnterSubblock(bitc::TYPE_SYMTAB_BLOCK_ID, 3); - - // 7-bit fixed width VST_CODE_ENTRY strings. - BitCodeAbbrev *Abbv = new BitCodeAbbrev(); - Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, - Log2_32_Ceil(VE.getTypes().size()+1))); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); - unsigned V7Abbrev = Stream.EmitAbbrev(Abbv); - - SmallVector<unsigned, 64> NameVals; - - for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end(); - TI != TE; ++TI) { - // TST_ENTRY: [typeid, namechar x N] - NameVals.push_back(VE.getTypeID(TI->second)); - - const std::string &Str = TI->first; - bool is7Bit = true; - for (unsigned i = 0, e = Str.size(); i != e; ++i) { - NameVals.push_back((unsigned char)Str[i]); - if (Str[i] & 128) - is7Bit = false; - } - - // Emit the finished record. - Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, is7Bit ? V7Abbrev : 0); - NameVals.clear(); - } - - Stream.ExitBlock(); -} - // Emit blockinfo, which defines the standard abbreviations etc. static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) { // We only want to emit block info records for blocks that have multiple @@ -1521,9 +1515,6 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) { // Emit metadata. WriteModuleMetadataStore(M, Stream); - // Emit the type symbol table information. - WriteTypeSymbolTable(M->getTypeSymbolTable(), VE, Stream); - // Emit names for globals/functions etc. WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream); diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 5138c3c984f..b68bf92d51b 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -17,7 +17,6 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" -#include "llvm/TypeSymbolTable.h" #include "llvm/ValueSymbolTable.h" #include "llvm/Instructions.h" #include <algorithm> @@ -59,9 +58,6 @@ ValueEnumerator::ValueEnumerator(const Module *M) { I != E; ++I) EnumerateValue(I->getAliasee()); - // Enumerate types used by the type symbol table. - EnumerateTypeSymbolTable(M->getTypeSymbolTable()); - // Insert constants and metadata that are named at module level into the slot // pool so that the module symbol table can refer to them... EnumerateValueSymbolTable(M->getValueSymbolTable()); @@ -109,78 +105,12 @@ ValueEnumerator::ValueEnumerator(const Module *M) { // Optimize constant ordering. OptimizeConstants(FirstConstant, Values.size()); - - OptimizeTypes(); - - // Now that we rearranged the type table, rebuild TypeMap. - for (unsigned i = 0, e = Types.size(); i != e; ++i) - TypeMap[Types[i]] = i+1; -} - -struct TypeAndDeps { - const Type *Ty; - unsigned NumDeps; -}; - -static int CompareByDeps(const void *a, const void *b) { - const TypeAndDeps &ta = *(const TypeAndDeps*) a; - const TypeAndDeps &tb = *(const TypeAndDeps*) b; - return ta.NumDeps - tb.NumDeps; -} - -static void VisitType(const Type *Ty, SmallPtrSet<const Type*, 16> &Visited, - std::vector<const Type*> &Out) { - if (Visited.count(Ty)) - return; - - Visited.insert(Ty); - - for (Type::subtype_iterator I2 = Ty->subtype_begin(), - E2 = Ty->subtype_end(); I2 != E2; ++I2) { - const Type *InnerType = I2->get(); - VisitType(InnerType, Visited, Out); - } - - Out.push_back(Ty); } -void ValueEnumerator::OptimizeTypes(void) { - // If the types form a DAG, this will compute a topological sort and - // no forward references will be needed when reading them in. - // If there are cycles, this is a simple but reasonable heuristic for - // the minimum feedback arc set problem. - const unsigned NumTypes = Types.size(); - std::vector<TypeAndDeps> TypeDeps; - TypeDeps.resize(NumTypes); - - for (unsigned I = 0; I < NumTypes; ++I) { - const Type *Ty = Types[I]; - TypeDeps[I].Ty = Ty; - TypeDeps[I].NumDeps = 0; - } - - for (unsigned I = 0; I < NumTypes; ++I) { - const Type *Ty = TypeDeps[I].Ty; - for (Type::subtype_iterator I2 = Ty->subtype_begin(), - E2 = Ty->subtype_end(); I2 != E2; ++I2) { - const Type *InnerType = I2->get(); - unsigned InnerIndex = TypeMap.lookup(InnerType) - 1; - TypeDeps[InnerIndex].NumDeps++; - } - } - array_pod_sort(TypeDeps.begin(), TypeDeps.end(), CompareByDeps); - - SmallPtrSet<const Type*, 16> Visited; - Types.clear(); - Types.reserve(NumTypes); - for (unsigned I = 0; I < NumTypes; ++I) { - VisitType(TypeDeps[I].Ty, Visited, Types); - } -} unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const { InstructionMapType::const_iterator I = InstructionMap.find(Inst); - assert (I != InstructionMap.end() && "Instruction is not mapped!"); + assert(I != InstructionMap.end() && "Instruction is not mapped!"); return I->second; } @@ -235,14 +165,6 @@ void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) { } -/// EnumerateTypeSymbolTable - Insert all of the types in the specified symbol -/// table. -void ValueEnumerator::EnumerateTypeSymbolTable(const TypeSymbolTable &TST) { - for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end(); - TI != TE; ++TI) - EnumerateType(TI->second); -} - /// EnumerateValueSymbolTable - Insert all of the values in the specified symbol /// table into the values table. void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) { @@ -394,20 +316,40 @@ void ValueEnumerator::EnumerateValue(const Value *V) { void ValueEnumerator::EnumerateType(const Type *Ty) { - unsigned &TypeID = TypeMap[Ty]; + unsigned *TypeID = &TypeMap[Ty]; // We've already seen this type. - if (TypeID) + if (*TypeID) return; - // First time we saw this type, add it. - Types.push_back(Ty); - TypeID = Types.size(); - - // Enumerate subtypes. + // If it is a non-anonymous struct, mark the type as being visited so that we + // don't recursively visit it. This is safe because we allow forward + // references of these in the bitcode reader. + if (const StructType *STy = dyn_cast<StructType>(Ty)) + if (!STy->isAnonymous()) + *TypeID = ~0U; + + // Enumerate all of the subtypes before we enumerate this type. This ensures + // that the type will be enumerated in an order that can be directly built. for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); I != E; ++I) EnumerateType(*I); + + // Refresh the TypeID pointer in case the table rehashed. + TypeID = &TypeMap[Ty]; + + // Check to see if we got the pointer another way. This can happen when + // enumerating recursive types that hit the base case deeper than they start. + // + // If this is actually a struct that we are treating as forward ref'able, + // then emit the definition now that all of its contents are available. + if (*TypeID && *TypeID != ~0U) + return; + + // Add this type now that its contents are all happily enumerated. + Types.push_back(Ty); + + *TypeID = Types.size(); } // Enumerate the types for the specified value. If the value is a constant, diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/llvm/lib/Bitcode/Writer/ValueEnumerator.h index 1e42a266766..6617b60deb2 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.h +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.h @@ -30,7 +30,6 @@ class Module; class MDNode; class NamedMDNode; class AttrListPtr; -class TypeSymbolTable; class ValueSymbolTable; class MDSymbolTable; @@ -135,7 +134,6 @@ public: private: void OptimizeConstants(unsigned CstStart, unsigned CstEnd); - void OptimizeTypes(); void EnumerateMDNodeOperands(const MDNode *N); void EnumerateMetadata(const Value *MD); @@ -146,7 +144,6 @@ private: void EnumerateOperandType(const Value *V); void EnumerateAttributes(const AttrListPtr &PAL); - void EnumerateTypeSymbolTable(const TypeSymbolTable &ST); void EnumerateValueSymbolTable(const ValueSymbolTable &ST); void EnumerateNamedMetadata(const Module *M); }; |