From c6a4f5e819217e1e12c458aed8e7b122e23a3a58 Mon Sep 17 00:00:00 2001 From: Stephen Hines Date: Mon, 21 Jul 2014 00:45:20 -0700 Subject: Update LLVM for rebase to r212749. Includes a cherry-pick of: r212948 - fixes a small issue with atomic calls Change-Id: Ib97bd980b59f18142a69506400911a6009d9df18 --- lib/Bitcode/Reader/BitReader.cpp | 4 +- lib/Bitcode/Reader/BitcodeReader.cpp | 301 +++++++++++++++++---------------- lib/Bitcode/Reader/BitcodeReader.h | 90 +++++----- lib/Bitcode/Reader/BitstreamReader.cpp | 4 +- lib/Bitcode/Writer/BitcodeWriter.cpp | 43 ++++- lib/Bitcode/Writer/ValueEnumerator.cpp | 43 +++-- lib/Bitcode/Writer/ValueEnumerator.h | 9 + 7 files changed, 280 insertions(+), 214 deletions(-) (limited to 'lib/Bitcode') diff --git a/lib/Bitcode/Reader/BitReader.cpp b/lib/Bitcode/Reader/BitReader.cpp index 716299f..b5886c1 100644 --- a/lib/Bitcode/Reader/BitReader.cpp +++ b/lib/Bitcode/Reader/BitReader.cpp @@ -32,7 +32,7 @@ LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, char **OutMessage) { ErrorOr ModuleOrErr = parseBitcodeFile(unwrap(MemBuf), *unwrap(ContextRef)); - if (error_code EC = ModuleOrErr.getError()) { + if (std::error_code EC = ModuleOrErr.getError()) { if (OutMessage) *OutMessage = strdup(EC.message().c_str()); *OutModule = wrap((Module*)nullptr); @@ -54,7 +54,7 @@ LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, ErrorOr ModuleOrErr = getLazyBitcodeModule(unwrap(MemBuf), *unwrap(ContextRef)); - if (error_code EC = ModuleOrErr.getError()) { + if (std::error_code EC = ModuleOrErr.getError()) { *OutM = wrap((Module *)nullptr); if (OutMessage) *OutMessage = strdup(EC.message().c_str()); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 4170f98..192f753 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -39,12 +39,11 @@ void BitcodeReader::materializeForwardReferencedFunctions() { } void BitcodeReader::FreeState() { - if (BufferOwned) - delete Buffer; Buffer = nullptr; std::vector().swap(TypeList); ValueList.clear(); MDValueList.clear(); + std::vector().swap(ComdatList); std::vector().swap(MAttributes); std::vector().swap(FunctionBBs); @@ -205,6 +204,22 @@ static SynchronizationScope GetDecodedSynchScope(unsigned Val) { } } +static Comdat::SelectionKind getDecodedComdatSelectionKind(unsigned Val) { + switch (Val) { + default: // Map unknown selection kinds to any. + case bitc::COMDAT_SELECTION_KIND_ANY: + return Comdat::Any; + case bitc::COMDAT_SELECTION_KIND_EXACT_MATCH: + return Comdat::ExactMatch; + case bitc::COMDAT_SELECTION_KIND_LARGEST: + return Comdat::Largest; + case bitc::COMDAT_SELECTION_KIND_NO_DUPLICATES: + return Comdat::NoDuplicates; + case bitc::COMDAT_SELECTION_KIND_SAME_SIZE: + return Comdat::SameSize; + } +} + static void UpgradeDLLImportExportLinkage(llvm::GlobalValue *GV, unsigned Val) { switch (Val) { case 5: GV->setDLLStorageClass(GlobalValue::DLLImportStorageClass); break; @@ -470,7 +485,7 @@ static void decodeLLVMAttributesForBitcode(AttrBuilder &B, (EncodedAttrs & 0xffff)); } -error_code BitcodeReader::ParseAttributeBlock() { +std::error_code BitcodeReader::ParseAttributeBlock() { if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID)) return Error(InvalidRecord); @@ -490,7 +505,7 @@ error_code BitcodeReader::ParseAttributeBlock() { case BitstreamEntry::Error: return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return error_code::success(); + return std::error_code(); case BitstreamEntry::Record: // The interesting case. break; @@ -549,6 +564,8 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) { return Attribute::InlineHint; case bitc::ATTR_KIND_IN_REG: return Attribute::InReg; + case bitc::ATTR_KIND_JUMP_TABLE: + return Attribute::JumpTable; case bitc::ATTR_KIND_MIN_SIZE: return Attribute::MinSize; case bitc::ATTR_KIND_NAKED: @@ -614,15 +631,15 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) { } } -error_code BitcodeReader::ParseAttrKind(uint64_t Code, - Attribute::AttrKind *Kind) { +std::error_code BitcodeReader::ParseAttrKind(uint64_t Code, + Attribute::AttrKind *Kind) { *Kind = GetAttrFromCode(Code); if (*Kind == Attribute::None) return Error(InvalidValue); - return error_code::success(); + return std::error_code(); } -error_code BitcodeReader::ParseAttributeGroupBlock() { +std::error_code BitcodeReader::ParseAttributeGroupBlock() { if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) return Error(InvalidRecord); @@ -640,7 +657,7 @@ error_code BitcodeReader::ParseAttributeGroupBlock() { case BitstreamEntry::Error: return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return error_code::success(); + return std::error_code(); case BitstreamEntry::Record: // The interesting case. break; @@ -662,13 +679,13 @@ error_code BitcodeReader::ParseAttributeGroupBlock() { for (unsigned i = 2, e = Record.size(); i != e; ++i) { if (Record[i] == 0) { // Enum attribute Attribute::AttrKind Kind; - if (error_code EC = ParseAttrKind(Record[++i], &Kind)) + if (std::error_code EC = ParseAttrKind(Record[++i], &Kind)) return EC; B.addAttribute(Kind); } else if (Record[i] == 1) { // Align attribute Attribute::AttrKind Kind; - if (error_code EC = ParseAttrKind(Record[++i], &Kind)) + if (std::error_code EC = ParseAttrKind(Record[++i], &Kind)) return EC; if (Kind == Attribute::Alignment) B.addAlignmentAttr(Record[++i]); @@ -704,14 +721,14 @@ error_code BitcodeReader::ParseAttributeGroupBlock() { } } -error_code BitcodeReader::ParseTypeTable() { +std::error_code BitcodeReader::ParseTypeTable() { if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW)) return Error(InvalidRecord); return ParseTypeTableBody(); } -error_code BitcodeReader::ParseTypeTableBody() { +std::error_code BitcodeReader::ParseTypeTableBody() { if (!TypeList.empty()) return Error(InvalidMultipleBlocks); @@ -731,7 +748,7 @@ error_code BitcodeReader::ParseTypeTableBody() { case BitstreamEntry::EndBlock: if (NumRecords != TypeList.size()) return Error(MalformedBlock); - return error_code::success(); + return std::error_code(); case BitstreamEntry::Record: // The interesting case. break; @@ -931,7 +948,7 @@ error_code BitcodeReader::ParseTypeTableBody() { } } -error_code BitcodeReader::ParseValueSymbolTable() { +std::error_code BitcodeReader::ParseValueSymbolTable() { if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) return Error(InvalidRecord); @@ -947,7 +964,7 @@ error_code BitcodeReader::ParseValueSymbolTable() { case BitstreamEntry::Error: return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return error_code::success(); + return std::error_code(); case BitstreamEntry::Record: // The interesting case. break; @@ -985,7 +1002,7 @@ error_code BitcodeReader::ParseValueSymbolTable() { } } -error_code BitcodeReader::ParseMetadata() { +std::error_code BitcodeReader::ParseMetadata() { unsigned NextMDValueNo = MDValueList.size(); if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID)) @@ -1002,7 +1019,7 @@ error_code BitcodeReader::ParseMetadata() { case BitstreamEntry::Error: return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return error_code::success(); + return std::error_code(); case BitstreamEntry::Record: // The interesting case. break; @@ -1062,7 +1079,8 @@ error_code BitcodeReader::ParseMetadata() { break; } case bitc::METADATA_STRING: { - SmallString<8> String(Record.begin(), Record.end()); + std::string String(Record.begin(), Record.end()); + llvm::UpgradeMDStringConstant(String); Value *V = MDString::get(Context, String); MDValueList.AssignValue(V, NextMDValueNo++); break; @@ -1094,31 +1112,9 @@ uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) { return 1ULL << 63; } -// FIXME: Delete this in LLVM 4.0 and just assert that the aliasee is a -// GlobalObject. -static GlobalObject & -getGlobalObjectInExpr(const DenseMap &Map, - Constant &C) { - auto *GO = dyn_cast(&C); - if (GO) - return *GO; - - auto *GA = dyn_cast(&C); - if (GA) - return getGlobalObjectInExpr(Map, *Map.find(GA)->second); - - auto &CE = cast(C); - assert(CE.getOpcode() == Instruction::BitCast || - CE.getOpcode() == Instruction::GetElementPtr || - CE.getOpcode() == Instruction::AddrSpaceCast); - if (CE.getOpcode() == Instruction::GetElementPtr) - assert(cast(CE).hasAllZeroIndices()); - return getGlobalObjectInExpr(Map, *CE.getOperand(0)); -} - /// ResolveGlobalAndAliasInits - Resolve all of the initializers for global /// values and aliases that we can. -error_code BitcodeReader::ResolveGlobalAndAliasInits() { +std::error_code BitcodeReader::ResolveGlobalAndAliasInits() { std::vector > GlobalInitWorklist; std::vector > AliasInitWorklist; std::vector > FunctionPrefixWorklist; @@ -1141,30 +1137,19 @@ error_code BitcodeReader::ResolveGlobalAndAliasInits() { GlobalInitWorklist.pop_back(); } - // FIXME: Delete this in LLVM 4.0 - // Older versions of llvm could write an alias pointing to another. We cannot - // construct those aliases, so we first collect an alias to aliasee expression - // and then compute the actual aliasee. - DenseMap AliasInit; - while (!AliasInitWorklist.empty()) { unsigned ValID = AliasInitWorklist.back().second; if (ValID >= ValueList.size()) { AliasInits.push_back(AliasInitWorklist.back()); } else { if (Constant *C = dyn_cast_or_null(ValueList[ValID])) - AliasInit.insert(std::make_pair(AliasInitWorklist.back().first, C)); + AliasInitWorklist.back().first->setAliasee(C); else return Error(ExpectedConstant); } AliasInitWorklist.pop_back(); } - for (auto &Pair : AliasInit) { - auto &GO = getGlobalObjectInExpr(AliasInit, *Pair.second); - Pair.first->setAliasee(&GO); - } - while (!FunctionPrefixWorklist.empty()) { unsigned ValID = FunctionPrefixWorklist.back().second; if (ValID >= ValueList.size()) { @@ -1178,7 +1163,7 @@ error_code BitcodeReader::ResolveGlobalAndAliasInits() { FunctionPrefixWorklist.pop_back(); } - return error_code::success(); + return std::error_code(); } static APInt ReadWideAPInt(ArrayRef Vals, unsigned TypeBits) { @@ -1189,7 +1174,7 @@ static APInt ReadWideAPInt(ArrayRef Vals, unsigned TypeBits) { return APInt(TypeBits, Words); } -error_code BitcodeReader::ParseConstants() { +std::error_code BitcodeReader::ParseConstants() { if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID)) return Error(InvalidRecord); @@ -1212,7 +1197,7 @@ error_code BitcodeReader::ParseConstants() { // Once all the constants have been read, go through and resolve forward // references. ValueList.ResolveConstantForwardRefs(); - return error_code::success(); + return std::error_code(); case BitstreamEntry::Record: // The interesting case. break; @@ -1627,7 +1612,7 @@ error_code BitcodeReader::ParseConstants() { } } -error_code BitcodeReader::ParseUseLists() { +std::error_code BitcodeReader::ParseUseLists() { if (Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID)) return Error(InvalidRecord); @@ -1642,7 +1627,7 @@ error_code BitcodeReader::ParseUseLists() { case BitstreamEntry::Error: return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return error_code::success(); + return std::error_code(); case BitstreamEntry::Record: // The interesting case. break; @@ -1667,7 +1652,7 @@ error_code BitcodeReader::ParseUseLists() { /// RememberAndSkipFunctionBody - When we see the block for a function body, /// remember where it is and then skip it. This lets us lazily deserialize the /// functions. -error_code BitcodeReader::RememberAndSkipFunctionBody() { +std::error_code BitcodeReader::RememberAndSkipFunctionBody() { // Get the function we are talking about. if (FunctionsWithBodies.empty()) return Error(InsufficientFunctionProtos); @@ -1682,10 +1667,10 @@ error_code BitcodeReader::RememberAndSkipFunctionBody() { // Skip over the function block for now. if (Stream.SkipBlock()) return Error(InvalidRecord); - return error_code::success(); + return std::error_code(); } -error_code BitcodeReader::GlobalCleanup() { +std::error_code BitcodeReader::GlobalCleanup() { // Patch the initializers for globals and aliases up. ResolveGlobalAndAliasInits(); if (!GlobalInits.empty() || !AliasInits.empty()) @@ -1711,10 +1696,10 @@ error_code BitcodeReader::GlobalCleanup() { // want lazy deserialization. std::vector >().swap(GlobalInits); std::vector >().swap(AliasInits); - return error_code::success(); + return std::error_code(); } -error_code BitcodeReader::ParseModule(bool Resume) { +std::error_code BitcodeReader::ParseModule(bool Resume) { if (Resume) Stream.JumpToBit(NextUnreadBit); else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) @@ -1745,30 +1730,30 @@ error_code BitcodeReader::ParseModule(bool Resume) { return Error(MalformedBlock); break; case bitc::PARAMATTR_BLOCK_ID: - if (error_code EC = ParseAttributeBlock()) + if (std::error_code EC = ParseAttributeBlock()) return EC; break; case bitc::PARAMATTR_GROUP_BLOCK_ID: - if (error_code EC = ParseAttributeGroupBlock()) + if (std::error_code EC = ParseAttributeGroupBlock()) return EC; break; case bitc::TYPE_BLOCK_ID_NEW: - if (error_code EC = ParseTypeTable()) + if (std::error_code EC = ParseTypeTable()) return EC; break; case bitc::VALUE_SYMTAB_BLOCK_ID: - if (error_code EC = ParseValueSymbolTable()) + if (std::error_code EC = ParseValueSymbolTable()) return EC; SeenValueSymbolTable = true; break; case bitc::CONSTANTS_BLOCK_ID: - if (error_code EC = ParseConstants()) + if (std::error_code EC = ParseConstants()) return EC; - if (error_code EC = ResolveGlobalAndAliasInits()) + if (std::error_code EC = ResolveGlobalAndAliasInits()) return EC; break; case bitc::METADATA_BLOCK_ID: - if (error_code EC = ParseMetadata()) + if (std::error_code EC = ParseMetadata()) return EC; break; case bitc::FUNCTION_BLOCK_ID: @@ -1776,12 +1761,12 @@ error_code BitcodeReader::ParseModule(bool Resume) { // FunctionsWithBodies list. if (!SeenFirstFunctionBody) { std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end()); - if (error_code EC = GlobalCleanup()) + if (std::error_code EC = GlobalCleanup()) return EC; SeenFirstFunctionBody = true; } - if (error_code EC = RememberAndSkipFunctionBody()) + if (std::error_code EC = RememberAndSkipFunctionBody()) return EC; // For streaming bitcode, suspend parsing when we reach the function // bodies. Subsequent materialization calls will resume it when @@ -1791,11 +1776,11 @@ error_code BitcodeReader::ParseModule(bool Resume) { // just finish the parse now. if (LazyStreamer && SeenValueSymbolTable) { NextUnreadBit = Stream.GetCurrentBitNo(); - return error_code::success(); + return std::error_code(); } break; case bitc::USELIST_BLOCK_ID: - if (error_code EC = ParseUseLists()) + if (std::error_code EC = ParseUseLists()) return EC; break; } @@ -1870,6 +1855,20 @@ error_code BitcodeReader::ParseModule(bool Resume) { GCTable.push_back(S); break; } + case bitc::MODULE_CODE_COMDAT: { // COMDAT: [selection_kind, name] + if (Record.size() < 2) + return Error(InvalidRecord); + Comdat::SelectionKind SK = getDecodedComdatSelectionKind(Record[0]); + unsigned ComdatNameSize = Record[1]; + std::string ComdatName; + ComdatName.reserve(ComdatNameSize); + for (unsigned i = 0; i != ComdatNameSize; ++i) + ComdatName += (char)Record[2 + i]; + Comdat *C = TheModule->getOrInsertComdat(ComdatName); + C->setSelectionKind(SK); + ComdatList.push_back(C); + break; + } // GLOBALVAR: [pointer type, isconst, initid, // linkage, alignment, section, visibility, threadlocal, // unnamed_addr, dllstorageclass] @@ -1930,6 +1929,12 @@ error_code BitcodeReader::ParseModule(bool Resume) { // Remember which value to use for the global initializer. if (unsigned InitID = Record[2]) GlobalInits.push_back(std::make_pair(NewGV, InitID-1)); + + if (Record.size() > 11) + if (unsigned ComdatID = Record[11]) { + assert(ComdatID <= ComdatList.size()); + NewGV->setComdat(ComdatList[ComdatID - 1]); + } break; } // FUNCTION: [type, callingconv, isproto, linkage, paramattr, @@ -1983,6 +1988,12 @@ error_code BitcodeReader::ParseModule(bool Resume) { else UpgradeDLLImportExportLinkage(Func, Record[3]); + if (Record.size() > 12) + if (unsigned ComdatID = Record[12]) { + assert(ComdatID <= ComdatList.size()); + Func->setComdat(ComdatList[ComdatID - 1]); + } + ValueList.push_back(Func); // If this is a function with a body, remember the prototype we are @@ -2017,6 +2028,10 @@ error_code BitcodeReader::ParseModule(bool Resume) { NewGA->setDLLStorageClass(GetDecodedDLLStorageClass(Record[4])); else UpgradeDLLImportExportLinkage(NewGA, Record[2]); + if (Record.size() > 5) + NewGA->setThreadLocalMode(GetDecodedThreadLocalMode(Record[5])); + if (Record.size() > 6) + NewGA->setUnnamedAddr(Record[6]); ValueList.push_back(NewGA); AliasInits.push_back(std::make_pair(NewGA, Record[1])); break; @@ -2033,10 +2048,10 @@ error_code BitcodeReader::ParseModule(bool Resume) { } } -error_code BitcodeReader::ParseBitcodeInto(Module *M) { +std::error_code BitcodeReader::ParseBitcodeInto(Module *M) { TheModule = nullptr; - if (error_code EC = InitStream()) + if (std::error_code EC = InitStream()) return EC; // Sniff for the signature. @@ -2052,7 +2067,7 @@ error_code BitcodeReader::ParseBitcodeInto(Module *M) { // need to understand them all. while (1) { if (Stream.AtEndOfStream()) - return error_code::success(); + return std::error_code(); BitstreamEntry Entry = Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); @@ -2061,7 +2076,7 @@ error_code BitcodeReader::ParseBitcodeInto(Module *M) { case BitstreamEntry::Error: return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return error_code::success(); + return std::error_code(); case BitstreamEntry::SubBlock: switch (Entry.ID) { @@ -2074,10 +2089,10 @@ error_code BitcodeReader::ParseBitcodeInto(Module *M) { if (TheModule) return Error(InvalidMultipleBlocks); TheModule = M; - if (error_code EC = ParseModule(false)) + if (std::error_code EC = ParseModule(false)) return EC; if (LazyStreamer) - return error_code::success(); + return std::error_code(); break; default: if (Stream.SkipBlock()) @@ -2094,19 +2109,20 @@ error_code BitcodeReader::ParseBitcodeInto(Module *M) { if (Stream.getAbbrevIDWidth() == 2 && Entry.ID == 2 && Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a && Stream.AtEndOfStream()) - return error_code::success(); + return std::error_code(); return Error(InvalidRecord); } } } -error_code BitcodeReader::ParseModuleTriple(std::string &Triple) { +ErrorOr BitcodeReader::parseModuleTriple() { if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) return Error(InvalidRecord); SmallVector Record; + std::string Triple; // Read all the records for this module. while (1) { BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); @@ -2116,7 +2132,7 @@ error_code BitcodeReader::ParseModuleTriple(std::string &Triple) { case BitstreamEntry::Error: return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return error_code::success(); + return Triple; case BitstreamEntry::Record: // The interesting case. break; @@ -2135,10 +2151,11 @@ error_code BitcodeReader::ParseModuleTriple(std::string &Triple) { } Record.clear(); } + llvm_unreachable("Exit infinite loop"); } -error_code BitcodeReader::ParseTriple(std::string &Triple) { - if (error_code EC = InitStream()) +ErrorOr BitcodeReader::parseTriple() { + if (std::error_code EC = InitStream()) return EC; // Sniff for the signature. @@ -2159,11 +2176,11 @@ error_code BitcodeReader::ParseTriple(std::string &Triple) { case BitstreamEntry::Error: return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return error_code::success(); + return std::error_code(); case BitstreamEntry::SubBlock: if (Entry.ID == bitc::MODULE_BLOCK_ID) - return ParseModuleTriple(Triple); + return parseModuleTriple(); // Ignore other sub-blocks. if (Stream.SkipBlock()) @@ -2178,7 +2195,7 @@ error_code BitcodeReader::ParseTriple(std::string &Triple) { } /// ParseMetadataAttachment - Parse metadata attachments. -error_code BitcodeReader::ParseMetadataAttachment() { +std::error_code BitcodeReader::ParseMetadataAttachment() { if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) return Error(InvalidRecord); @@ -2191,7 +2208,7 @@ error_code BitcodeReader::ParseMetadataAttachment() { case BitstreamEntry::Error: return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return error_code::success(); + return std::error_code(); case BitstreamEntry::Record: // The interesting case. break; @@ -2225,7 +2242,7 @@ error_code BitcodeReader::ParseMetadataAttachment() { } /// ParseFunctionBody - Lazily parse the specified function body block. -error_code BitcodeReader::ParseFunctionBody(Function *F) { +std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID)) return Error(InvalidRecord); @@ -2261,20 +2278,20 @@ error_code BitcodeReader::ParseFunctionBody(Function *F) { return Error(InvalidRecord); break; case bitc::CONSTANTS_BLOCK_ID: - if (error_code EC = ParseConstants()) + if (std::error_code EC = ParseConstants()) return EC; NextValueNo = ValueList.size(); break; case bitc::VALUE_SYMTAB_BLOCK_ID: - if (error_code EC = ParseValueSymbolTable()) + if (std::error_code EC = ParseValueSymbolTable()) return EC; break; case bitc::METADATA_ATTACHMENT_ID: - if (error_code EC = ParseMetadataAttachment()) + if (std::error_code EC = ParseMetadataAttachment()) return EC; break; case bitc::METADATA_BLOCK_ID: - if (error_code EC = ParseMetadata()) + if (std::error_code EC = ParseMetadata()) return EC; break; } @@ -2857,7 +2874,7 @@ error_code BitcodeReader::ParseFunctionBody(Function *F) { assert((CT != LandingPadInst::Filter || isa(Val->getType())) && "Filter clause has invalid type!"); - LP->addClause(Val); + LP->addClause(cast(Val)); } I = LP; @@ -2950,7 +2967,7 @@ error_code BitcodeReader::ParseFunctionBody(Function *F) { } case bitc::FUNC_CODE_INST_CMPXCHG: { // CMPXCHG:[ptrty, ptr, cmp, new, vol, successordering, synchscope, - // failureordering] + // failureordering?, isweak?] unsigned OpNum = 0; Value *Ptr, *Cmp, *New; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || @@ -2958,7 +2975,7 @@ error_code BitcodeReader::ParseFunctionBody(Function *F) { cast(Ptr->getType())->getElementType(), Cmp) || popValue(Record, OpNum, NextValueNo, cast(Ptr->getType())->getElementType(), New) || - (OpNum + 3 != Record.size() && OpNum + 4 != Record.size())) + (Record.size() < OpNum + 3 || Record.size() > OpNum + 5)) return Error(InvalidRecord); AtomicOrdering SuccessOrdering = GetDecodedOrdering(Record[OpNum+1]); if (SuccessOrdering == NotAtomic || SuccessOrdering == Unordered) @@ -2975,6 +2992,17 @@ error_code BitcodeReader::ParseFunctionBody(Function *F) { I = new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering, FailureOrdering, SynchScope); cast(I)->setVolatile(Record[OpNum]); + + if (Record.size() < 8) { + // Before weak cmpxchgs existed, the instruction simply returned the + // value loaded from memory, so bitcode files from that era will be + // expecting the first component of a modern cmpxchg. + CurBB->getInstList().push_back(I); + I = ExtractValueInst::Create(I, 0); + } else { + cast(I)->setWeak(Record[OpNum+4]); + } + InstructionList.push_back(I); break; } @@ -3144,27 +3172,29 @@ OutOfRecordLoop: ValueList.shrinkTo(ModuleValueListSize); MDValueList.shrinkTo(ModuleMDValueListSize); std::vector().swap(FunctionBBs); - return error_code::success(); + return std::error_code(); } /// Find the function body in the bitcode stream -error_code BitcodeReader::FindFunctionInStream(Function *F, - DenseMap::iterator DeferredFunctionInfoIterator) { +std::error_code BitcodeReader::FindFunctionInStream( + Function *F, + DenseMap::iterator DeferredFunctionInfoIterator) { while (DeferredFunctionInfoIterator->second == 0) { if (Stream.AtEndOfStream()) return Error(CouldNotFindFunctionInStream); // ParseModule will parse the next body in the stream and set its // position in the DeferredFunctionInfo map. - if (error_code EC = ParseModule(true)) + if (std::error_code EC = ParseModule(true)) return EC; } - return error_code::success(); + return std::error_code(); } //===----------------------------------------------------------------------===// // GVMaterializer implementation //===----------------------------------------------------------------------===// +void BitcodeReader::releaseBuffer() { Buffer.release(); } bool BitcodeReader::isMaterializable(const GlobalValue *GV) const { if (const Function *F = dyn_cast(GV)) { @@ -3174,24 +3204,24 @@ bool BitcodeReader::isMaterializable(const GlobalValue *GV) const { return false; } -error_code BitcodeReader::Materialize(GlobalValue *GV) { +std::error_code BitcodeReader::Materialize(GlobalValue *GV) { Function *F = dyn_cast(GV); // If it's not a function or is already material, ignore the request. if (!F || !F->isMaterializable()) - return error_code::success(); + return std::error_code(); DenseMap::iterator DFII = DeferredFunctionInfo.find(F); assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); // If its position is recorded as 0, its body is somewhere in the stream // but we haven't seen it yet. if (DFII->second == 0 && LazyStreamer) - if (error_code EC = FindFunctionInStream(F, DFII)) + if (std::error_code EC = FindFunctionInStream(F, DFII)) return EC; // Move the bit stream to the saved position of the deferred function body. Stream.JumpToBit(DFII->second); - if (error_code EC = ParseFunctionBody(F)) + if (std::error_code EC = ParseFunctionBody(F)) return EC; // Upgrade any old intrinsic calls in the function. @@ -3206,7 +3236,7 @@ error_code BitcodeReader::Materialize(GlobalValue *GV) { } } - return error_code::success(); + return std::error_code(); } bool BitcodeReader::isDematerializable(const GlobalValue *GV) const { @@ -3228,8 +3258,7 @@ void BitcodeReader::Dematerialize(GlobalValue *GV) { F->deleteBody(); } - -error_code BitcodeReader::MaterializeModule(Module *M) { +std::error_code BitcodeReader::MaterializeModule(Module *M) { assert(M == TheModule && "Can only Materialize the Module this BitcodeReader is attached to."); // Iterate over the module, deserializing any functions that are still on @@ -3237,7 +3266,7 @@ error_code BitcodeReader::MaterializeModule(Module *M) { for (Module::iterator F = TheModule->begin(), E = TheModule->end(); F != E; ++F) { if (F->isMaterializable()) { - if (error_code EC = Materialize(F)) + if (std::error_code EC = Materialize(F)) return EC; } } @@ -3270,16 +3299,16 @@ error_code BitcodeReader::MaterializeModule(Module *M) { UpgradeInstWithTBAATag(InstsWithTBAATag[I]); UpgradeDebugInfo(*M); - return error_code::success(); + return std::error_code(); } -error_code BitcodeReader::InitStream() { +std::error_code BitcodeReader::InitStream() { if (LazyStreamer) return InitLazyStream(); return InitStreamFromBuffer(); } -error_code BitcodeReader::InitStreamFromBuffer() { +std::error_code BitcodeReader::InitStreamFromBuffer() { const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart(); const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); @@ -3299,10 +3328,10 @@ error_code BitcodeReader::InitStreamFromBuffer() { StreamFile.reset(new BitstreamReader(BufPtr, BufEnd)); Stream.init(*StreamFile); - return error_code::success(); + return std::error_code(); } -error_code BitcodeReader::InitLazyStream() { +std::error_code BitcodeReader::InitLazyStream() { // Check and strip off the bitcode wrapper; BitstreamReader expects never to // see it. StreamingMemoryObject *Bytes = new StreamingMemoryObject(LazyStreamer); @@ -3323,12 +3352,12 @@ error_code BitcodeReader::InitLazyStream() { Bytes->dropLeadingBytes(bitcodeStart - buf); Bytes->setKnownObjectSize(bitcodeEnd - bitcodeStart); } - return error_code::success(); + return std::error_code(); } namespace { -class BitcodeErrorCategoryType : public error_category { - const char *name() const override { +class BitcodeErrorCategoryType : public std::error_category { + const char *name() const LLVM_NOEXCEPT override { return "llvm.bitcode"; } std::string message(int IE) const override { @@ -3378,7 +3407,7 @@ class BitcodeErrorCategoryType : public error_category { }; } -const error_category &BitcodeReader::BitcodeErrorCategory() { +const std::error_category &BitcodeReader::BitcodeErrorCategory() { static BitcodeErrorCategoryType O; return O; } @@ -3394,12 +3423,11 @@ ErrorOr llvm::getLazyBitcodeModule(MemoryBuffer *Buffer, Module *M = new Module(Buffer->getBufferIdentifier(), Context); BitcodeReader *R = new BitcodeReader(Buffer, Context); M->setMaterializer(R); - if (error_code EC = R->ParseBitcodeInto(M)) { + if (std::error_code EC = R->ParseBitcodeInto(M)) { + R->releaseBuffer(); // Never take ownership on error. delete M; // Also deletes R. return EC; } - // Have the BitcodeReader dtor delete 'Buffer'. - R->setBufferOwned(true); R->materializeForwardReferencedFunctions(); @@ -3414,13 +3442,12 @@ Module *llvm::getStreamedBitcodeModule(const std::string &name, Module *M = new Module(name, Context); BitcodeReader *R = new BitcodeReader(streamer, Context); M->setMaterializer(R); - if (error_code EC = R->ParseBitcodeInto(M)) { + if (std::error_code EC = R->ParseBitcodeInto(M)) { if (ErrMsg) *ErrMsg = EC.message(); delete M; // Also deletes R. return nullptr; } - R->setBufferOwned(false); // no buffer to delete return M; } @@ -3430,13 +3457,8 @@ ErrorOr llvm::parseBitcodeFile(MemoryBuffer *Buffer, if (!ModuleOrErr) return ModuleOrErr; Module *M = ModuleOrErr.get(); - - // Don't let the BitcodeReader dtor delete 'Buffer', regardless of whether - // there was an error. - static_cast(M->getMaterializer())->setBufferOwned(false); - // Read in the entire module, and destroy the BitcodeReader. - if (error_code EC = M->materializeAllPermanently()) { + if (std::error_code EC = M->materializeAllPermanently(true)) { delete M; return EC; } @@ -3448,17 +3470,12 @@ ErrorOr llvm::parseBitcodeFile(MemoryBuffer *Buffer, } std::string llvm::getBitcodeTargetTriple(MemoryBuffer *Buffer, - LLVMContext& Context, - std::string *ErrMsg) { + LLVMContext &Context) { BitcodeReader *R = new BitcodeReader(Buffer, Context); - // Don't let the BitcodeReader dtor delete 'Buffer'. - R->setBufferOwned(false); - - std::string Triple(""); - if (error_code EC = R->ParseTriple(Triple)) - if (ErrMsg) - *ErrMsg = EC.message(); - + ErrorOr Triple = R->parseTriple(); + R->releaseBuffer(); delete R; - return Triple; + if (Triple.getError()) + return ""; + return Triple.get(); } diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 593d8f9..1d4869a 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -22,10 +22,11 @@ #include "llvm/IR/OperandTraits.h" #include "llvm/IR/Type.h" #include "llvm/IR/ValueHandle.h" -#include "llvm/Support/system_error.h" +#include #include namespace llvm { + class Comdat; class MemoryBuffer; class LLVMContext; @@ -125,8 +126,7 @@ public: class BitcodeReader : public GVMaterializer { LLVMContext &Context; Module *TheModule; - MemoryBuffer *Buffer; - bool BufferOwned; + std::unique_ptr Buffer; std::unique_ptr StreamFile; BitstreamCursor Stream; DataStreamer *LazyStreamer; @@ -136,6 +136,7 @@ class BitcodeReader : public GVMaterializer { std::vector TypeList; BitcodeReaderValueList ValueList; BitcodeReaderMDValueList MDValueList; + std::vector ComdatList; SmallVector InstructionList; SmallVector, 64> UseListRecords; @@ -193,7 +194,7 @@ class BitcodeReader : public GVMaterializer { /// not need this flag. bool UseRelativeIDs; - static const error_category &BitcodeErrorCategory(); + static const std::error_category &BitcodeErrorCategory(); public: enum ErrorType { @@ -219,47 +220,39 @@ public: InvalidValue // Invalid version, inst number, attr number, etc }; - error_code Error(ErrorType E) { - return error_code(E, BitcodeErrorCategory()); + std::error_code Error(ErrorType E) { + return std::error_code(E, BitcodeErrorCategory()); } explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C) - : Context(C), TheModule(nullptr), Buffer(buffer), BufferOwned(false), - LazyStreamer(nullptr), NextUnreadBit(0), SeenValueSymbolTable(false), - ValueList(C), MDValueList(C), - SeenFirstFunctionBody(false), UseRelativeIDs(false) { - } + : Context(C), TheModule(nullptr), Buffer(buffer), LazyStreamer(nullptr), + NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C), + MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false) {} explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C) - : Context(C), TheModule(nullptr), Buffer(nullptr), BufferOwned(false), - LazyStreamer(streamer), NextUnreadBit(0), SeenValueSymbolTable(false), - ValueList(C), MDValueList(C), - SeenFirstFunctionBody(false), UseRelativeIDs(false) { - } - ~BitcodeReader() { - FreeState(); - } + : Context(C), TheModule(nullptr), Buffer(nullptr), LazyStreamer(streamer), + NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C), + MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false) {} + ~BitcodeReader() { FreeState(); } void materializeForwardReferencedFunctions(); void FreeState(); - /// setBufferOwned - If this is true, the reader will destroy the MemoryBuffer - /// when the reader is destroyed. - void setBufferOwned(bool Owned) { BufferOwned = Owned; } + void releaseBuffer() override; bool isMaterializable(const GlobalValue *GV) const override; bool isDematerializable(const GlobalValue *GV) const override; - error_code Materialize(GlobalValue *GV) override; - error_code MaterializeModule(Module *M) override; + std::error_code Materialize(GlobalValue *GV) override; + std::error_code MaterializeModule(Module *M) override; void Dematerialize(GlobalValue *GV) override; /// @brief Main interface to parsing a bitcode buffer. /// @returns true if an error occurred. - error_code ParseBitcodeInto(Module *M); + std::error_code ParseBitcodeInto(Module *M); /// @brief Cheap mechanism to just extract module triple /// @returns true if an error occurred. - error_code ParseTriple(std::string &Triple); + ErrorOr parseTriple(); static uint64_t decodeSignRotatedValue(uint64_t V); @@ -346,28 +339,29 @@ private: return getFnValueByID(ValNo, Ty); } - error_code ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind); - error_code ParseModule(bool Resume); - error_code ParseAttributeBlock(); - error_code ParseAttributeGroupBlock(); - error_code ParseTypeTable(); - error_code ParseTypeTableBody(); - - error_code ParseValueSymbolTable(); - error_code ParseConstants(); - error_code RememberAndSkipFunctionBody(); - error_code ParseFunctionBody(Function *F); - error_code GlobalCleanup(); - error_code ResolveGlobalAndAliasInits(); - error_code ParseMetadata(); - error_code ParseMetadataAttachment(); - error_code ParseModuleTriple(std::string &Triple); - error_code ParseUseLists(); - error_code InitStream(); - error_code InitStreamFromBuffer(); - error_code InitLazyStream(); - error_code FindFunctionInStream(Function *F, - DenseMap::iterator DeferredFunctionInfoIterator); + std::error_code ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind); + std::error_code ParseModule(bool Resume); + std::error_code ParseAttributeBlock(); + std::error_code ParseAttributeGroupBlock(); + std::error_code ParseTypeTable(); + std::error_code ParseTypeTableBody(); + + std::error_code ParseValueSymbolTable(); + std::error_code ParseConstants(); + std::error_code RememberAndSkipFunctionBody(); + std::error_code ParseFunctionBody(Function *F); + std::error_code GlobalCleanup(); + std::error_code ResolveGlobalAndAliasInits(); + std::error_code ParseMetadata(); + std::error_code ParseMetadataAttachment(); + ErrorOr parseModuleTriple(); + std::error_code ParseUseLists(); + std::error_code InitStream(); + std::error_code InitStreamFromBuffer(); + std::error_code InitLazyStream(); + std::error_code FindFunctionInStream( + Function *F, + DenseMap::iterator DeferredFunctionInfoIterator); }; } // End llvm namespace diff --git a/lib/Bitcode/Reader/BitstreamReader.cpp b/lib/Bitcode/Reader/BitstreamReader.cpp index f31e1fa..72451ec 100644 --- a/lib/Bitcode/Reader/BitstreamReader.cpp +++ b/lib/Bitcode/Reader/BitstreamReader.cpp @@ -97,7 +97,7 @@ void BitstreamCursor::readAbbreviatedField(const BitCodeAbbrevOp &Op, switch (Op.getEncoding()) { case BitCodeAbbrevOp::Array: case BitCodeAbbrevOp::Blob: - assert(0 && "Should not reach here"); + llvm_unreachable("Should not reach here"); case BitCodeAbbrevOp::Fixed: Vals.push_back(Read((unsigned)Op.getEncodingData())); break; @@ -117,7 +117,7 @@ void BitstreamCursor::skipAbbreviatedField(const BitCodeAbbrevOp &Op) { switch (Op.getEncoding()) { case BitCodeAbbrevOp::Array: case BitCodeAbbrevOp::Blob: - assert(0 && "Should not reach here"); + llvm_unreachable("Should not reach here"); case BitCodeAbbrevOp::Fixed: (void)Read((unsigned)Op.getEncodingData()); break; diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index cc73b84..dd9282a 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -177,6 +177,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_INLINE_HINT; case Attribute::InReg: return bitc::ATTR_KIND_IN_REG; + case Attribute::JumpTable: + return bitc::ATTR_KIND_JUMP_TABLE; case Attribute::MinSize: return bitc::ATTR_KIND_MIN_SIZE; case Attribute::Naked: @@ -511,7 +513,7 @@ static unsigned getEncodedDLLStorageClass(const GlobalValue &GV) { llvm_unreachable("Invalid DLL storage class"); } -static unsigned getEncodedThreadLocalMode(const GlobalVariable &GV) { +static unsigned getEncodedThreadLocalMode(const GlobalValue &GV) { switch (GV.getThreadLocalMode()) { case GlobalVariable::NotThreadLocal: return 0; case GlobalVariable::GeneralDynamicTLSModel: return 1; @@ -522,6 +524,35 @@ static unsigned getEncodedThreadLocalMode(const GlobalVariable &GV) { llvm_unreachable("Invalid TLS model"); } +static unsigned getEncodedComdatSelectionKind(const Comdat &C) { + switch (C.getSelectionKind()) { + case Comdat::Any: + return bitc::COMDAT_SELECTION_KIND_ANY; + case Comdat::ExactMatch: + return bitc::COMDAT_SELECTION_KIND_EXACT_MATCH; + case Comdat::Largest: + return bitc::COMDAT_SELECTION_KIND_LARGEST; + case Comdat::NoDuplicates: + return bitc::COMDAT_SELECTION_KIND_NO_DUPLICATES; + case Comdat::SameSize: + return bitc::COMDAT_SELECTION_KIND_SAME_SIZE; + } + llvm_unreachable("Invalid selection kind"); +} + +static void writeComdats(const ValueEnumerator &VE, BitstreamWriter &Stream) { + SmallVector Vals; + for (const Comdat *C : VE.getComdats()) { + // COMDAT: [selection_kind, name] + Vals.push_back(getEncodedComdatSelectionKind(*C)); + Vals.push_back(C->getName().size()); + for (char Chr : C->getName()) + Vals.push_back((unsigned char)Chr); + Stream.EmitRecord(bitc::MODULE_CODE_COMDAT, Vals, /*AbbrevToUse=*/0); + Vals.clear(); + } +} + // Emit top-level description of module, including target triple, inline asm, // descriptors for global variables, and function prototype info. static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, @@ -623,12 +654,14 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, if (GV.isThreadLocal() || GV.getVisibility() != GlobalValue::DefaultVisibility || GV.hasUnnamedAddr() || GV.isExternallyInitialized() || - GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass) { + GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass || + GV.hasComdat()) { Vals.push_back(getEncodedVisibility(GV)); Vals.push_back(getEncodedThreadLocalMode(GV)); Vals.push_back(GV.hasUnnamedAddr()); Vals.push_back(GV.isExternallyInitialized()); Vals.push_back(getEncodedDLLStorageClass(GV)); + Vals.push_back(GV.hasComdat() ? VE.getComdatID(GV.getComdat()) : 0); } else { AbbrevToUse = SimpleGVarAbbrev; } @@ -654,6 +687,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, Vals.push_back(F.hasPrefixData() ? (VE.getValueID(F.getPrefixData()) + 1) : 0); Vals.push_back(getEncodedDLLStorageClass(F)); + Vals.push_back(F.hasComdat() ? VE.getComdatID(F.getComdat()) : 0); unsigned AbbrevToUse = 0; Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); @@ -668,6 +702,8 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, Vals.push_back(getEncodedLinkage(A)); Vals.push_back(getEncodedVisibility(A)); Vals.push_back(getEncodedDLLStorageClass(A)); + Vals.push_back(getEncodedThreadLocalMode(A)); + Vals.push_back(A.hasUnnamedAddr()); unsigned AbbrevToUse = 0; Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse); Vals.clear(); @@ -1445,6 +1481,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, cast(I).getSynchScope())); Vals.push_back(GetEncodedOrdering( cast(I).getFailureOrdering())); + Vals.push_back(cast(I).isWeak()); break; case Instruction::AtomicRMW: Code = bitc::FUNC_CODE_INST_ATOMICRMW; @@ -1910,6 +1947,8 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) { // Emit information describing all of the types in the module. WriteTypeTable(VE, Stream); + writeComdats(VE, Stream); + // Emit top-level description of module, including target triple, inline asm, // descriptors for global variables, and function prototype info. WriteModuleInfo(M, VE, Stream); diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index 8531e76..15f8034 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -73,37 +73,34 @@ ValueEnumerator::ValueEnumerator(const Module *M) { SmallVector, 8> MDs; // Enumerate types used by function bodies and argument lists. - for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) { - - for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); - I != E; ++I) - EnumerateType(I->getType()); - - 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(*OI)) + for (const Function &F : *M) { + for (const Argument &A : F.args()) + EnumerateType(A.getType()); + + for (const BasicBlock &BB : F) + for (const Instruction &I : BB) { + for (const Use &Op : I.operands()) { + if (MDNode *MD = dyn_cast(&Op)) if (MD->isFunctionLocal() && MD->getFunction()) // These will get enumerated during function-incorporation. continue; - EnumerateOperandType(*OI); + EnumerateOperandType(Op); } - EnumerateType(I->getType()); - if (const CallInst *CI = dyn_cast(I)) + EnumerateType(I.getType()); + if (const CallInst *CI = dyn_cast(&I)) EnumerateAttributes(CI->getAttributes()); - else if (const InvokeInst *II = dyn_cast(I)) + else if (const InvokeInst *II = dyn_cast(&I)) EnumerateAttributes(II->getAttributes()); // Enumerate metadata attached with this instruction. MDs.clear(); - I->getAllMetadataOtherThanDebugLoc(MDs); + I.getAllMetadataOtherThanDebugLoc(MDs); for (unsigned i = 0, e = MDs.size(); i != e; ++i) EnumerateMetadata(MDs[i].second); - if (!I->getDebugLoc().isUnknown()) { + if (!I.getDebugLoc().isUnknown()) { MDNode *Scope, *IA; - I->getDebugLoc().getScopeAndInlinedAt(Scope, IA, I->getContext()); + I.getDebugLoc().getScopeAndInlinedAt(Scope, IA, I.getContext()); if (Scope) EnumerateMetadata(Scope); if (IA) EnumerateMetadata(IA); } @@ -120,6 +117,12 @@ unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const { return I->second; } +unsigned ValueEnumerator::getComdatID(const Comdat *C) const { + unsigned ComdatID = Comdats.idFor(C); + assert(ComdatID && "Comdat not found!"); + return ComdatID; +} + void ValueEnumerator::setInstructionID(const Instruction *I) { InstructionMap[I] = InstructionCount++; } @@ -310,6 +313,10 @@ void ValueEnumerator::EnumerateValue(const Value *V) { return; } + if (auto *GO = dyn_cast(V)) + if (const Comdat *C = GO->getComdat()) + Comdats.insert(C); + // Enumerate the type of this value. EnumerateType(V->getType()); diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h index d1ca15f..1c9f38e 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.h +++ b/lib/Bitcode/Writer/ValueEnumerator.h @@ -16,6 +16,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/UniqueVector.h" #include "llvm/IR/Attributes.h" #include @@ -25,6 +26,7 @@ class Type; class Value; class Instruction; class BasicBlock; +class Comdat; class Function; class Module; class MDNode; @@ -48,6 +50,10 @@ private: typedef DenseMap ValueMapType; ValueMapType ValueMap; ValueList Values; + + typedef UniqueVector ComdatSetType; + ComdatSetType Comdats; + ValueList MDValues; SmallVector FunctionLocalMDs; ValueMapType MDValueMap; @@ -139,6 +145,9 @@ public: return AttributeGroups; } + const ComdatSetType &getComdats() const { return Comdats; } + unsigned getComdatID(const Comdat *C) const; + /// getGlobalBasicBlockID - This returns the function-specific ID for the /// specified basic block. This is relatively expensive information, so it /// should only be used by rare constructs such as address-of-label. -- cgit v1.1