X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBytecode%2FWriter%2FWriter.cpp;h=48cccda8f40676d0aa97208a161a9d9123fc99d7;hb=b74ed07bfd3af42331b1964c24c39912610a08f4;hp=b1f2634296f1c2ab104733258e1c4160914707e7;hpb=cb6682fa44e13262bdef7dd22b4ba90f8c2e7b97;p=oota-llvm.git diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index b1f2634296f..48cccda8f40 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -22,12 +22,14 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/SymbolTable.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/Compressor.h" #include "llvm/Support/MathExtras.h" +#include "llvm/System/Program.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" #include @@ -129,7 +131,7 @@ inline void BytecodeWriter::output_vbr(int i) { inline void BytecodeWriter::output(const std::string &s) { unsigned Len = s.length(); - output_vbr(Len ); // Strings may have an arbitrary length... + output_vbr(Len); // Strings may have an arbitrary length. Out.insert(Out.end(), s.begin(), s.end()); } @@ -141,8 +143,8 @@ inline void BytecodeWriter::output_float(float& FloatVal) { /// FIXME: This isn't optimal, it has size problems on some platforms /// where FP is not IEEE. uint32_t i = FloatToBits(FloatVal); - Out.push_back( static_cast( (i & 0xFF ))); - Out.push_back( static_cast( (i >> 8) & 0xFF)); + Out.push_back( static_cast( (i ) & 0xFF)); + Out.push_back( static_cast( (i >> 8 ) & 0xFF)); Out.push_back( static_cast( (i >> 16) & 0xFF)); Out.push_back( static_cast( (i >> 24) & 0xFF)); } @@ -151,8 +153,8 @@ inline void BytecodeWriter::output_double(double& DoubleVal) { /// FIXME: This isn't optimal, it has size problems on some platforms /// where FP is not IEEE. uint64_t i = DoubleToBits(DoubleVal); - Out.push_back( static_cast( (i & 0xFF ))); - Out.push_back( static_cast( (i >> 8) & 0xFF)); + Out.push_back( static_cast( (i ) & 0xFF)); + Out.push_back( static_cast( (i >> 8 ) & 0xFF)); Out.push_back( static_cast( (i >> 16) & 0xFF)); Out.push_back( static_cast( (i >> 24) & 0xFF)); Out.push_back( static_cast( (i >> 32) & 0xFF)); @@ -161,8 +163,8 @@ inline void BytecodeWriter::output_double(double& DoubleVal) { Out.push_back( static_cast( (i >> 56) & 0xFF)); } -inline BytecodeBlock::BytecodeBlock(unsigned ID, BytecodeWriter& w, - bool elideIfEmpty, bool hasLongFormat ) +inline BytecodeBlock::BytecodeBlock(unsigned ID, BytecodeWriter &w, + bool elideIfEmpty, bool hasLongFormat) : Id(ID), Writer(w), ElideIfEmpty(elideIfEmpty), HasLongFormat(hasLongFormat){ if (HasLongFormat) { @@ -389,6 +391,19 @@ void BytecodeWriter::outputConstant(const Constant *CPV) { return; } +/// outputInlineAsm - InlineAsm's get emitted to the constant pool, so they can +/// be shared by multiple uses. +void BytecodeWriter::outputInlineAsm(const InlineAsm *IA) { + // Output a marker, so we know when we have one one parsing the constant pool. + // Note that this encoding is 5 bytes: not very efficient for a marker. Since + // unique inline asms are rare, this should hardly matter. + output_vbr(~0U); + + output(IA->getAsmString()); + output(IA->getConstraintString()); + output_vbr(unsigned(IA->hasSideEffects())); +} + void BytecodeWriter::outputConstantStrings() { SlotCalculator::string_iterator I = Table.string_begin(); SlotCalculator::string_iterator E = Table.string_end(); @@ -416,7 +431,6 @@ void BytecodeWriter::outputConstantStrings() { //===----------------------------------------------------------------------===// //=== Instruction Output ===// //===----------------------------------------------------------------------===// -typedef unsigned char uchar; // outputInstructionFormat0 - Output those weird instructions that have a large // number of operands or have large operands themselves. @@ -514,7 +528,8 @@ void BytecodeWriter::outputInstrVarArgsCall(const Instruction *I, // variable argument. NumFixedOperands = 3+NumParams; } - output_vbr(2 * I->getNumOperands()-NumFixedOperands); + output_vbr(2 * I->getNumOperands()-NumFixedOperands + + unsigned(Opcode == 56 || Opcode == 58)); // The type for the function has already been emitted in the type field of the // instruction. Just emit the slot # now. @@ -535,6 +550,14 @@ void BytecodeWriter::outputInstrVarArgsCall(const Instruction *I, assert(Slot >= 0 && "No slot number for value!?!?"); output_vbr((unsigned)Slot); } + + // If this is the escape sequence for call, emit the tailcall/cc info. + if (Opcode == 58) { + const CallInst *CI = cast(I); + output_vbr((CI->getCallingConv() << 1) | unsigned(CI->isTailCall())); + } else if (Opcode == 56) { // Invoke escape sequence. + output_vbr(cast(I)->getCallingConv()); + } } @@ -693,6 +716,13 @@ void BytecodeWriter::outputInstruction(const Instruction &I) { assert(Slots[1] != ~0U && "Cast return type unknown?"); if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1]; NumOperands++; + } else if (const AllocationInst *AI = dyn_cast(&I)) { + assert(NumOperands == 1 && "Bogus allocation!"); + if (AI->getAlignment()) { + Slots[1] = Log2_32(AI->getAlignment())+1; + if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1]; + NumOperands = 2; + } } else if (const GetElementPtrInst *GEP = dyn_cast(&I)) { // We need to encode the type of sequential type indices into their slot # unsigned Idx = 1; @@ -714,8 +744,9 @@ void BytecodeWriter::outputInstruction(const Instruction &I) { // If this is the escape sequence for call, emit the tailcall/cc info. const CallInst &CI = cast(I); ++NumOperands; - if (NumOperands < 3) { - Slots[NumOperands-1] = (CI.getCallingConv() << 1)|unsigned(CI.isTailCall()); + if (NumOperands <= 3) { + Slots[NumOperands-1] = + (CI.getCallingConv() << 1)|unsigned(CI.isTailCall()); if (Slots[NumOperands-1] > MaxOpSlot) MaxOpSlot = Slots[NumOperands-1]; } @@ -769,7 +800,7 @@ BytecodeWriter::BytecodeWriter(std::vector &o, const Module *M) : Out(o), Table(M) { // Emit the signature... - static const unsigned char *Sig = (const unsigned char*)"llvm"; + static const unsigned char *Sig = (const unsigned char*)"llvm"; output_data(Sig, Sig+4); // Emit the top level CLASS block. @@ -789,8 +820,8 @@ BytecodeWriter::BytecodeWriter(std::vector &o, const Module *M) // The Global type plane comes first { - BytecodeBlock CPool(BytecodeFormat::GlobalTypePlaneBlockID, *this ); - outputTypes(Type::FirstDerivedTyID); + BytecodeBlock CPool(BytecodeFormat::GlobalTypePlaneBlockID, *this); + outputTypes(Type::FirstDerivedTyID); } // The ModuleInfoBlock follows directly after the type information @@ -841,7 +872,8 @@ void BytecodeWriter::outputConstantsInPlane(const std::vector /*empty*/; unsigned NC = ValNo; // Number of constants - for (; NC < Plane.size() && (isa(Plane[NC])); NC++) + for (; NC < Plane.size() && (isa(Plane[NC]) || + isa(Plane[NC])); NC++) /*empty*/; NC -= ValNo; // Convert from index into count if (NC == 0) return; // Skip empty type planes... @@ -860,9 +892,10 @@ void BytecodeWriter::outputConstantsInPlane(const std::vector for (unsigned i = ValNo; i < ValNo+NC; ++i) { const Value *V = Plane[i]; - if (const Constant *C = dyn_cast(V)) { + if (const Constant *C = dyn_cast(V)) outputConstant(C); - } + else + outputInlineAsm(cast(V)); } } @@ -905,28 +938,67 @@ void BytecodeWriter::outputConstants(bool isFunction) { static unsigned getEncodedLinkage(const GlobalValue *GV) { switch (GV->getLinkage()) { default: assert(0 && "Invalid linkage!"); - case GlobalValue::ExternalLinkage: return 0; - case GlobalValue::WeakLinkage: return 1; - case GlobalValue::AppendingLinkage: return 2; - case GlobalValue::InternalLinkage: return 3; - case GlobalValue::LinkOnceLinkage: return 4; + case GlobalValue::ExternalLinkage: return 0; + case GlobalValue::WeakLinkage: return 1; + case GlobalValue::AppendingLinkage: return 2; + case GlobalValue::InternalLinkage: return 3; + case GlobalValue::LinkOnceLinkage: return 4; + case GlobalValue::DLLImportLinkage: return 5; + case GlobalValue::DLLExportLinkage: return 6; + case GlobalValue::ExternalWeakLinkage: return 7; } } 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) { + End = M->global_end(); I != End; ++I) { int Slot = Table.getSlot(I->getType()); assert(Slot != -1 && "Module global vars is broken!"); + assert((I->hasInitializer() || !I->hasInternalLinkage()) && + "Global must have an initializer or have external linkage!"); + // Fields: bit0 = isConstant, bit1 = hasInitializer, bit2-4=Linkage, - // bit5+ = Slot # for type - unsigned oSlot = ((unsigned)Slot << 5) | (getEncodedLinkage(I) << 2) | - (I->hasInitializer() << 1) | (unsigned)I->isConstant(); - output_vbr(oSlot); + // bit5+ = Slot # for type. + bool HasExtensionWord = (I->getAlignment() != 0) || I->hasSection(); + + // If we need to use the extension byte, set linkage=3(internal) and + // initializer = 0 (impossible!). + if (!HasExtensionWord) { + unsigned oSlot = ((unsigned)Slot << 5) | (getEncodedLinkage(I) << 2) | + (I->hasInitializer() << 1) | (unsigned)I->isConstant(); + output_vbr(oSlot); + } else { + unsigned oSlot = ((unsigned)Slot << 5) | (3 << 2) | + (0 << 1) | (unsigned)I->isConstant(); + 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. + unsigned ExtWord = (unsigned)I->hasInitializer() | + (getEncodedLinkage(I) << 1) | + ((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. if (I->hasInitializer()) { @@ -942,18 +1014,49 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { int Slot = Table.getSlot(I->getType()); assert(Slot != -1 && "Module slot calculator is broken!"); assert(Slot >= Type::FirstDerivedTyID && "Derived type not in range!"); - assert(((Slot << 5) >> 5) == Slot && "Slot # too big!"); - unsigned ID = (Slot << 5); - - if (I->getCallingConv() < 15) - ID += I->getCallingConv()+1; + assert(((Slot << 6) >> 6) == Slot && "Slot # too big!"); + unsigned CC = I->getCallingConv()+1; + unsigned ID = (Slot << 5) | (CC & 15); if (I->isExternal()) // 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()) + ) + 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, bit 10 = hasSectionID., bits 11-12 = external linkage type + unsigned extLinkage = 0; + + if (I->isExternal()) { + if (I->hasDLLImportLinkage()) { + extLinkage = 1; + } else if (I->hasExternalWeakLinkage()) { + extLinkage = 2; + } + } - if (I->getCallingConv() >= 15) - output_vbr(I->getCallingConv()); + ID = (Log2_32(I->getAlignment())+1) | ((CC >> 4) << 5) | + (I->hasSection() << 10) | + ((extLinkage & 3) << 11); + 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); @@ -966,6 +1069,14 @@ 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]); + + // Output the inline asm string. + output(M->getModuleInlineAsm()); } void BytecodeWriter::outputInstructions(const Function *F) { @@ -1039,7 +1150,7 @@ void BytecodeWriter::outputCompactionTypes(unsigned StartNo) { // The compaction types may have been uncompactified back to the // global types. If so, we just write an empty table - if (CTypes.size() == 0 ) { + if (CTypes.size() == 0) { output_vbr(0U); return; } @@ -1086,7 +1197,7 @@ void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) { // Write each of the types for (SymbolTable::type_const_iterator TI = MST.type_begin(), - TE = MST.type_end(); TI != TE; ++TI ) { + TE = MST.type_end(); TI != TE; ++TI) { // Symtab entry:[def slot #][name] output_typeid((unsigned)Table.getSlot(TI->second)); output(TI->first); @@ -1121,9 +1232,14 @@ void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) { } void llvm::WriteBytecodeToFile(const Module *M, std::ostream &Out, - bool compress ) { + 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 == std::cout) + sys::Program::ChangeStdoutToBinary(); + // Create a vector of unsigned char for the bytecode output. We // reserve 256KBytes of space in the vector so that we avoid doing // lots of little allocations. 256KBytes is sufficient for a large @@ -1172,4 +1288,3 @@ void llvm::WriteBytecodeToFile(const Module *M, std::ostream &Out, // make sure it hits disk now Out.flush(); } -