From 404cddfcf9053f6170ec8e9c580dba7a35303b22 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 12 Nov 2005 01:33:40 +0000 Subject: [PATCH] Read and write section info from/to .bc files git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24321 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bytecode/Reader/Reader.cpp | 52 +++++++++++++++++++++------ lib/Bytecode/Writer/Writer.cpp | 44 +++++++++++++++++++---- lib/Bytecode/Writer/WriterInternals.h | 4 --- 3 files changed, 80 insertions(+), 20 deletions(-) diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 165e085cf4c..645a01b0603 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -1891,6 +1891,10 @@ void BytecodeReader::ParseModuleGlobalInfo() { if (Handler) Handler->handleModuleGlobalsBegin(); + // SectionID - If a global has an explicit section specified, this map + // remembers the ID until we can translate it into a string. + std::map SectionID; + // Read global variables... unsigned VarType = read_vbr_uint(); while (VarType != Type::VoidTyID) { // List is terminated by Void @@ -1903,6 +1907,7 @@ void BytecodeReader::ParseModuleGlobalInfo() { bool isConstant = VarType & 1; bool hasInitializer = (VarType & 2) != 0; unsigned Alignment = 0; + unsigned GlobalSectionID = 0; // An extension word is present when linkage = 3 (internal) and hasinit = 0. if (LinkageID == 3 && !hasInitializer) { @@ -1912,6 +1917,9 @@ void BytecodeReader::ParseModuleGlobalInfo() { hasInitializer = ExtWord & 1; LinkageID = (ExtWord >> 1) & 7; Alignment = (1 << ((ExtWord >> 4) & 31)) >> 1; + + if (ExtWord & (1 << 9)) // Has a section ID. + GlobalSectionID = read_vbr_uint(); } GlobalValue::LinkageTypes Linkage; @@ -1942,6 +1950,9 @@ void BytecodeReader::ParseModuleGlobalInfo() { GV->setAlignment(Alignment); insertValue(GV, SlotNo, ModuleValues); + if (GlobalSectionID != 0) + SectionID[GV] = GlobalSectionID; + unsigned initSlot = 0; if (hasInitializer) { initSlot = read_vbr_uint(); @@ -1975,9 +1986,8 @@ void BytecodeReader::ParseModuleGlobalInfo() { const FunctionType* FTy = cast(cast(Ty)->getElementType()); - // Insert the place holder. - Function* Func = new Function(FTy, GlobalValue::ExternalLinkage, + Function *Func = new Function(FTy, GlobalValue::ExternalLinkage, "", TheModule); insertValue(Func, (FnSignature & (~0U >> 1)) >> 5, ModuleValues); @@ -1997,6 +2007,9 @@ void BytecodeReader::ParseModuleGlobalInfo() { unsigned ExtWord = read_vbr_uint(); Alignment = (1 << (ExtWord & 31)) >> 1; CC |= ((ExtWord >> 5) & 15) << 4; + + if (ExtWord & (1 << 10)) // Has a section ID. + SectionID[Func] = read_vbr_uint(); } Func->setCallingConv(CC-1); @@ -2014,28 +2027,47 @@ void BytecodeReader::ParseModuleGlobalInfo() { // remove elements efficiently from the back of the vector. std::reverse(FunctionSignatureList.begin(), FunctionSignatureList.end()); - // If this bytecode format has dependent library information in it .. - if (!hasNoDependentLibraries) { - // Read in the number of dependent library items that follow + /// SectionNames - This contains the list of section names encoded in the + /// moduleinfoblock. Functions and globals with an explicit section index + /// into this to get their section name. + std::vector SectionNames; + + if (hasInconsistentModuleGlobalInfo) { + align32(); + } else if (!hasNoDependentLibraries) { + // If this bytecode format has dependent library information in it, read in + // the number of dependent library items that follow. unsigned num_dep_libs = read_vbr_uint(); std::string dep_lib; - while( num_dep_libs-- ) { + while (num_dep_libs--) { dep_lib = read_str(); TheModule->addLibrary(dep_lib); if (Handler) Handler->handleDependentLibrary(dep_lib); } - - // Read target triple and place into the module + // Read target triple and place into the module. std::string triple = read_str(); TheModule->setTargetTriple(triple); if (Handler) Handler->handleTargetTriple(triple); + + if (At != BlockEnd) { + // If the file has section info in it, read the section names now. + unsigned NumSections = read_vbr_uint(); + while (NumSections--) + SectionNames.push_back(read_str()); + } } - if (hasInconsistentModuleGlobalInfo) - align32(); + // If any globals are in specified sections, assign them now. + for (std::map::iterator I = SectionID.begin(), E = + SectionID.end(); I != E; ++I) + if (I->second) { + if (I->second > SectionID.size()) + error("SectionID out of range for global!"); + I->first->setSection(SectionNames[I->second-1]); + } // This is for future proofing... in the future extra fields may be added that // we don't understand, so we transparently ignore them. diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index 2bfe915b4bb..879d50c86a1 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -922,6 +922,11 @@ static unsigned getEncodedLinkage(const GlobalValue *GV) { void BytecodeWriter::outputModuleInfoBlock(const Module *M) { BytecodeBlock ModuleInfoBlock(BytecodeFormat::ModuleGlobalInfoBlockID, *this); + // Give numbers to sections as we encounter them. + unsigned SectionIDCounter = 0; + std::vector SectionNames; + std::map SectionID; + // Output the types for the global variables in the module... for (Module::const_global_iterator I = M->global_begin(), End = M->global_end(); I != End; ++I) { @@ -933,7 +938,7 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { // Fields: bit0 = isConstant, bit1 = hasInitializer, bit2-4=Linkage, // bit5+ = Slot # for type. - bool HasExtensionWord = I->getAlignment() != 0; + bool HasExtensionWord = (I->getAlignment() != 0) || I->hasSection(); // If we need to use the extension byte, set linkage=3(internal) and // initializer = 0 (impossible!). @@ -947,11 +952,22 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { output_vbr(oSlot); // The extension word has this format: bit 0 = has initializer, bit 1-3 = - // linkage, bit 4-8 = alignment (log2), bits 10+ = future use. + // linkage, bit 4-8 = alignment (log2), bit 9 = has SectionID, + // bits 10+ = future use. unsigned ExtWord = (unsigned)I->hasInitializer() | (getEncodedLinkage(I) << 1) | - ((Log2_32(I->getAlignment())+1) << 4); + ((Log2_32(I->getAlignment())+1) << 4) | + ((unsigned)I->hasSection() << 9); output_vbr(ExtWord); + if (I->hasSection()) { + // Give section names unique ID's. + unsigned &Entry = SectionID[I->getSection()]; + if (Entry == 0) { + Entry = ++SectionIDCounter; + SectionNames.push_back(I->getSection()); + } + output_vbr(Entry); + } } // If we have an initializer, output it now. @@ -975,16 +991,27 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { if (I->isExternal()) // If external, we don't have an FunctionInfo block. ID |= 1 << 4; - if (I->getAlignment() || (CC & ~15) != 0) + if (I->getAlignment() || I->hasSection() || (CC & ~15) != 0) ID |= 1 << 31; // Do we need an extension word? output_vbr(ID); if (ID & (1 << 31)) { // Extension byte: bits 0-4 = alignment, bits 5-9 = top nibble of calling - // convention. - ID = (Log2_32(I->getAlignment())+1) | ((CC >> 4) << 5); + // convention, bit 10 = hasSectionID. + ID = (Log2_32(I->getAlignment())+1) | ((CC >> 4) << 5) | + (I->hasSection() << 10); output_vbr(ID); + + // Give section names unique ID's. + if (I->hasSection()) { + unsigned &Entry = SectionID[I->getSection()]; + if (Entry == 0) { + Entry = ++SectionIDCounter; + SectionNames.push_back(I->getSection()); + } + output_vbr(Entry); + } } } output_vbr((unsigned)Table.getSlot(Type::VoidTy) << 5); @@ -998,6 +1025,11 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { // Output the target triple from the module output(M->getTargetTriple()); + + // Emit the table of section names. + output_vbr((unsigned)SectionNames.size()); + for (unsigned i = 0, e = SectionNames.size(); i != e; ++i) + output(SectionNames[i]); } void BytecodeWriter::outputInstructions(const Function *F) { diff --git a/lib/Bytecode/Writer/WriterInternals.h b/lib/Bytecode/Writer/WriterInternals.h index 46ad5c67103..15dd92db1ec 100644 --- a/lib/Bytecode/Writer/WriterInternals.h +++ b/lib/Bytecode/Writer/WriterInternals.h @@ -10,10 +10,6 @@ // This header defines the interface used between components of the bytecode // writer. // -// Note that the performance of this library is not terribly important, because -// it shouldn't be used by JIT type applications... so it is not a huge focus -// at least. :) -// //===----------------------------------------------------------------------===// #ifndef LLVM_LIB_BYTECODE_WRITER_WRITERINTERNALS_H