X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FBitcode%2FWriter%2FBitcodeWriter.cpp;h=931e944a410d1dc13f9abe128a4b5b95771cfb2f;hb=d9b4a5f859188cbb168c223071b413e58c53c925;hp=fdaa9be5bb615b5b586c463387a32d4759e0502c;hpb=9d5f45607793052bf5b4436d1b43013fab9999ac;p=oota-llvm.git diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index fdaa9be5bb6..931e944a410 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Chris Lattner and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -20,10 +20,11 @@ #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Module.h" -#include "llvm/ParameterAttributes.h" #include "llvm/TypeSymbolTable.h" #include "llvm/ValueSymbolTable.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/Streams.h" +#include "llvm/System/Program.h" using namespace llvm; /// These are manifest constants used by the bitcode writer. They do not need to @@ -109,17 +110,18 @@ static void WriteStringRecord(unsigned Code, const std::string &Str, // Emit information about parameter attributes. static void WriteParamAttrTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { - const std::vector &Attrs = VE.getParamAttrs(); + const std::vector &Attrs = VE.getParamAttrs(); if (Attrs.empty()) return; Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3); SmallVector Record; for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { - const ParamAttrsList *A = Attrs[i]; - for (unsigned op = 0, e = A->size(); op != e; ++op) { - Record.push_back(A->getParamIndex(op)); - Record.push_back(A->getParamAttrsAtIndex(op)); + const PAListPtr &A = Attrs[i]; + for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) { + const ParamAttrsWithIndex &PAWI = A.getSlot(i); + Record.push_back(PAWI.Index); + Record.push_back(PAWI.Attrs); } Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record); @@ -141,14 +143,14 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(VE.getTypes().size()+1))); + Abbv->Add(BitCodeAbbrevOp(0)); // Addrspace = 0 unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv); // Abbrev for TYPE_CODE_FUNCTION. Abbv = new BitCodeAbbrev(); Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_FUNCTION)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isvararg - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, - Log2_32_Ceil(VE.getParamAttrs().size()+1))); + Abbv->Add(BitCodeAbbrevOp(0)); // FIXME: DEAD value, remove in LLVM 3.0 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(VE.getTypes().size()+1))); @@ -197,19 +199,22 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { Code = bitc::TYPE_CODE_INTEGER; TypeVals.push_back(cast(T)->getBitWidth()); break; - case Type::PointerTyID: - // POINTER: [pointee type] + case Type::PointerTyID: { + const PointerType *PTy = cast(T); + // POINTER: [pointee type, address space] Code = bitc::TYPE_CODE_POINTER; - TypeVals.push_back(VE.getTypeID(cast(T)->getElementType())); - AbbrevToUse = PtrAbbrev; + TypeVals.push_back(VE.getTypeID(PTy->getElementType())); + unsigned AddressSpace = PTy->getAddressSpace(); + TypeVals.push_back(AddressSpace); + if (AddressSpace == 0) AbbrevToUse = PtrAbbrev; break; - + } case Type::FunctionTyID: { const FunctionType *FT = cast(T); // FUNCTION: [isvararg, attrid, retty, paramty x N] Code = bitc::TYPE_CODE_FUNCTION; TypeVals.push_back(FT->isVarArg()); - TypeVals.push_back(VE.getParamAttrID(FT->getParamAttrs())); + TypeVals.push_back(0); // FIXME: DEAD: remove in llvm 3.0 TypeVals.push_back(VE.getTypeID(FT->getReturnType())); for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) TypeVals.push_back(VE.getTypeID(FT->getParamType(i))); @@ -267,6 +272,7 @@ static unsigned getEncodedLinkage(const GlobalValue *GV) { case GlobalValue::DLLImportLinkage: return 5; case GlobalValue::DLLExportLinkage: return 6; case GlobalValue::ExternalWeakLinkage: return 7; + case GlobalValue::CommonLinkage: return 8; } } @@ -298,9 +304,10 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(), 0/*TODO*/, Stream); - // Emit information about sections, computing how many there are. Also + // Emit information about sections and GC, computing how many there are. Also // compute the maximum alignment value. std::map SectionMap; + std::map GCMap; unsigned MaxAlignment = 0; unsigned MaxGlobalType = 0; for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end(); @@ -318,13 +325,24 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, } for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) { MaxAlignment = std::max(MaxAlignment, F->getAlignment()); - if (!F->hasSection()) continue; - // Give section names unique ID's. - unsigned &Entry = SectionMap[F->getSection()]; - if (Entry != 0) continue; - WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F->getSection(), - 0/*TODO*/, Stream); - Entry = SectionMap.size(); + if (F->hasSection()) { + // Give section names unique ID's. + unsigned &Entry = SectionMap[F->getSection()]; + if (!Entry) { + WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F->getSection(), + 0/*TODO*/, Stream); + Entry = SectionMap.size(); + } + } + if (F->hasGC()) { + // Same for GC names. + unsigned &Entry = GCMap[F->getGC()]; + if (!Entry) { + WriteStringRecord(bitc::MODULE_CODE_GCNAME, F->getGC(), + 0/*TODO*/, Stream); + Entry = GCMap.size(); + } + } } // Emit abbrev for globals, now that we know # sections and max alignment. @@ -337,7 +355,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, Log2_32_Ceil(MaxGlobalType+1))); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Constant. Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Initializer. - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage. + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // Linkage. if (MaxAlignment == 0) // Alignment. Abbv->Add(BitCodeAbbrevOp(0)); else { @@ -383,21 +401,17 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, // Emit the function proto information. for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) { - // FUNCTION: [type, callingconv, isproto, linkage, alignment, section, - // visibility] + // FUNCTION: [type, callingconv, isproto, paramattr, + // linkage, alignment, section, visibility, gc] Vals.push_back(VE.getTypeID(F->getType())); Vals.push_back(F->getCallingConv()); Vals.push_back(F->isDeclaration()); Vals.push_back(getEncodedLinkage(F)); - - // Note: we emit the param attr ID number for the function type of this - // function. In the future, we intend for attrs to be properties of - // functions, instead of on the type. This is to support this future work. - Vals.push_back(VE.getParamAttrID(F->getFunctionType()->getParamAttrs())); - + Vals.push_back(VE.getParamAttrID(F->getParamAttrs())); Vals.push_back(Log2_32(F->getAlignment())+1); Vals.push_back(F->hasSection() ? SectionMap[F->getSection()] : 0); Vals.push_back(getEncodedVisibility(F)); + Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0); unsigned AbbrevToUse = 0; Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); @@ -411,6 +425,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, Vals.push_back(VE.getTypeID(AI->getType())); Vals.push_back(VE.getValueID(AI->getAliasee())); Vals.push_back(getEncodedLinkage(AI)); + Vals.push_back(getEncodedVisibility(AI)); unsigned AbbrevToUse = 0; Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse); Vals.clear(); @@ -529,15 +544,16 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, if (Ty == Type::FloatTy || Ty == Type::DoubleTy) { Record.push_back(CFP->getValueAPF().convertToAPInt().getZExtValue()); } else if (Ty == Type::X86_FP80Ty) { - const uint64_t *p = CFP->getValueAPF().convertToAPInt().getRawData(); + // api needed to prevent premature destruction + APInt api = CFP->getValueAPF().convertToAPInt(); + const uint64_t *p = api.getRawData(); Record.push_back(p[0]); Record.push_back((uint16_t)p[1]); - } else if (Ty == Type::FP128Ty) { - const uint64_t *p = CFP->getValueAPF().convertToAPInt().getRawData(); + } else if (Ty == Type::FP128Ty || Ty == Type::PPC_FP128Ty) { + APInt api = CFP->getValueAPF().convertToAPInt(); + const uint64_t *p = api.getRawData(); Record.push_back(p[0]); Record.push_back(p[1]); - } else if (Ty == Type::PPC_FP128Ty) { - assert(0 && "PowerPC long double constants not handled yet."); } else { assert (0 && "Unknown FP type!"); } @@ -622,7 +638,16 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, break; case Instruction::ICmp: case Instruction::FCmp: - Code = bitc::CST_CODE_CE_CMP; + case Instruction::VICmp: + case Instruction::VFCmp: + if (isa(C->getOperand(0)->getType()) + && (CE->getOpcode() == Instruction::ICmp + || CE->getOpcode() == Instruction::FCmp)) { + // compare returning vector of Int1Ty + assert(0 && "Unsupported constant!"); + } else { + Code = bitc::CST_CODE_CE_CMP; + } Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); Record.push_back(VE.getValueID(C->getOperand(0))); Record.push_back(VE.getValueID(C->getOperand(1))); @@ -702,11 +727,28 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) PushValueAndType(I.getOperand(i), InstID, Vals, VE); break; + case Instruction::ExtractValue: { + Code = bitc::FUNC_CODE_INST_EXTRACTVAL; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + const ExtractValueInst *EVI = cast(&I); + for (const unsigned *i = EVI->idx_begin(), *e = EVI->idx_end(); i != e; ++i) + Vals.push_back(*i); + break; + } + case Instruction::InsertValue: { + Code = bitc::FUNC_CODE_INST_INSERTVAL; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + PushValueAndType(I.getOperand(1), InstID, Vals, VE); + const InsertValueInst *IVI = cast(&I); + for (const unsigned *i = IVI->idx_begin(), *e = IVI->idx_end(); i != e; ++i) + Vals.push_back(*i); + break; + } case Instruction::Select: - Code = bitc::FUNC_CODE_INST_SELECT; + Code = bitc::FUNC_CODE_INST_VSELECT; PushValueAndType(I.getOperand(1), InstID, Vals, VE); Vals.push_back(VE.getValueID(I.getOperand(2))); - Vals.push_back(VE.getValueID(I.getOperand(0))); + PushValueAndType(I.getOperand(0), InstID, Vals, VE); break; case Instruction::ExtractElement: Code = bitc::FUNC_CODE_INST_EXTRACTELT; @@ -727,18 +769,34 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, break; case Instruction::ICmp: case Instruction::FCmp: - Code = bitc::FUNC_CODE_INST_CMP; + case Instruction::VICmp: + case Instruction::VFCmp: + if (I.getOpcode() == Instruction::ICmp + || I.getOpcode() == Instruction::FCmp) { + // compare returning Int1Ty or vector of Int1Ty + Code = bitc::FUNC_CODE_INST_CMP2; + } else { + Code = bitc::FUNC_CODE_INST_CMP; + } PushValueAndType(I.getOperand(0), InstID, Vals, VE); Vals.push_back(VE.getValueID(I.getOperand(1))); Vals.push_back(cast(I).getPredicate()); break; - case Instruction::Ret: - Code = bitc::FUNC_CODE_INST_RET; - if (!I.getNumOperands()) - AbbrevToUse = FUNCTION_INST_RET_VOID_ABBREV; - else if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) - AbbrevToUse = FUNCTION_INST_RET_VAL_ABBREV; + case Instruction::Ret: + { + Code = bitc::FUNC_CODE_INST_RET; + unsigned NumOperands = I.getNumOperands(); + if (NumOperands == 0) + AbbrevToUse = FUNCTION_INST_RET_VOID_ABBREV; + else if (NumOperands == 1) { + if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) + AbbrevToUse = FUNCTION_INST_RET_VAL_ABBREV; + } else { + for (unsigned i = 0, e = NumOperands; i != e; ++i) + PushValueAndType(I.getOperand(i), InstID, Vals, VE); + } + } break; case Instruction::Br: Code = bitc::FUNC_CODE_INST_BR; @@ -759,12 +817,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, const FunctionType *FTy = cast(PTy->getElementType()); Code = bitc::FUNC_CODE_INST_INVOKE; - // Note: we emit the param attr ID number for the function type of this - // function. In the future, we intend for attrs to be properties of - // functions, instead of on the type. This is to support this future work. - Vals.push_back(VE.getParamAttrID(FTy->getParamAttrs())); - - Vals.push_back(cast(I).getCallingConv()); + const InvokeInst *II = cast(&I); + Vals.push_back(VE.getParamAttrID(II->getParamAttrs())); + Vals.push_back(II->getCallingConv()); Vals.push_back(VE.getValueID(I.getOperand(1))); // normal dest Vals.push_back(VE.getValueID(I.getOperand(2))); // unwind dest PushValueAndType(I.getOperand(0), InstID, Vals, VE); // callee @@ -824,9 +879,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Vals.push_back(cast(I).isVolatile()); break; case Instruction::Store: - Code = bitc::FUNC_CODE_INST_STORE; - PushValueAndType(I.getOperand(0), InstID, Vals, VE); // val. - Vals.push_back(VE.getValueID(I.getOperand(1))); // ptr. + Code = bitc::FUNC_CODE_INST_STORE2; + PushValueAndType(I.getOperand(1), InstID, Vals, VE); // ptrty + ptr + Vals.push_back(VE.getValueID(I.getOperand(0))); // val. Vals.push_back(Log2_32(cast(I).getAlignment())+1); Vals.push_back(cast(I).isVolatile()); break; @@ -836,14 +891,10 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Code = bitc::FUNC_CODE_INST_CALL; - // Note: we emit the param attr ID number for the function type of this - // function. In the future, we intend for attrs to be properties of - // functions, instead of on the type. This is to support this future work. - Vals.push_back(VE.getParamAttrID(FTy->getParamAttrs())); - - Vals.push_back((cast(I).getCallingConv() << 1) | - unsigned(cast(I).isTailCall())); - PushValueAndType(I.getOperand(0), InstID, Vals, VE); // Callee + const CallInst *CI = cast(&I); + Vals.push_back(VE.getParamAttrID(CI->getParamAttrs())); + Vals.push_back((CI->getCallingConv() << 1) | unsigned(CI->isTailCall())); + PushValueAndType(CI->getOperand(0), InstID, Vals, VE); // Callee // Emit value #'s for the fixed parameters. for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) @@ -1211,6 +1262,70 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) { Stream.ExitBlock(); } +/// EmitDarwinBCHeader - If generating a bc file on darwin, we have to emit a +/// header and trailer to make it compatible with the system archiver. To do +/// this we emit the following header, and then emit a trailer that pads the +/// file out to be a multiple of 16 bytes. +/// +/// struct bc_header { +/// uint32_t Magic; // 0x0B17C0DE +/// uint32_t Version; // Version, currently always 0. +/// uint32_t BitcodeOffset; // Offset to traditional bitcode file. +/// uint32_t BitcodeSize; // Size of traditional bitcode file. +/// uint32_t CPUType; // CPU specifier. +/// ... potentially more later ... +/// }; +enum { + DarwinBCSizeFieldOffset = 3*4, // Offset to bitcode_size. + DarwinBCHeaderSize = 5*4 +}; + +static void EmitDarwinBCHeader(BitstreamWriter &Stream, + const std::string &TT) { + unsigned CPUType = ~0U; + + // Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*. The CPUType is a + // magic number from /usr/include/mach/machine.h. It is ok to reproduce the + // specific constants here because they are implicitly part of the Darwin ABI. + enum { + DARWIN_CPU_ARCH_ABI64 = 0x01000000, + DARWIN_CPU_TYPE_X86 = 7, + DARWIN_CPU_TYPE_POWERPC = 18 + }; + + if (TT.find("x86_64-") == 0) + CPUType = DARWIN_CPU_TYPE_X86 | DARWIN_CPU_ARCH_ABI64; + else if (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' && + TT[4] == '-' && TT[1] - '3' < 6) + CPUType = DARWIN_CPU_TYPE_X86; + else if (TT.find("powerpc-") == 0) + CPUType = DARWIN_CPU_TYPE_POWERPC; + else if (TT.find("powerpc64-") == 0) + CPUType = DARWIN_CPU_TYPE_POWERPC | DARWIN_CPU_ARCH_ABI64; + + // Traditional Bitcode starts after header. + unsigned BCOffset = DarwinBCHeaderSize; + + Stream.Emit(0x0B17C0DE, 32); + Stream.Emit(0 , 32); // Version. + Stream.Emit(BCOffset , 32); + Stream.Emit(0 , 32); // Filled in later. + Stream.Emit(CPUType , 32); +} + +/// EmitDarwinBCTrailer - Emit the darwin epilog after the bitcode file and +/// finalize the header. +static void EmitDarwinBCTrailer(BitstreamWriter &Stream, unsigned BufferSize) { + // Update the size field in the header. + Stream.BackpatchWord(DarwinBCSizeFieldOffset, BufferSize-DarwinBCHeaderSize); + + // If the file is not a multiple of 16 bytes, insert dummy padding. + while (BufferSize & 15) { + Stream.Emit(0, 8); + ++BufferSize; + } +} + /// WriteBitcodeToFile - Write the specified module to the specified output /// stream. @@ -1220,6 +1335,11 @@ void llvm::WriteBitcodeToFile(const Module *M, std::ostream &Out) { Buffer.reserve(256*1024); + // If this is darwin, emit a file header and trailer if needed. + bool isDarwin = M->getTargetTriple().find("-darwin") != std::string::npos; + if (isDarwin) + EmitDarwinBCHeader(Stream, M->getTargetTriple()); + // Emit the file header. Stream.Emit((unsigned)'B', 8); Stream.Emit((unsigned)'C', 8); @@ -1230,7 +1350,15 @@ void llvm::WriteBitcodeToFile(const Module *M, std::ostream &Out) { // Emit the module. WriteModule(M, Stream); + + if (isDarwin) + EmitDarwinBCTrailer(Stream, Buffer.size()); + + // If writing to stdout, set binary mode. + if (llvm::cout == Out) + sys::Program::ChangeStdoutToBinary(); + // Write the generated bitstream to "Out". Out.write((char*)&Buffer.front(), Buffer.size());