X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBitcode%2FWriter%2FBitcodeWriter.cpp;h=279e447873cab76fc90b4097f95d852e64366816;hb=e2e9d8e6aa914b81d79ff496736165f3358c6f3a;hp=086dca8640e843f63ad299d1d72b0acb7c6dd966;hpb=3a08abfd3492b86b7305992a5e38b969aea5e9b8;p=oota-llvm.git diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 086dca8640e..279e447873c 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,12 @@ #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/Support/raw_ostream.h" +#include "llvm/System/Program.h" using namespace llvm; /// These are manifest constants used by the bitcode writer. They do not need to @@ -107,19 +109,20 @@ static void WriteStringRecord(unsigned Code, const std::string &Str, } // Emit information about parameter attributes. -static void WriteParamAttrTable(const ValueEnumerator &VE, +static void WriteAttributeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { - const std::vector &Attrs = VE.getParamAttrs(); + const std::vector &Attrs = VE.getAttributes(); 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 AttrListPtr &A = Attrs[i]; + for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) { + const AttributeWithIndex &PAWI = A.getSlot(i); + Record.push_back(PAWI.Index); + Record.push_back(PAWI.Attrs); } Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record); @@ -141,14 +144,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))); @@ -187,6 +190,9 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { 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::IntegerTyID: @@ -194,19 +200,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))); @@ -264,6 +273,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; } } @@ -295,9 +305,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(); @@ -315,13 +326,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. @@ -334,7 +356,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 { @@ -380,21 +402,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.getAttributeID(F->getAttributes())); 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); @@ -408,6 +426,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(); @@ -522,11 +541,22 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, } } else if (const ConstantFP *CFP = dyn_cast(C)) { Code = bitc::CST_CODE_FLOAT; - if (CFP->getType() == Type::FloatTy) { - Record.push_back(FloatToBits((float)CFP->getValue())); + const Type *Ty = CFP->getType(); + if (Ty == Type::FloatTy || Ty == Type::DoubleTy) { + Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue()); + } else if (Ty == Type::X86_FP80Ty) { + // api needed to prevent premature destruction + APInt api = CFP->getValueAPF().bitcastToAPInt(); + const uint64_t *p = api.getRawData(); + Record.push_back(p[0]); + Record.push_back((uint16_t)p[1]); + } else if (Ty == Type::FP128Ty || Ty == Type::PPC_FP128Ty) { + APInt api = CFP->getValueAPF().bitcastToAPInt(); + const uint64_t *p = api.getRawData(); + Record.push_back(p[0]); + Record.push_back(p[1]); } else { - assert (CFP->getType() == Type::DoubleTy && "Unknown FP type!"); - Record.push_back(DoubleToBits((double)CFP->getValue())); + assert (0 && "Unknown FP type!"); } } else if (isa(C) && cast(C)->isString()) { // Emit constant strings specially. @@ -609,7 +639,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))); @@ -689,11 +728,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; @@ -714,18 +770,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; @@ -746,12 +818,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.getAttributeID(II->getAttributes())); + 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 @@ -811,9 +880,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; @@ -823,14 +892,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.getAttributeID(CI->getAttributes())); + 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) @@ -1162,7 +1227,7 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) { WriteBlockInfo(VE, Stream); // Emit information about parameter attributes. - WriteParamAttrTable(VE, Stream); + WriteAttributeTable(VE, Stream); // Emit information describing all of the types in the module. WriteTypeTable(VE, Stream); @@ -1198,15 +1263,94 @@ 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. void llvm::WriteBitcodeToFile(const Module *M, std::ostream &Out) { + raw_os_ostream RawOut(Out); + // If writing to stdout, set binary mode. + if (llvm::cout == Out) + sys::Program::ChangeStdoutToBinary(); + WriteBitcodeToFile(M, RawOut); +} + +/// WriteBitcodeToFile - Write the specified module to the specified output +/// stream. +void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) { std::vector Buffer; BitstreamWriter Stream(Buffer); 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); @@ -1217,7 +1361,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::outs() == &Out) + sys::Program::ChangeStdoutToBinary(); + // Write the generated bitstream to "Out". Out.write((char*)&Buffer.front(), Buffer.size());