diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-02-16 09:30:23 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-02-16 09:30:23 +0000 |
commit | f25ddd991a5601d0101602c4c263a58c7af4b8a2 (patch) | |
tree | 4cfca640904d1896e25032757a61f8959c066919 /lib/Bitcode | |
parent | 3fd58f91dd318518f7daa4ba64c0aaf31799d89b (diff) | |
download | FreeBSD-src-f25ddd991a5601d0101602c4c263a58c7af4b8a2.zip FreeBSD-src-f25ddd991a5601d0101602c4c263a58c7af4b8a2.tar.gz |
Update LLVM to r96341.
Diffstat (limited to 'lib/Bitcode')
-rw-r--r-- | lib/Bitcode/Reader/BitReader.cpp | 31 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 160 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.h | 37 | ||||
-rw-r--r-- | lib/Bitcode/Reader/Makefile | 1 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 66 | ||||
-rw-r--r-- | lib/Bitcode/Writer/Makefile | 1 | ||||
-rw-r--r-- | lib/Bitcode/Writer/ValueEnumerator.cpp | 14 |
7 files changed, 174 insertions, 136 deletions
diff --git a/lib/Bitcode/Reader/BitReader.cpp b/lib/Bitcode/Reader/BitReader.cpp index 32b97e8..7537435 100644 --- a/lib/Bitcode/Reader/BitReader.cpp +++ b/lib/Bitcode/Reader/BitReader.cpp @@ -21,17 +21,8 @@ using namespace llvm; Optionally returns a human-readable error message via OutMessage. */ LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule, char **OutMessage) { - std::string Message; - - *OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), getGlobalContext(), - &Message)); - if (!*OutModule) { - if (OutMessage) - *OutMessage = strdup(Message.c_str()); - return 1; - } - - return 0; + return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule, + OutMessage); } LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, @@ -57,18 +48,8 @@ LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf, LLVMModuleProviderRef *OutMP, char **OutMessage) { - std::string Message; - - *OutMP = wrap(getBitcodeModuleProvider(unwrap(MemBuf), getGlobalContext(), - &Message)); - - if (!*OutMP) { - if (OutMessage) - *OutMessage = strdup(Message.c_str()); - return 1; - } - - return 0; + return LLVMGetBitcodeModuleProviderInContext(wrap(&getGlobalContext()), + MemBuf, OutMP, OutMessage); } LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef, @@ -77,8 +58,8 @@ LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef, char **OutMessage) { std::string Message; - *OutMP = wrap(getBitcodeModuleProvider(unwrap(MemBuf), *unwrap(ContextRef), - &Message)); + *OutMP = reinterpret_cast<LLVMModuleProviderRef>( + getLazyBitcodeModule(unwrap(MemBuf), *unwrap(ContextRef), &Message)); if (!*OutMP) { if (OutMessage) *OutMessage = strdup(Message.c_str()); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 2549a51..cebfbf6 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -28,7 +28,8 @@ using namespace llvm; void BitcodeReader::FreeState() { - delete Buffer; + if (BufferOwned) + delete Buffer; Buffer = 0; std::vector<PATypeHolder>().swap(TypeList); ValueList.clear(); @@ -107,17 +108,17 @@ static int GetDecodedBinaryOpcode(unsigned Val, const Type *Ty) { switch (Val) { default: return -1; case bitc::BINOP_ADD: - return Ty->isFPOrFPVector() ? Instruction::FAdd : Instruction::Add; + return Ty->isFPOrFPVectorTy() ? Instruction::FAdd : Instruction::Add; case bitc::BINOP_SUB: - return Ty->isFPOrFPVector() ? Instruction::FSub : Instruction::Sub; + return Ty->isFPOrFPVectorTy() ? Instruction::FSub : Instruction::Sub; case bitc::BINOP_MUL: - return Ty->isFPOrFPVector() ? Instruction::FMul : Instruction::Mul; + return Ty->isFPOrFPVectorTy() ? Instruction::FMul : Instruction::Mul; case bitc::BINOP_UDIV: return Instruction::UDiv; case bitc::BINOP_SDIV: - return Ty->isFPOrFPVector() ? Instruction::FDiv : Instruction::SDiv; + return Ty->isFPOrFPVectorTy() ? Instruction::FDiv : Instruction::SDiv; case bitc::BINOP_UREM: return Instruction::URem; case bitc::BINOP_SREM: - return Ty->isFPOrFPVector() ? Instruction::FRem : Instruction::SRem; + return Ty->isFPOrFPVectorTy() ? Instruction::FRem : Instruction::SRem; case bitc::BINOP_SHL: return Instruction::Shl; case bitc::BINOP_LSHR: return Instruction::LShr; case bitc::BINOP_ASHR: return Instruction::AShr; @@ -584,6 +585,13 @@ bool BitcodeReader::ParseTypeTable() { ResultTy = StructType::get(Context, EltTys, Record[0]); break; } + case bitc::TYPE_CODE_UNION: { // UNION: [eltty x N] + SmallVector<const Type*, 8> EltTys; + for (unsigned i = 0, e = Record.size(); i != e; ++i) + EltTys.push_back(getTypeByID(Record[i], true)); + ResultTy = UnionType::get(&EltTys[0], EltTys.size()); + break; + } case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty] if (Record.size() < 2) return Error("Invalid ARRAY type record"); @@ -1167,7 +1175,7 @@ bool BitcodeReader::ParseConstants() { Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy); - if (OpTy->isFPOrFPVector()) + if (OpTy->isFPOrFPVectorTy()) V = ConstantExpr::getFCmp(Record[3], Op0, Op1); else V = ConstantExpr::getICmp(Record[3], Op0, Op1); @@ -1241,11 +1249,7 @@ bool BitcodeReader::RememberAndSkipFunctionBody() { // Save the current stream state. uint64_t CurBit = Stream.GetCurrentBitNo(); - DeferredFunctionInfo[Fn] = std::make_pair(CurBit, Fn->getLinkage()); - - // Set the functions linkage to GhostLinkage so we know it is lazily - // deserialized. - Fn->setLinkage(GlobalValue::GhostLinkage); + DeferredFunctionInfo[Fn] = CurBit; // Skip over the function block for now. if (Stream.SkipBlock()) @@ -1253,17 +1257,10 @@ bool BitcodeReader::RememberAndSkipFunctionBody() { return false; } -bool BitcodeReader::ParseModule(const std::string &ModuleID) { - // Reject multiple MODULE_BLOCK's in a single bitstream. - if (TheModule) - return Error("Multiple MODULE_BLOCKs in same stream"); - +bool BitcodeReader::ParseModule() { if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) return Error("Malformed block record"); - // Otherwise, create the module. - TheModule = new Module(ModuleID, Context); - SmallVector<uint64_t, 64> Record; std::vector<std::string> SectionTable; std::vector<std::string> GCTable; @@ -1520,7 +1517,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { return Error("Premature end of bitstream"); } -bool BitcodeReader::ParseBitcode() { +bool BitcodeReader::ParseBitcodeInto(Module *M) { TheModule = 0; if (Buffer->getBufferSize() & 3) @@ -1564,7 +1561,11 @@ bool BitcodeReader::ParseBitcode() { return Error("Malformed BlockInfoBlock"); break; case bitc::MODULE_BLOCK_ID: - if (ParseModule(Buffer->getBufferIdentifier())) + // Reject multiple MODULE_BLOCK's in a single bitstream. + if (TheModule) + return Error("Multiple MODULE_BLOCKs in same stream"); + TheModule = M; + if (ParseModule()) return true; break; default: @@ -1702,12 +1703,12 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (Opc == Instruction::Add || Opc == Instruction::Sub || Opc == Instruction::Mul) { - if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP)) + if (Record[OpNum] & (1 << bitc::OBO_NO_SIGNED_WRAP)) cast<BinaryOperator>(I)->setHasNoSignedWrap(true); - if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP)) + if (Record[OpNum] & (1 << bitc::OBO_NO_UNSIGNED_WRAP)) cast<BinaryOperator>(I)->setHasNoUnsignedWrap(true); } else if (Opc == Instruction::SDiv) { - if (Record[3] & (1 << bitc::SDIV_EXACT)) + if (Record[OpNum] & (1 << bitc::SDIV_EXACT)) cast<BinaryOperator>(I)->setIsExact(true); } } @@ -1891,7 +1892,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { OpNum+1 != Record.size()) return Error("Invalid CMP record"); - if (LHS->getType()->isFPOrFPVector()) + if (LHS->getType()->isFPOrFPVectorTy()) I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS); else I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS); @@ -2299,22 +2300,28 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { } //===----------------------------------------------------------------------===// -// ModuleProvider implementation +// GVMaterializer implementation //===----------------------------------------------------------------------===// -bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) { - // If it already is material, ignore the request. - if (!F->hasNotBeenReadFromBitcode()) return false; +bool BitcodeReader::isMaterializable(const GlobalValue *GV) const { + if (const Function *F = dyn_cast<Function>(GV)) { + return F->isDeclaration() && + DeferredFunctionInfo.count(const_cast<Function*>(F)); + } + return false; +} - DenseMap<Function*, std::pair<uint64_t, unsigned> >::iterator DFII = - DeferredFunctionInfo.find(F); +bool BitcodeReader::Materialize(GlobalValue *GV, std::string *ErrInfo) { + Function *F = dyn_cast<Function>(GV); + // If it's not a function or is already material, ignore the request. + if (!F || !F->isMaterializable()) return false; + + DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F); assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); - // Move the bit stream to the saved position of the deferred function body and - // restore the real linkage type for the function. - Stream.JumpToBit(DFII->second.first); - F->setLinkage((GlobalValue::LinkageTypes)DFII->second.second); + // Move the bit stream to the saved position of the deferred function body. + Stream.JumpToBit(DFII->second); if (ParseFunctionBody(F)) { if (ErrInfo) *ErrInfo = ErrorString; @@ -2336,27 +2343,36 @@ bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) { return false; } -void BitcodeReader::dematerializeFunction(Function *F) { - // If this function isn't materialized, or if it is a proto, this is a noop. - if (F->hasNotBeenReadFromBitcode() || F->isDeclaration()) +bool BitcodeReader::isDematerializable(const GlobalValue *GV) const { + const Function *F = dyn_cast<Function>(GV); + if (!F || F->isDeclaration()) + return false; + return DeferredFunctionInfo.count(const_cast<Function*>(F)); +} + +void BitcodeReader::Dematerialize(GlobalValue *GV) { + Function *F = dyn_cast<Function>(GV); + // If this function isn't dematerializable, this is a noop. + if (!F || !isDematerializable(F)) return; assert(DeferredFunctionInfo.count(F) && "No info to read function later?"); // Just forget the function body, we can remat it later. F->deleteBody(); - F->setLinkage(GlobalValue::GhostLinkage); } -Module *BitcodeReader::materializeModule(std::string *ErrInfo) { +bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) { + assert(M == TheModule && + "Can only Materialize the Module this BitcodeReader is attached to."); // Iterate over the module, deserializing any functions that are still on // disk. for (Module::iterator F = TheModule->begin(), E = TheModule->end(); F != E; ++F) - if (F->hasNotBeenReadFromBitcode() && - materializeFunction(F, ErrInfo)) - return 0; + if (F->isMaterializable() && + Materialize(F, ErrInfo)) + return true; // Upgrade any intrinsic calls that slipped through (should not happen!) and // delete the old functions to clean up. We can't do this unless the entire @@ -2380,19 +2396,7 @@ Module *BitcodeReader::materializeModule(std::string *ErrInfo) { // Check debug info intrinsics. CheckDebugInfoIntrinsics(TheModule); - return TheModule; -} - - -/// This method is provided by the parent ModuleProvde class and overriden -/// here. It simply releases the module from its provided and frees up our -/// state. -/// @brief Release our hold on the generated module -Module *BitcodeReader::releaseModule(std::string *ErrInfo) { - // Since we're losing control of this Module, we must hand it back complete - Module *M = ModuleProvider::releaseModule(ErrInfo); - FreeState(); - return M; + return false; } @@ -2400,45 +2404,41 @@ Module *BitcodeReader::releaseModule(std::string *ErrInfo) { // External interface //===----------------------------------------------------------------------===// -/// getBitcodeModuleProvider - lazy function-at-a-time loading from a file. +/// getLazyBitcodeModule - lazy function-at-a-time loading from a file. /// -ModuleProvider *llvm::getBitcodeModuleProvider(MemoryBuffer *Buffer, - LLVMContext& Context, - std::string *ErrMsg) { +Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer, + LLVMContext& Context, + std::string *ErrMsg) { + Module *M = new Module(Buffer->getBufferIdentifier(), Context); BitcodeReader *R = new BitcodeReader(Buffer, Context); - if (R->ParseBitcode()) { + M->setMaterializer(R); + if (R->ParseBitcodeInto(M)) { if (ErrMsg) *ErrMsg = R->getErrorString(); - // Don't let the BitcodeReader dtor delete 'Buffer'. - R->releaseMemoryBuffer(); - delete R; + delete M; // Also deletes R. return 0; } - return R; + // Have the BitcodeReader dtor delete 'Buffer'. + R->setBufferOwned(true); + return M; } /// ParseBitcodeFile - Read the specified bitcode file, returning the module. /// If an error occurs, return null and fill in *ErrMsg if non-null. Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context, std::string *ErrMsg){ - BitcodeReader *R; - R = static_cast<BitcodeReader*>(getBitcodeModuleProvider(Buffer, Context, - ErrMsg)); - if (!R) return 0; - - // Read in the entire module. - Module *M = R->materializeModule(ErrMsg); + Module *M = getLazyBitcodeModule(Buffer, Context, ErrMsg); + if (!M) return 0; // Don't let the BitcodeReader dtor delete 'Buffer', regardless of whether // there was an error. - R->releaseMemoryBuffer(); + static_cast<BitcodeReader*>(M->getMaterializer())->setBufferOwned(false); - // If there was no error, tell ModuleProvider not to delete it when its dtor - // is run. - if (M) - M = R->releaseModule(ErrMsg); - - delete R; + // Read in the entire module, and destroy the BitcodeReader. + if (M->MaterializeAllPermanently(ErrMsg)) { + delete M; + return NULL; + } return M; } diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index bb3961a..55c71f7 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -14,7 +14,7 @@ #ifndef BITCODE_READER_H #define BITCODE_READER_H -#include "llvm/ModuleProvider.h" +#include "llvm/GVMaterializer.h" #include "llvm/Attributes.h" #include "llvm/Type.h" #include "llvm/OperandTraits.h" @@ -121,9 +121,11 @@ public: void AssignValue(Value *V, unsigned Idx); }; -class BitcodeReader : public ModuleProvider { +class BitcodeReader : public GVMaterializer { LLVMContext &Context; + Module *TheModule; MemoryBuffer *Buffer; + bool BufferOwned; BitstreamReader StreamFile; BitstreamCursor Stream; @@ -160,9 +162,9 @@ class BitcodeReader : public ModuleProvider { bool HasReversedFunctionsWithBodies; /// DeferredFunctionInfo - When function bodies are initially scanned, this - /// map contains info about where to find deferred function body (in the - /// stream) and what linkage the original function had. - DenseMap<Function*, std::pair<uint64_t, unsigned> > DeferredFunctionInfo; + /// map contains info about where to find deferred function body in the + /// stream. + DenseMap<Function*, uint64_t> DeferredFunctionInfo; /// BlockAddrFwdRefs - These are blockaddr references to basic blocks. These /// are resolved lazily when functions are loaded. @@ -171,7 +173,8 @@ class BitcodeReader : public ModuleProvider { public: explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C) - : Context(C), Buffer(buffer), ErrorString(0), ValueList(C), MDValueList(C) { + : Context(C), TheModule(0), Buffer(buffer), BufferOwned(false), + ErrorString(0), ValueList(C), MDValueList(C) { HasReversedFunctionsWithBodies = false; } ~BitcodeReader() { @@ -180,17 +183,15 @@ public: void FreeState(); - /// releaseMemoryBuffer - This causes the reader to completely forget about - /// the memory buffer it contains, which prevents the buffer from being - /// destroyed when it is deleted. - void releaseMemoryBuffer() { - Buffer = 0; - } + /// setBufferOwned - If this is true, the reader will destroy the MemoryBuffer + /// when the reader is destroyed. + void setBufferOwned(bool Owned) { BufferOwned = Owned; } - virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0); - virtual Module *materializeModule(std::string *ErrInfo = 0); - virtual void dematerializeFunction(Function *F); - virtual Module *releaseModule(std::string *ErrInfo = 0); + virtual bool isMaterializable(const GlobalValue *GV) const; + virtual bool isDematerializable(const GlobalValue *GV) const; + virtual bool Materialize(GlobalValue *GV, std::string *ErrInfo = 0); + virtual bool MaterializeModule(Module *M, std::string *ErrInfo = 0); + virtual void Dematerialize(GlobalValue *GV); bool Error(const char *Str) { ErrorString = Str; @@ -200,7 +201,7 @@ public: /// @brief Main interface to parsing a bitcode buffer. /// @returns true if an error occurred. - bool ParseBitcode(); + bool ParseBitcodeInto(Module *M); private: const Type *getTypeByID(unsigned ID, bool isTypeTable = false); Value *getFnValueByID(unsigned ID, const Type *Ty) { @@ -248,7 +249,7 @@ private: } - bool ParseModule(const std::string &ModuleID); + bool ParseModule(); bool ParseAttributeBlock(); bool ParseTypeTable(); bool ParseTypeSymbolTable(); diff --git a/lib/Bitcode/Reader/Makefile b/lib/Bitcode/Reader/Makefile index 0aae3bf..59af8d53 100644 --- a/lib/Bitcode/Reader/Makefile +++ b/lib/Bitcode/Reader/Makefile @@ -10,7 +10,6 @@ LEVEL = ../../.. LIBRARYNAME = LLVMBitReader BUILD_ARCHIVE = 1 -CXXFLAGS = -fno-rtti include $(LEVEL)/Makefile.common diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 5a4a1b2..82e73b5 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -181,6 +181,14 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { Log2_32_Ceil(VE.getTypes().size()+1))); unsigned StructAbbrev = Stream.EmitAbbrev(Abbv); + // Abbrev for TYPE_CODE_UNION. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_UNION)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + Log2_32_Ceil(VE.getTypes().size()+1))); + unsigned UnionAbbrev = Stream.EmitAbbrev(Abbv); + // Abbrev for TYPE_CODE_ARRAY. Abbv = new BitCodeAbbrev(); Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY)); @@ -250,6 +258,17 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { AbbrevToUse = StructAbbrev; break; } + case Type::UnionTyID: { + const UnionType *UT = cast<UnionType>(T); + // UNION: [eltty x N] + Code = bitc::TYPE_CODE_UNION; + // Output all of the element types. + for (UnionType::element_iterator I = UT->element_begin(), + E = UT->element_end(); I != E; ++I) + TypeVals.push_back(VE.getTypeID(*I)); + AbbrevToUse = UnionAbbrev; + break; + } case Type::ArrayTyID: { const ArrayType *AT = cast<ArrayType>(T); // ARRAY: [numelts, eltty] @@ -280,7 +299,6 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { static unsigned getEncodedLinkage(const GlobalValue *GV) { switch (GV->getLinkage()) { default: llvm_unreachable("Invalid linkage!"); - case GlobalValue::GhostLinkage: // Map ghost linkage onto external. case GlobalValue::ExternalLinkage: return 0; case GlobalValue::WeakAnyLinkage: return 1; case GlobalValue::AppendingLinkage: return 2; @@ -499,7 +517,7 @@ static void WriteModuleMetadata(const ValueEnumerator &VE, for (unsigned i = 0, e = Vals.size(); i != e; ++i) { if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first)) { - if (!N->isFunctionLocal()) { + if (!N->isFunctionLocal() || !N->getFunction()) { if (!StartedMetadataBlock) { Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); StartedMetadataBlock = true; @@ -563,7 +581,7 @@ static void WriteFunctionLocalMetadata(const Function &F, for (unsigned i = 0, e = Vals.size(); i != e; ++i) if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first)) - if (N->getFunction() == &F) { + if (N->isFunctionLocal() && N->getFunction() == &F) { if (!StartedMetadataBlock) { Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); StartedMetadataBlock = true; @@ -790,7 +808,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, else if (isCStr7) AbbrevToUse = CString7Abbrev; } else if (isa<ConstantArray>(C) || isa<ConstantStruct>(V) || - isa<ConstantVector>(V)) { + isa<ConstantUnion>(C) || isa<ConstantVector>(V)) { Code = bitc::CST_CODE_AGGREGATE; for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) Record.push_back(VE.getValueID(C->getOperand(i))); @@ -1511,16 +1529,50 @@ enum { DarwinBCHeaderSize = 5*4 }; +/// isARMTriplet - Return true if the triplet looks like: +/// arm-*, thumb-*, armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*. +static bool isARMTriplet(const std::string &TT) { + size_t Pos = 0; + size_t Size = TT.size(); + if (Size >= 6 && + TT[0] == 't' && TT[1] == 'h' && TT[2] == 'u' && + TT[3] == 'm' && TT[4] == 'b') + Pos = 5; + else if (Size >= 4 && TT[0] == 'a' && TT[1] == 'r' && TT[2] == 'm') + Pos = 3; + else + return false; + + if (TT[Pos] == '-') + return true; + else if (TT[Pos] == 'v') { + if (Size >= Pos+4 && + TT[Pos+1] == '6' && TT[Pos+2] == 't' && TT[Pos+3] == '2') + return true; + else if (Size >= Pos+4 && + TT[Pos+1] == '5' && TT[Pos+2] == 't' && TT[Pos+3] == 'e') + return true; + } else + return false; + while (++Pos < Size && TT[Pos] != '-') { + if (!isdigit(TT[Pos])) + return false; + } + return true; +} + 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 + // Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*, arm-*, thumb-*, + // armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*. 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_ARM = 12, DARWIN_CPU_TYPE_POWERPC = 18 }; @@ -1533,6 +1585,8 @@ static void EmitDarwinBCHeader(BitstreamWriter &Stream, CPUType = DARWIN_CPU_TYPE_POWERPC; else if (TT.find("powerpc64-") == 0) CPUType = DARWIN_CPU_TYPE_POWERPC | DARWIN_CPU_ARCH_ABI64; + else if (isARMTriplet(TT)) + CPUType = DARWIN_CPU_TYPE_ARM; // Traditional Bitcode starts after header. unsigned BCOffset = DarwinBCHeaderSize; diff --git a/lib/Bitcode/Writer/Makefile b/lib/Bitcode/Writer/Makefile index 5f9742e..7b0bd72 100644 --- a/lib/Bitcode/Writer/Makefile +++ b/lib/Bitcode/Writer/Makefile @@ -10,7 +10,6 @@ LEVEL = ../../.. LIBRARYNAME = LLVMBitWriter BUILD_ARCHIVE = 1 -CXXFLAGS = -fno-rtti include $(LEVEL)/Makefile.common diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index c46d735..595497f 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -93,7 +93,7 @@ ValueEnumerator::ValueEnumerator(const Module *M) { for (User::const_op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI) { if (MDNode *MD = dyn_cast<MDNode>(*OI)) - if (MD->isFunctionLocal()) + if (MD->isFunctionLocal() && MD->getFunction()) // These will get enumerated during function-incorporation. continue; EnumerateOperandType(*OI); @@ -408,21 +408,25 @@ void ValueEnumerator::incorporateFunction(const Function &F) { FirstInstID = Values.size(); + SmallVector<MDNode *, 8> FunctionLocalMDs; // Add all of the instructions. for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) { for (User::const_op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI) { if (MDNode *MD = dyn_cast<MDNode>(*OI)) - if (!MD->isFunctionLocal()) - // These were already enumerated during ValueEnumerator creation. - continue; - EnumerateOperandType(*OI); + if (MD->isFunctionLocal() && MD->getFunction()) + // Enumerate metadata after the instructions they might refer to. + FunctionLocalMDs.push_back(MD); } if (!I->getType()->isVoidTy()) EnumerateValue(I); } } + + // Add all of the function-local metadata. + for (unsigned i = 0, e = FunctionLocalMDs.size(); i != e; ++i) + EnumerateOperandType(FunctionLocalMDs[i]); } void ValueEnumerator::purgeFunction() { |