X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBytecode%2FWriter%2FWriter.cpp;h=a2e8fe566d35633bfe55c7751ccb04126c0841bf;hb=ef9b9a793949469cdaa4ab6d0173136229dcab7b;hp=37c6321e33c785218244a9556cb083abf032f343;hpb=ac0b6ae358944ae8b2b5a11dc08f52c3ed89f2da;p=oota-llvm.git diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index 37c6321e33c..a2e8fe566d3 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -17,6 +17,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "bytecodewriter" #include "WriterInternals.h" #include "llvm/Bytecode/WriteBytecodePass.h" #include "llvm/CallingConv.h" @@ -25,7 +26,8 @@ #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Module.h" -#include "llvm/SymbolTable.h" +#include "llvm/TypeSymbolTable.h" +#include "llvm/ValueSymbolTable.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/Compressor.h" #include "llvm/Support/MathExtras.h" @@ -45,8 +47,7 @@ const unsigned BCVersionNum = 7; static RegisterPass X("emitbytecode", "Bytecode Writer"); -static Statistic -BytesWritten("bytecodewriter", "Number of bytecode bytes written"); +STATISTIC(BytesWritten, "Number of bytecode bytes written"); //===----------------------------------------------------------------------===// //=== Output Primitives ===// @@ -197,29 +198,39 @@ inline BytecodeBlock::~BytecodeBlock() { // Do backpatch when block goes out //===----------------------------------------------------------------------===// void BytecodeWriter::outputType(const Type *T) { - output_vbr((unsigned)T->getTypeID()); + const StructType* STy = dyn_cast(T); + if(STy && STy->isPacked()) + output_vbr((unsigned)Type::PackedStructTyID); + else + output_vbr((unsigned)T->getTypeID()); // That's all there is to handling primitive types... - if (T->isPrimitiveType()) { + if (T->isPrimitiveType()) return; // We might do this if we alias a prim type: %x = type int - } switch (T->getTypeID()) { // Handle derived types now. + case Type::IntegerTyID: + output_vbr(cast(T)->getBitWidth()); + break; case Type::FunctionTyID: { const FunctionType *MT = cast(T); int Slot = Table.getSlot(MT->getReturnType()); assert(Slot != -1 && "Type used but not available!!"); output_typeid((unsigned)Slot); + output_vbr(unsigned(MT->getParamAttrs(0))); // Output the number of arguments to function (+1 if varargs): output_vbr((unsigned)MT->getNumParams()+MT->isVarArg()); // Output all of the arguments... FunctionType::param_iterator I = MT->param_begin(); + unsigned Idx = 1; for (; I != MT->param_end(); ++I) { Slot = Table.getSlot(*I); assert(Slot != -1 && "Type used but not available!!"); output_typeid((unsigned)Slot); + output_vbr(unsigned(MT->getParamAttrs(Idx))); + Idx++; } // Terminate list with VoidTy if we are a varargs function... @@ -246,10 +257,8 @@ void BytecodeWriter::outputType(const Type *T) { break; } - case Type::StructTyID: { const StructType *ST = cast(T); - // Output all of the element types... for (StructType::element_iterator I = ST->element_begin(), E = ST->element_end(); I != E; ++I) { @@ -276,15 +285,15 @@ void BytecodeWriter::outputType(const Type *T) { break; default: - llvm_cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to serialize" - << " Type '" << T->getDescription() << "'\n"; + cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to serialize" + << " Type '" << T->getDescription() << "'\n"; break; } } void BytecodeWriter::outputConstant(const Constant *CPV) { - assert((CPV->getType()->isPrimitiveType() || !CPV->isNullValue()) && - "Shouldn't output null constants!"); + assert(((CPV->getType()->isPrimitiveType() || CPV->getType()->isInteger()) || + !CPV->isNullValue()) && "Shouldn't output null constants!"); // We must check for a ConstantExpr before switching by type because // a ConstantExpr can be of any type, and has no explicit value. @@ -314,26 +323,16 @@ void BytecodeWriter::outputConstant(const Constant *CPV) { } switch (CPV->getType()->getTypeID()) { - case Type::BoolTyID: // Boolean Types - if (cast(CPV)->getValue()) - output_vbr(1U); - else - output_vbr(0U); - break; - - case Type::UByteTyID: // Unsigned integer types... - case Type::UShortTyID: - case Type::UIntTyID: - case Type::ULongTyID: - output_vbr(cast(CPV)->getZExtValue()); - break; - - case Type::SByteTyID: // Signed integer types... - case Type::ShortTyID: - case Type::IntTyID: - case Type::LongTyID: - output_vbr(cast(CPV)->getSExtValue()); + case Type::IntegerTyID: { // Integer types... + unsigned NumBits = cast(CPV->getType())->getBitWidth(); + if (NumBits <= 32) + output_vbr(uint32_t(cast(CPV)->getZExtValue())); + else if (NumBits <= 64) + output_vbr(uint64_t(cast(CPV)->getZExtValue())); + else + assert("Integer types > 64 bits not supported."); break; + } case Type::ArrayTyID: { const ConstantArray *CPA = cast(CPV); @@ -387,8 +386,8 @@ void BytecodeWriter::outputConstant(const Constant *CPV) { case Type::VoidTyID: case Type::LabelTyID: default: - llvm_cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to serialize" - << " type '" << *CPV->getType() << "'\n"; + cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to serialize" + << " type '" << *CPV->getType() << "'\n"; break; } return; @@ -484,15 +483,15 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I, assert(Slot >= 0 && "No slot number for value!?!?"); if (isa(*TI)) { - unsigned IdxId; - switch (I->getOperand(Idx)->getType()->getTypeID()) { - default: assert(0 && "Unknown index type!"); - case Type::UIntTyID: IdxId = 0; break; - case Type::IntTyID: IdxId = 1; break; - case Type::ULongTyID: IdxId = 2; break; - case Type::LongTyID: IdxId = 3; break; - } - Slot = (Slot << 2) | IdxId; + // These should be either 32-bits or 64-bits, however, with bit + // accurate types we just distinguish between less than or equal to + // 32-bits or greater than 32-bits. + unsigned BitWidth = + cast(I->getOperand(Idx)->getType())->getBitWidth(); + assert(BitWidth == 32 || BitWidth == 64 && + "Invalid bitwidth for GEP index"); + unsigned IdxId = BitWidth == 32 ? 0 : 1; + Slot = (Slot << 1) | IdxId; } output_vbr(unsigned(Slot)); } @@ -737,15 +736,15 @@ void BytecodeWriter::outputInstruction(const Instruction &I) { for (gep_type_iterator I = gep_type_begin(GEP), E = gep_type_end(GEP); I != E; ++I, ++Idx) if (isa(*I)) { - unsigned IdxId; - switch (GEP->getOperand(Idx)->getType()->getTypeID()) { - default: assert(0 && "Unknown index type!"); - case Type::UIntTyID: IdxId = 0; break; - case Type::IntTyID: IdxId = 1; break; - case Type::ULongTyID: IdxId = 2; break; - case Type::LongTyID: IdxId = 3; break; - } - Slots[Idx] = (Slots[Idx] << 2) | IdxId; + // These should be either 32-bits or 64-bits, however, with bit + // accurate types we just distinguish between less than or equal to + // 32-bits or greater than 32-bits. + unsigned BitWidth = + cast(GEP->getOperand(Idx)->getType())->getBitWidth(); + assert(BitWidth == 32 || BitWidth == 64 && + "Invalid bitwidth for GEP index"); + unsigned IdxId = BitWidth == 32 ? 0 : 1; + Slots[Idx] = (Slots[Idx] << 1) | IdxId; if (Slots[Idx] > MaxOpSlot) MaxOpSlot = Slots[Idx]; } } else if (Opcode == 58) { @@ -814,17 +813,8 @@ BytecodeWriter::BytecodeWriter(std::vector &o, const Module *M) // Emit the top level CLASS block. BytecodeBlock ModuleBlock(BytecodeFormat::ModuleBlockID, *this, false, true); - bool isBigEndian = M->getEndianness() == Module::BigEndian; - bool hasLongPointers = M->getPointerSize() == Module::Pointer64; - bool hasNoEndianness = M->getEndianness() == Module::AnyEndianness; - bool hasNoPointerSize = M->getPointerSize() == Module::AnyPointerSize; - - // Output the version identifier and other information. - unsigned Version = (BCVersionNum << 4) | - (unsigned)isBigEndian | (hasLongPointers << 1) | - (hasNoEndianness << 2) | - (hasNoPointerSize << 3); - output_vbr(Version); + // Output the version identifier + output_vbr(BCVersionNum); // The Global type plane comes first { @@ -842,8 +832,11 @@ BytecodeWriter::BytecodeWriter(std::vector &o, const Module *M) for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) outputFunction(I); - // If needed, output the symbol table for the module... - outputSymbolTable(M->getSymbolTable()); + // Output the symbole table for types + outputTypeSymbolTable(M->getTypeSymbolTable()); + + // Output the symbol table for values + outputValueSymbolTable(M->getValueSymbolTable()); } void BytecodeWriter::outputTypes(unsigned TypeNum) { @@ -957,6 +950,14 @@ static unsigned getEncodedLinkage(const GlobalValue *GV) { } } +static unsigned getEncodedVisibility(const GlobalValue *GV) { + switch (GV->getVisibility()) { + default: assert(0 && "Invalid visibility!"); + case GlobalValue::DefaultVisibility: return 0; + case GlobalValue::HiddenVisibility: return 1; + } +} + void BytecodeWriter::outputModuleInfoBlock(const Module *M) { BytecodeBlock ModuleInfoBlock(BytecodeFormat::ModuleGlobalInfoBlockID, *this); @@ -976,7 +977,9 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { // Fields: bit0 = isConstant, bit1 = hasInitializer, bit2-4=Linkage, // bit5+ = Slot # for type. - bool HasExtensionWord = (I->getAlignment() != 0) || I->hasSection(); + bool HasExtensionWord = (I->getAlignment() != 0) || + I->hasSection() || + (I->getVisibility() != GlobalValue::DefaultVisibility); // If we need to use the extension byte, set linkage=3(internal) and // initializer = 0 (impossible!). @@ -990,12 +993,13 @@ 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), bit 9 = has SectionID, - // bits 10+ = future use. + // linkage, bit 4-8 = alignment (log2), bit 9 = has SectionID, + // bits 10-12 = visibility, bits 13+ = future use. unsigned ExtWord = (unsigned)I->hasInitializer() | (getEncodedLinkage(I) << 1) | ((Log2_32(I->getAlignment())+1) << 4) | - ((unsigned)I->hasSection() << 9); + ((unsigned)I->hasSection() << 9) | + (getEncodedVisibility(I) << 10); output_vbr(ExtWord); if (I->hasSection()) { // Give section names unique ID's. @@ -1026,12 +1030,12 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { unsigned CC = I->getCallingConv()+1; unsigned ID = (Slot << 5) | (CC & 15); - if (I->isExternal()) // If external, we don't have an FunctionInfo block. + if (I->isDeclaration()) // If external, we don't have an FunctionInfo block. ID |= 1 << 4; if (I->getAlignment() || I->hasSection() || (CC & ~15) != 0 || - (I->isExternal() && I->hasDLLImportLinkage()) || - (I->isExternal() && I->hasExternalWeakLinkage()) + (I->isDeclaration() && I->hasDLLImportLinkage()) || + (I->isDeclaration() && I->hasExternalWeakLinkage()) ) ID |= 1 << 31; // Do we need an extension word? @@ -1042,7 +1046,7 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { // convention, bit 10 = hasSectionID., bits 11-12 = external linkage type unsigned extLinkage = 0; - if (I->isExternal()) { + if (I->isDeclaration()) { if (I->hasDLLImportLinkage()) { extLinkage = 1; } else if (I->hasExternalWeakLinkage()) { @@ -1077,6 +1081,9 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { // Output the target triple from the module output(M->getTargetTriple()); + + // Output the data layout from the module + output(M->getDataLayout()); // Emit the table of section names. output_vbr((unsigned)SectionNames.size()); @@ -1096,128 +1103,72 @@ void BytecodeWriter::outputInstructions(const Function *F) { void BytecodeWriter::outputFunction(const Function *F) { // If this is an external function, there is nothing else to emit! - if (F->isExternal()) return; + if (F->isDeclaration()) return; BytecodeBlock FunctionBlock(BytecodeFormat::FunctionBlockID, *this); - output_vbr(getEncodedLinkage(F)); + unsigned rWord = (getEncodedVisibility(F) << 16) | getEncodedLinkage(F); + output_vbr(rWord); // Get slot information about the function... Table.incorporateFunction(F); - if (Table.getCompactionTable().empty()) { - // Output information about the constants in the function if the compaction - // table is not being used. - outputConstants(true); - } else { - // Otherwise, emit the compaction table. - outputCompactionTable(); - } + outputConstants(true); // Output all of the instructions in the body of the function outputInstructions(F); // If needed, output the symbol table for the function... - outputSymbolTable(F->getSymbolTable()); + outputValueSymbolTable(F->getValueSymbolTable()); Table.purgeFunction(); } -void BytecodeWriter::outputCompactionTablePlane(unsigned PlaneNo, - const std::vector &Plane, - unsigned StartNo) { - unsigned End = Table.getModuleLevel(PlaneNo); - if (Plane.empty() || StartNo == End || End == 0) return; // Nothing to emit - assert(StartNo < End && "Cannot emit negative range!"); - assert(StartNo < Plane.size() && End <= Plane.size()); - - // Do not emit the null initializer! - ++StartNo; - - // Figure out which encoding to use. By far the most common case we have is - // to emit 0-2 entries in a compaction table plane. - switch (End-StartNo) { - case 0: // Avoid emitting two vbr's if possible. - case 1: - case 2: - output_vbr((PlaneNo << 2) | End-StartNo); - break; - default: - // Output the number of things. - output_vbr((unsigned(End-StartNo) << 2) | 3); - output_typeid(PlaneNo); // Emit the type plane this is - break; - } - - for (unsigned i = StartNo; i != End; ++i) - output_vbr(Table.getGlobalSlot(Plane[i])); -} - -void BytecodeWriter::outputCompactionTypes(unsigned StartNo) { - // Get the compaction type table from the slot calculator - const std::vector &CTypes = Table.getCompactionTypes(); - - // The compaction types may have been uncompactified back to the - // global types. If so, we just write an empty table - if (CTypes.size() == 0) { - output_vbr(0U); - return; - } - - assert(CTypes.size() >= StartNo && "Invalid compaction types start index"); - - // Determine how many types to write - unsigned NumTypes = CTypes.size() - StartNo; - - // Output the number of types. - output_vbr(NumTypes); - - for (unsigned i = StartNo; i < StartNo+NumTypes; ++i) - output_typeid(Table.getGlobalSlot(CTypes[i])); -} - -void BytecodeWriter::outputCompactionTable() { - // Avoid writing the compaction table at all if there is no content. - if (Table.getCompactionTypes().size() >= Type::FirstDerivedTyID || - (!Table.CompactionTableIsEmpty())) { - BytecodeBlock CTB(BytecodeFormat::CompactionTableBlockID, *this, - true/*ElideIfEmpty*/); - const std::vector > &CT = - Table.getCompactionTable(); - - // First things first, emit the type compaction table if there is one. - outputCompactionTypes(Type::FirstDerivedTyID); - for (unsigned i = 0, e = CT.size(); i != e; ++i) - outputCompactionTablePlane(i, CT[i], 0); - } -} - -void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) { - // Do not output the Bytecode block for an empty symbol table, it just wastes +void BytecodeWriter::outputTypeSymbolTable(const TypeSymbolTable &TST) { + // Do not output the block for an empty symbol table, it just wastes // space! - if (MST.isEmpty()) return; + if (TST.empty()) return; - BytecodeBlock SymTabBlock(BytecodeFormat::SymbolTableBlockID, *this, + // Create a header for the symbol table + BytecodeBlock SymTabBlock(BytecodeFormat::TypeSymbolTableBlockID, *this, true/*ElideIfEmpty*/); - // Write the number of types - output_vbr(MST.num_types()); + output_vbr(TST.size()); // Write each of the types - for (SymbolTable::type_const_iterator TI = MST.type_begin(), - TE = MST.type_end(); TI != TE; ++TI) { + for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end(); + TI != TE; ++TI) { // Symtab entry:[def slot #][name] output_typeid((unsigned)Table.getSlot(TI->second)); output(TI->first); } +} - // Now do each of the type planes in order. - for (SymbolTable::plane_const_iterator PI = MST.plane_begin(), - PE = MST.plane_end(); PI != PE; ++PI) { - SymbolTable::value_const_iterator I = MST.value_begin(PI->first); - SymbolTable::value_const_iterator End = MST.value_end(PI->first); +void BytecodeWriter::outputValueSymbolTable(const ValueSymbolTable &VST) { + // Do not output the Bytecode block for an empty symbol table, it just wastes + // space! + if (VST.empty()) return; + + BytecodeBlock SymTabBlock(BytecodeFormat::ValueSymbolTableBlockID, *this, + true/*ElideIfEmpty*/); + + // Organize the symbol table by type + typedef std::pair PlaneMapEntry; + typedef std::vector PlaneMapVector; + typedef std::map PlaneMap; + PlaneMap Planes; + for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end(); + SI != SE; ++SI) + Planes[SI->second->getType()].push_back( + std::make_pair(SI->first,SI->second)); + + for (PlaneMap::const_iterator PI = Planes.begin(), PE = Planes.end(); + PI != PE; ++PI) { int Slot; + PlaneMapVector::const_iterator I = PI->second.begin(); + PlaneMapVector::const_iterator End = PI->second.end(); + if (I == End) continue; // Don't mess with an absent type... // Write the number of values in this plane @@ -1239,13 +1190,13 @@ void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) { } } -void llvm::WriteBytecodeToFile(const Module *M, llvm_ostream &Out, +void llvm::WriteBytecodeToFile(const Module *M, OStream &Out, bool compress) { assert(M && "You can't write a null module!!"); // Make sure that std::cout is put into binary mode for systems // that care. - if (Out == llvm_cout) + if (Out == cout) sys::Program::ChangeStdoutToBinary(); // Create a vector of unsigned char for the bytecode output. We