diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
commit | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch) | |
tree | 599ab169a01f1c86eda9adc774edaedde2f2db5b /lib/Bitcode/Reader/BitcodeReader.cpp | |
parent | 1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff) |
Notes
Diffstat (limited to 'lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 1261 |
1 files changed, 919 insertions, 342 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index fe051e7a9125..29dc7f616392 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1,9 +1,8 @@ //===- BitcodeReader.cpp - Internal BitcodeReader implementation ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -21,7 +20,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" -#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Bitstream/BitstreamReader.h" #include "llvm/Bitcode/LLVMBitCodes.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/Argument.h" @@ -106,18 +105,25 @@ static Error error(const Twine &Message) { Message, make_error_code(BitcodeError::CorruptedBitcode)); } -/// Helper to read the header common to all bitcode files. -static bool hasValidBitcodeHeader(BitstreamCursor &Stream) { - // Sniff for the signature. - if (!Stream.canSkipToPos(4) || - Stream.Read(8) != 'B' || - Stream.Read(8) != 'C' || - Stream.Read(4) != 0x0 || - Stream.Read(4) != 0xC || - Stream.Read(4) != 0xE || - Stream.Read(4) != 0xD) - return false; - return true; +static Error hasInvalidBitcodeHeader(BitstreamCursor &Stream) { + if (!Stream.canSkipToPos(4)) + return createStringError(std::errc::illegal_byte_sequence, + "file too small to contain bitcode header"); + for (unsigned C : {'B', 'C'}) + if (Expected<SimpleBitstreamCursor::word_t> Res = Stream.Read(8)) { + if (Res.get() != C) + return createStringError(std::errc::illegal_byte_sequence, + "file doesn't start with bitcode header"); + } else + return Res.takeError(); + for (unsigned C : {0x0, 0xC, 0xE, 0xD}) + if (Expected<SimpleBitstreamCursor::word_t> Res = Stream.Read(4)) { + if (Res.get() != C) + return createStringError(std::errc::illegal_byte_sequence, + "file doesn't start with bitcode header"); + } else + return Res.takeError(); + return Error::success(); } static Expected<BitstreamCursor> initStream(MemoryBufferRef Buffer) { @@ -134,8 +140,8 @@ static Expected<BitstreamCursor> initStream(MemoryBufferRef Buffer) { return error("Invalid bitcode wrapper header"); BitstreamCursor Stream(ArrayRef<uint8_t>(BufPtr, BufEnd)); - if (!hasValidBitcodeHeader(Stream)) - return error("Invalid bitcode signature"); + if (Error Err = hasInvalidBitcodeHeader(Stream)) + return std::move(Err); return std::move(Stream); } @@ -165,8 +171,8 @@ static void stripTBAA(Module *M) { /// Read the "IDENTIFICATION_BLOCK_ID" block, do some basic enforcement on the /// "epoch" encoded in the bitcode, and return the producer name if any. static Expected<std::string> readIdentificationBlock(BitstreamCursor &Stream) { - if (Stream.EnterSubBlock(bitc::IDENTIFICATION_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::IDENTIFICATION_BLOCK_ID)) + return std::move(Err); // Read all the records. SmallVector<uint64_t, 64> Record; @@ -174,7 +180,11 @@ static Expected<std::string> readIdentificationBlock(BitstreamCursor &Stream) { std::string ProducerIdentification; while (true) { - BitstreamEntry Entry = Stream.advance(); + BitstreamEntry Entry; + if (Expected<BitstreamEntry> Res = Stream.advance()) + Entry = Res.get(); + else + return Res.takeError(); switch (Entry.Kind) { default: @@ -189,8 +199,10 @@ static Expected<std::string> readIdentificationBlock(BitstreamCursor &Stream) { // Read a record. Record.clear(); - unsigned BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (MaybeBitCode.get()) { default: // Default behavior: reject return error("Invalid value"); case bitc::IDENTIFICATION_CODE_STRING: // IDENTIFICATION: [strchr x N] @@ -215,7 +227,12 @@ static Expected<std::string> readIdentificationCode(BitstreamCursor &Stream) { if (Stream.AtEndOfStream()) return ""; - BitstreamEntry Entry = Stream.advance(); + BitstreamEntry Entry; + if (Expected<BitstreamEntry> Res = Stream.advance()) + Entry = std::move(Res.get()); + else + return Res.takeError(); + switch (Entry.Kind) { case BitstreamEntry::EndBlock: case BitstreamEntry::Error: @@ -226,25 +243,30 @@ static Expected<std::string> readIdentificationCode(BitstreamCursor &Stream) { return readIdentificationBlock(Stream); // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); continue; case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; + if (Expected<unsigned> Skipped = Stream.skipRecord(Entry.ID)) + continue; + else + return Skipped.takeError(); } } } static Expected<bool> hasObjCCategoryInModule(BitstreamCursor &Stream) { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return std::move(Err); SmallVector<uint64_t, 64> Record; // Read all the records for this module. while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -258,7 +280,10 @@ static Expected<bool> hasObjCCategoryInModule(BitstreamCursor &Stream) { } // Read a record. - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N] @@ -281,7 +306,11 @@ static Expected<bool> hasObjCCategory(BitstreamCursor &Stream) { // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. while (true) { - BitstreamEntry Entry = Stream.advance(); + BitstreamEntry Entry; + if (Expected<BitstreamEntry> Res = Stream.advance()) + Entry = std::move(Res.get()); + else + return Res.takeError(); switch (Entry.Kind) { case BitstreamEntry::Error: @@ -294,20 +323,22 @@ static Expected<bool> hasObjCCategory(BitstreamCursor &Stream) { return hasObjCCategoryInModule(Stream); // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); continue; case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; + if (Expected<unsigned> Skipped = Stream.skipRecord(Entry.ID)) + continue; + else + return Skipped.takeError(); } } } static Expected<std::string> readModuleTriple(BitstreamCursor &Stream) { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return std::move(Err); SmallVector<uint64_t, 64> Record; @@ -315,7 +346,10 @@ static Expected<std::string> readModuleTriple(BitstreamCursor &Stream) { // Read all the records for this module. while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -329,7 +363,10 @@ static Expected<std::string> readModuleTriple(BitstreamCursor &Stream) { } // Read a record. - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] std::string S; @@ -348,7 +385,10 @@ static Expected<std::string> readTriple(BitstreamCursor &Stream) { // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::Error: @@ -361,13 +401,15 @@ static Expected<std::string> readTriple(BitstreamCursor &Stream) { return readModuleTriple(Stream); // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); continue; case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; + if (llvm::Expected<unsigned> Skipped = Stream.skipRecord(Entry.ID)) + continue; + else + return Skipped.takeError(); } } } @@ -452,6 +494,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { std::vector<std::string> GCTable; std::vector<Type*> TypeList; + DenseMap<Function *, FunctionType *> FunctionTypes; BitcodeReaderValueList ValueList; Optional<MetadataLoader> MDLoader; std::vector<Comdat *> ComdatList; @@ -550,12 +593,42 @@ private: StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name); StructType *createIdentifiedStructType(LLVMContext &Context); - Type *getTypeByID(unsigned ID); + /// Map all pointer types within \param Ty to the opaque pointer + /// type in the same address space if opaque pointers are being + /// used, otherwise nop. This converts a bitcode-reader internal + /// type into one suitable for use in a Value. + Type *flattenPointerTypes(Type *Ty) { + return Ty; + } + + /// Given a fully structured pointer type (i.e. not opaque), return + /// the flattened form of its element, suitable for use in a Value. + Type *getPointerElementFlatType(Type *Ty) { + return flattenPointerTypes(cast<PointerType>(Ty)->getElementType()); + } + + /// Given a fully structured pointer type, get its element type in + /// both fully structured form, and flattened form suitable for use + /// in a Value. + std::pair<Type *, Type *> getPointerElementTypes(Type *FullTy) { + Type *ElTy = cast<PointerType>(FullTy)->getElementType(); + return std::make_pair(ElTy, flattenPointerTypes(ElTy)); + } - Value *getFnValueByID(unsigned ID, Type *Ty) { + /// Return the flattened type (suitable for use in a Value) + /// specified by the given \param ID . + Type *getTypeByID(unsigned ID) { + return flattenPointerTypes(getFullyStructuredTypeByID(ID)); + } + + /// Return the fully structured (bitcode-reader internal) type + /// corresponding to the given \param ID . + Type *getFullyStructuredTypeByID(unsigned ID); + + Value *getFnValueByID(unsigned ID, Type *Ty, Type **FullTy = nullptr) { if (Ty && Ty->isMetadataTy()) return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID)); - return ValueList.getValueFwdRef(ID, Ty); + return ValueList.getValueFwdRef(ID, Ty, FullTy); } Metadata *getFnMetadataByID(unsigned ID) { @@ -577,7 +650,8 @@ private: /// Increment Slot past the number of slots used in the record. Return true on /// failure. bool getValueTypePair(SmallVectorImpl<uint64_t> &Record, unsigned &Slot, - unsigned InstNum, Value *&ResVal) { + unsigned InstNum, Value *&ResVal, + Type **FullTy = nullptr) { if (Slot == Record.size()) return true; unsigned ValNo = (unsigned)Record[Slot++]; // Adjust the ValNo, if it was encoded relative to the InstNum. @@ -586,7 +660,7 @@ private: if (ValNo < InstNum) { // If this is not a forward reference, just return the value we already // have. - ResVal = getFnValueByID(ValNo, nullptr); + ResVal = getFnValueByID(ValNo, nullptr, FullTy); return ResVal == nullptr; } if (Slot == Record.size()) @@ -594,6 +668,8 @@ private: unsigned TypeNo = (unsigned)Record[Slot++]; ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo)); + if (FullTy) + *FullTy = getFullyStructuredTypeByID(TypeNo); return ResVal == nullptr; } @@ -639,6 +715,10 @@ private: return getFnValueByID(ValNo, Ty); } + /// Upgrades old-style typeless byval attributes by adding the corresponding + /// argument's pointee type. + void propagateByValTypes(CallBase *CB, ArrayRef<Type *> ArgsFullTys); + /// Converts alignment exponent (i.e. power of two (or zero)) to the /// corresponding alignment to use. If alignment is too large, returns /// a corresponding error code. @@ -748,6 +828,9 @@ private: bool HasRelBF); Error parseEntireSummary(unsigned ID); Error parseModuleStringTable(); + void parseTypeIdCompatibleVtableSummaryRecord(ArrayRef<uint64_t> Record); + void parseTypeIdCompatibleVtableInfo(ArrayRef<uint64_t> Record, size_t &Slot, + TypeIdCompatibleVtableInfo &TypeId); std::pair<ValueInfo, GlobalValue::GUID> getValueInfoFromValueId(unsigned ValueId); @@ -775,7 +858,7 @@ BitcodeReader::BitcodeReader(BitstreamCursor Stream, StringRef Strtab, StringRef ProducerIdentification, LLVMContext &Context) : BitcodeReaderBase(std::move(Stream), Strtab), Context(Context), - ValueList(Context) { + ValueList(Context, Stream.SizeInBytes()) { this->ProducerIdentification = ProducerIdentification; } @@ -894,13 +977,15 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags, // values as live. bool Live = (RawFlags & 0x2) || Version < 3; bool Local = (RawFlags & 0x4); + bool AutoHide = (RawFlags & 0x8); - return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, Live, Local); + return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, Live, Local, AutoHide); } // Decode the flags for GlobalVariable in the summary static GlobalVarSummary::GVarFlags getDecodedGVarFlags(uint64_t RawFlags) { - return GlobalVarSummary::GVarFlags((RawFlags & 0x1) ? true : false); + return GlobalVarSummary::GVarFlags((RawFlags & 0x1) ? true : false, + (RawFlags & 0x2) ? true : false); } static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) { @@ -1035,6 +1120,8 @@ static AtomicRMWInst::BinOp getDecodedRMWOperation(unsigned Val) { case bitc::RMW_MIN: return AtomicRMWInst::Min; case bitc::RMW_UMAX: return AtomicRMWInst::UMax; case bitc::RMW_UMIN: return AtomicRMWInst::UMin; + case bitc::RMW_FADD: return AtomicRMWInst::FAdd; + case bitc::RMW_FSUB: return AtomicRMWInst::FSub; } } @@ -1095,7 +1182,7 @@ static void upgradeDLLImportExportLinkage(GlobalValue *GV, unsigned Val) { } } -Type *BitcodeReader::getTypeByID(unsigned ID) { +Type *BitcodeReader::getFullyStructuredTypeByID(unsigned ID) { // The type table size is always specified correctly. if (ID >= TypeList.size()) return nullptr; @@ -1187,6 +1274,15 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) { case Attribute::ShadowCallStack: return 1ULL << 59; case Attribute::SpeculativeLoadHardening: return 1ULL << 60; + case Attribute::ImmArg: + return 1ULL << 61; + case Attribute::WillReturn: + return 1ULL << 62; + case Attribute::NoFree: + return 1ULL << 63; + case Attribute::NoSync: + llvm_unreachable("nosync attribute not supported in raw format"); + break; case Attribute::Dereferenceable: llvm_unreachable("dereferenceable attribute not supported in raw format"); break; @@ -1200,6 +1296,9 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) { case Attribute::AllocSize: llvm_unreachable("allocsize not supported in raw format"); break; + case Attribute::SanitizeMemTag: + llvm_unreachable("sanitize_memtag attribute not supported in raw format"); + break; } llvm_unreachable("Unsupported attribute type"); } @@ -1209,10 +1308,12 @@ static void addRawAttributeValue(AttrBuilder &B, uint64_t Val) { for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; I = Attribute::AttrKind(I + 1)) { - if (I == Attribute::Dereferenceable || + if (I == Attribute::SanitizeMemTag || + I == Attribute::Dereferenceable || I == Attribute::DereferenceableOrNull || I == Attribute::ArgMemOnly || - I == Attribute::AllocSize) + I == Attribute::AllocSize || + I == Attribute::NoSync) continue; if (uint64_t A = (Val & getRawAttributeMask(I))) { if (I == Attribute::Alignment) @@ -1245,8 +1346,8 @@ static void decodeLLVMAttributesForBitcode(AttrBuilder &B, } Error BitcodeReader::parseAttributeBlock() { - if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID)) + return Err; if (!MAttributes.empty()) return error("Invalid multiple blocks"); @@ -1257,7 +1358,10 @@ Error BitcodeReader::parseAttributeBlock() { // Read all the records. while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -1272,7 +1376,10 @@ Error BitcodeReader::parseAttributeBlock() { // Read a record. Record.clear(); - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: ignore. break; case bitc::PARAMATTR_CODE_ENTRY_OLD: // ENTRY: [paramidx0, attr0, ...] @@ -1345,6 +1452,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::NoCapture; case bitc::ATTR_KIND_NO_DUPLICATE: return Attribute::NoDuplicate; + case bitc::ATTR_KIND_NOFREE: + return Attribute::NoFree; case bitc::ATTR_KIND_NO_IMPLICIT_FLOAT: return Attribute::NoImplicitFloat; case bitc::ATTR_KIND_NO_INLINE: @@ -1365,6 +1474,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::NoRedZone; case bitc::ATTR_KIND_NO_RETURN: return Attribute::NoReturn; + case bitc::ATTR_KIND_NOSYNC: + return Attribute::NoSync; case bitc::ATTR_KIND_NOCF_CHECK: return Attribute::NoCfCheck; case bitc::ATTR_KIND_NO_UNWIND: @@ -1419,10 +1530,16 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::SwiftSelf; case bitc::ATTR_KIND_UW_TABLE: return Attribute::UWTable; + case bitc::ATTR_KIND_WILLRETURN: + return Attribute::WillReturn; case bitc::ATTR_KIND_WRITEONLY: return Attribute::WriteOnly; case bitc::ATTR_KIND_Z_EXT: return Attribute::ZExt; + case bitc::ATTR_KIND_IMMARG: + return Attribute::ImmArg; + case bitc::ATTR_KIND_SANITIZE_MEMTAG: + return Attribute::SanitizeMemTag; } } @@ -1444,8 +1561,8 @@ Error BitcodeReader::parseAttrKind(uint64_t Code, Attribute::AttrKind *Kind) { } Error BitcodeReader::parseAttributeGroupBlock() { - if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) + return Err; if (!MAttributeGroups.empty()) return error("Invalid multiple blocks"); @@ -1454,7 +1571,10 @@ Error BitcodeReader::parseAttributeGroupBlock() { // Read all the records. while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -1469,7 +1589,10 @@ Error BitcodeReader::parseAttributeGroupBlock() { // Read a record. Record.clear(); - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: ignore. break; case bitc::PARAMATTR_GRP_CODE_ENTRY: { // ENTRY: [grpid, idx, a0, a1, ...] @@ -1486,6 +1609,12 @@ Error BitcodeReader::parseAttributeGroupBlock() { if (Error Err = parseAttrKind(Record[++i], &Kind)) return Err; + // Upgrade old-style byval attribute to one with a type, even if it's + // nullptr. We will have to insert the real type when we associate + // this AttributeList with a function. + if (Kind == Attribute::ByVal) + B.addByValAttr(nullptr); + B.addAttribute(Kind); } else if (Record[i] == 1) { // Integer attribute Attribute::AttrKind Kind; @@ -1501,9 +1630,7 @@ Error BitcodeReader::parseAttributeGroupBlock() { B.addDereferenceableOrNullAttr(Record[++i]); else if (Kind == Attribute::AllocSize) B.addAllocSizeAttrFromRawRepr(Record[++i]); - } else { // String attribute - assert((Record[i] == 3 || Record[i] == 4) && - "Invalid attribute group entry"); + } else if (Record[i] == 3 || Record[i] == 4) { // String attribute bool HasValue = (Record[i++] == 4); SmallString<64> KindStr; SmallString<64> ValStr; @@ -1521,6 +1648,15 @@ Error BitcodeReader::parseAttributeGroupBlock() { } B.addAttribute(KindStr.str(), ValStr.str()); + } else { + assert((Record[i] == 5 || Record[i] == 6) && + "Invalid attribute group entry"); + bool HasType = Record[i] == 6; + Attribute::AttrKind Kind; + if (Error Err = parseAttrKind(Record[++i], &Kind)) + return Err; + if (Kind == Attribute::ByVal) + B.addByValAttr(HasType ? getTypeByID(Record[++i]) : nullptr); } } @@ -1532,8 +1668,8 @@ Error BitcodeReader::parseAttributeGroupBlock() { } Error BitcodeReader::parseTypeTable() { - if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW)) + return Err; return parseTypeTableBody(); } @@ -1549,7 +1685,10 @@ Error BitcodeReader::parseTypeTableBody() { // Read all the records for this type table. while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -1567,7 +1706,10 @@ Error BitcodeReader::parseTypeTableBody() { // Read a record. Record.clear(); Type *ResultTy = nullptr; - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: return error("Invalid value"); case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries] @@ -1752,7 +1894,8 @@ Error BitcodeReader::parseTypeTableBody() { return error("Invalid type"); ResultTy = ArrayType::get(ResultTy, Record[0]); break; - case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] + case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] or + // [numelts, eltty, scalable] if (Record.size() < 2) return error("Invalid record"); if (Record[0] == 0) @@ -1760,7 +1903,8 @@ Error BitcodeReader::parseTypeTableBody() { ResultTy = getTypeByID(Record[1]); if (!ResultTy || !StructType::isValidElementType(ResultTy)) return error("Invalid type"); - ResultTy = VectorType::get(ResultTy, Record[0]); + bool Scalable = Record.size() > 2 ? Record[2] : false; + ResultTy = VectorType::get(ResultTy, Record[0], Scalable); break; } @@ -1775,8 +1919,8 @@ Error BitcodeReader::parseTypeTableBody() { } Error BitcodeReader::parseOperandBundleTags() { - if (Stream.EnterSubBlock(bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID)) + return Err; if (!BundleTags.empty()) return error("Invalid multiple blocks"); @@ -1784,7 +1928,10 @@ Error BitcodeReader::parseOperandBundleTags() { SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -1799,7 +1946,10 @@ Error BitcodeReader::parseOperandBundleTags() { // Tags are implicitly mapped to integers by their order. - if (Stream.readRecord(Entry.ID, Record) != bitc::OPERAND_BUNDLE_TAG) + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + if (MaybeRecord.get() != bitc::OPERAND_BUNDLE_TAG) return error("Invalid record"); // OPERAND_BUNDLE_TAG: [strchr x N] @@ -1811,15 +1961,19 @@ Error BitcodeReader::parseOperandBundleTags() { } Error BitcodeReader::parseSyncScopeNames() { - if (Stream.EnterSubBlock(bitc::SYNC_SCOPE_NAMES_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::SYNC_SCOPE_NAMES_BLOCK_ID)) + return Err; if (!SSIDs.empty()) return error("Invalid multiple synchronization scope names blocks"); SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); + switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: @@ -1836,7 +1990,10 @@ Error BitcodeReader::parseSyncScopeNames() { // Synchronization scope names are implicitly mapped to synchronization // scope IDs by their order. - if (Stream.readRecord(Entry.ID, Record) != bitc::SYNC_SCOPE_NAME) + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + if (MaybeRecord.get() != bitc::SYNC_SCOPE_NAME) return error("Invalid record"); SmallString<16> SSN; @@ -1877,22 +2034,18 @@ Expected<Value *> BitcodeReader::recordValue(SmallVectorImpl<uint64_t> &Record, /// Helper to note and return the current location, and jump to the given /// offset. -static uint64_t jumpToValueSymbolTable(uint64_t Offset, - BitstreamCursor &Stream) { +static Expected<uint64_t> jumpToValueSymbolTable(uint64_t Offset, + BitstreamCursor &Stream) { // Save the current parsing location so we can jump back at the end // of the VST read. uint64_t CurrentBit = Stream.GetCurrentBitNo(); - Stream.JumpToBit(Offset * 32); -#ifndef NDEBUG - // Do some checking if we are in debug mode. - BitstreamEntry Entry = Stream.advance(); - assert(Entry.Kind == BitstreamEntry::SubBlock); - assert(Entry.ID == bitc::VALUE_SYMTAB_BLOCK_ID); -#else - // In NDEBUG mode ignore the output so we don't get an unused variable - // warning. - Stream.advance(); -#endif + if (Error JumpFailed = Stream.JumpToBit(Offset * 32)) + return std::move(JumpFailed); + Expected<BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + assert(MaybeEntry.get().Kind == BitstreamEntry::SubBlock); + assert(MaybeEntry.get().ID == bitc::VALUE_SYMTAB_BLOCK_ID); return CurrentBit; } @@ -1917,12 +2070,15 @@ Error BitcodeReader::parseGlobalValueSymbolTable() { unsigned FuncBitcodeOffsetDelta = Stream.getAbbrevIDWidth() + bitc::BlockIDWidth; - if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: @@ -1935,7 +2091,10 @@ Error BitcodeReader::parseGlobalValueSymbolTable() { } Record.clear(); - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { case bitc::VST_CODE_FNENTRY: // [valueid, offset] setDeferredFunctionInfo(FuncBitcodeOffsetDelta, cast<Function>(ValueList[Record[0]]), Record); @@ -1952,12 +2111,16 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { // VST (where we want to jump to the VST offset) and the function-level // VST (where we don't). if (Offset > 0) { - CurrentBit = jumpToValueSymbolTable(Offset, Stream); + Expected<uint64_t> MaybeCurrentBit = jumpToValueSymbolTable(Offset, Stream); + if (!MaybeCurrentBit) + return MaybeCurrentBit.takeError(); + CurrentBit = MaybeCurrentBit.get(); // If this module uses a string table, read this as a module-level VST. if (UseStrtab) { if (Error Err = parseGlobalValueSymbolTable()) return Err; - Stream.JumpToBit(CurrentBit); + if (Error JumpFailed = Stream.JumpToBit(CurrentBit)) + return JumpFailed; return Error::success(); } // Otherwise, the VST will be in a similar format to a function-level VST, @@ -1978,8 +2141,8 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { unsigned FuncBitcodeOffsetDelta = Stream.getAbbrevIDWidth() + bitc::BlockIDWidth; - if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; @@ -1989,7 +2152,10 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { SmallString<128> ValueName; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -1997,7 +2163,8 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { return error("Malformed block"); case BitstreamEntry::EndBlock: if (Offset > 0) - Stream.JumpToBit(CurrentBit); + if (Error JumpFailed = Stream.JumpToBit(CurrentBit)) + return JumpFailed; return Error::success(); case BitstreamEntry::Record: // The interesting case. @@ -2006,7 +2173,10 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { // Read a record. Record.clear(); - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: unknown type. break; case bitc::VST_CODE_ENTRY: { // VST_CODE_ENTRY: [valueid, namechar x N] @@ -2151,17 +2321,21 @@ static APInt readWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) { } Error BitcodeReader::parseConstants() { - if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; // Read all the records for this value table. Type *CurTy = Type::getInt32Ty(Context); + Type *CurFullTy = Type::getInt32Ty(Context); unsigned NextCstNo = ValueList.size(); while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -2184,8 +2358,10 @@ Error BitcodeReader::parseConstants() { Record.clear(); Type *VoidType = Type::getVoidTy(Context); Value *V = nullptr; - unsigned BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (unsigned BitCode = MaybeBitCode.get()) { default: // Default behavior: unknown constant case bitc::CST_CODE_UNDEF: // UNDEF V = UndefValue::get(CurTy); @@ -2197,7 +2373,8 @@ Error BitcodeReader::parseConstants() { return error("Invalid record"); if (TypeList[Record[0]] == VoidType) return error("Invalid constant type"); - CurTy = TypeList[Record[0]]; + CurFullTy = TypeList[Record[0]]; + CurTy = flattenPointerTypes(CurFullTy); continue; // Skip the ValueList manipulation. case bitc::CST_CODE_NULL: // NULL V = Constant::getNullValue(CurTy); @@ -2416,23 +2593,27 @@ Error BitcodeReader::parseConstants() { InBounds = true; SmallVector<Constant*, 16> Elts; + Type *Elt0FullTy = nullptr; while (OpNum != Record.size()) { + if (!Elt0FullTy) + Elt0FullTy = getFullyStructuredTypeByID(Record[OpNum]); Type *ElTy = getTypeByID(Record[OpNum++]); if (!ElTy) return error("Invalid record"); Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy)); } - if (PointeeType && - PointeeType != - cast<PointerType>(Elts[0]->getType()->getScalarType()) - ->getElementType()) - return error("Explicit gep operator type does not match pointee type " - "of pointer operand"); - if (Elts.size() < 1) return error("Invalid gep with no operands"); + Type *ImplicitPointeeType = + getPointerElementFlatType(Elt0FullTy->getScalarType()); + if (!PointeeType) + PointeeType = ImplicitPointeeType; + else if (PointeeType != ImplicitPointeeType) + return error("Explicit gep operator type does not match pointee type " + "of pointer operand"); + ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end()); V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices, InBounds, InRangeIndex); @@ -2560,10 +2741,10 @@ Error BitcodeReader::parseConstants() { AsmStr += (char)Record[2+i]; for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; - PointerType *PTy = cast<PointerType>(CurTy); UpgradeInlineAsmString(&AsmStr); - V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack); + V = InlineAsm::get( + cast<FunctionType>(getPointerElementFlatType(CurFullTy)), AsmStr, + ConstrStr, HasSideEffects, IsAlignStack); break; } // This version adds support for the asm dialect keywords (e.g., @@ -2586,11 +2767,11 @@ Error BitcodeReader::parseConstants() { AsmStr += (char)Record[2+i]; for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; - PointerType *PTy = cast<PointerType>(CurTy); UpgradeInlineAsmString(&AsmStr); - V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack, - InlineAsm::AsmDialect(AsmDialect)); + V = InlineAsm::get( + cast<FunctionType>(getPointerElementFlatType(CurFullTy)), AsmStr, + ConstrStr, HasSideEffects, IsAlignStack, + InlineAsm::AsmDialect(AsmDialect)); break; } case bitc::CST_CODE_BLOCKADDRESS:{ @@ -2636,20 +2817,25 @@ Error BitcodeReader::parseConstants() { } } - ValueList.assignValue(V, NextCstNo); + assert(V->getType() == flattenPointerTypes(CurFullTy) && + "Incorrect fully structured type provided for Constant"); + ValueList.assignValue(V, NextCstNo, CurFullTy); ++NextCstNo; } } Error BitcodeReader::parseUseLists() { - if (Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID)) + return Err; // Read all the records. SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -2665,7 +2851,10 @@ Error BitcodeReader::parseUseLists() { // Read a use list record. Record.clear(); bool IsBB = false; - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: unknown type. break; case bitc::USELIST_CODE_BB: @@ -2714,15 +2903,16 @@ Error BitcodeReader::rememberAndSkipMetadata() { DeferredMetadataInfo.push_back(CurBit); // Skip over the block for now. - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; return Error::success(); } Error BitcodeReader::materializeMetadata() { for (uint64_t BitPos : DeferredMetadataInfo) { // Move the bit stream to the saved position. - Stream.JumpToBit(BitPos); + if (Error JumpFailed = Stream.JumpToBit(BitPos)) + return JumpFailed; if (Error Err = MDLoader->parseModuleMetadata()) return Err; } @@ -2760,8 +2950,8 @@ Error BitcodeReader::rememberAndSkipFunctionBody() { DeferredFunctionInfo[Fn] = CurBit; // Skip over the function block for now. - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; return Error::success(); } @@ -2786,8 +2976,14 @@ Error BitcodeReader::globalCleanup() { } // Look for global variables which need to be renamed. + std::vector<std::pair<GlobalVariable *, GlobalVariable *>> UpgradedVariables; for (GlobalVariable &GV : TheModule->globals()) - UpgradeGlobalVariable(&GV); + if (GlobalVariable *Upgraded = UpgradeGlobalVariable(&GV)) + UpgradedVariables.emplace_back(&GV, Upgraded); + for (auto &Pair : UpgradedVariables) { + Pair.first->eraseFromParent(); + TheModule->getGlobalList().push_back(Pair.second); + } // Force deallocation of memory for these vectors to favor the client that // want lazy deserialization. @@ -2802,7 +2998,8 @@ Error BitcodeReader::globalCleanup() { /// or if we have an anonymous function being materialized, since anonymous /// functions do not have a name and are therefore not in the VST. Error BitcodeReader::rememberAndSkipFunctionBodies() { - Stream.JumpToBit(NextUnreadBit); + if (Error JumpFailed = Stream.JumpToBit(NextUnreadBit)) + return JumpFailed; if (Stream.AtEndOfStream()) return error("Could not find function in stream"); @@ -2817,7 +3014,11 @@ Error BitcodeReader::rememberAndSkipFunctionBodies() { SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); + switch (Entry.Kind) { default: return error("Expect SubBlock"); @@ -2836,7 +3037,12 @@ Error BitcodeReader::rememberAndSkipFunctionBodies() { } bool BitcodeReaderBase::readBlockInfo() { - Optional<BitstreamBlockInfo> NewBlockInfo = Stream.ReadBlockInfoBlock(); + Expected<Optional<BitstreamBlockInfo>> MaybeNewBlockInfo = + Stream.ReadBlockInfoBlock(); + if (!MaybeNewBlockInfo) + return true; // FIXME Handle the error. + Optional<BitstreamBlockInfo> NewBlockInfo = + std::move(MaybeNewBlockInfo.get()); if (!NewBlockInfo) return true; BlockInfo = std::move(*NewBlockInfo); @@ -2878,14 +3084,16 @@ static void inferDSOLocal(GlobalValue *GV) { Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { // v1: [pointer type, isconst, initid, linkage, alignment, section, // visibility, threadlocal, unnamed_addr, externally_initialized, - // dllstorageclass, comdat, attributes, preemption specifier] (name in VST) + // dllstorageclass, comdat, attributes, preemption specifier, + // partition strtab offset, partition strtab size] (name in VST) // v2: [strtab_offset, strtab_size, v1] StringRef Name; std::tie(Name, Record) = readNameFromStrtab(Record); if (Record.size() < 6) return error("Invalid record"); - Type *Ty = getTypeByID(Record[0]); + Type *FullTy = getFullyStructuredTypeByID(Record[0]); + Type *Ty = flattenPointerTypes(FullTy); if (!Ty) return error("Invalid record"); bool isConstant = Record[1] & 1; @@ -2897,7 +3105,7 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { if (!Ty->isPointerTy()) return error("Invalid type for value"); AddressSpace = cast<PointerType>(Ty)->getAddressSpace(); - Ty = cast<PointerType>(Ty)->getElementType(); + std::tie(FullTy, Ty) = getPointerElementTypes(FullTy); } uint64_t RawLinkage = Record[3]; @@ -2943,7 +3151,10 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { else upgradeDLLImportExportLinkage(NewGV, RawLinkage); - ValueList.push_back(NewGV); + FullTy = PointerType::get(FullTy, AddressSpace); + assert(NewGV->getType() == flattenPointerTypes(FullTy) && + "Incorrect fully specified type for GlobalVariable"); + ValueList.push_back(NewGV, FullTy); // Remember which value to use for the global initializer. if (unsigned InitID = Record[2]) @@ -2969,6 +3180,10 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { } inferDSOLocal(NewGV); + // Check whether we have enough values to read a partition name. + if (Record.size() > 15) + NewGV->setPartition(StringRef(Strtab.data() + Record[14], Record[15])); + return Error::success(); } @@ -2982,13 +3197,14 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { if (Record.size() < 8) return error("Invalid record"); - Type *Ty = getTypeByID(Record[0]); - if (!Ty) - return error("Invalid record"); - if (auto *PTy = dyn_cast<PointerType>(Ty)) - Ty = PTy->getElementType(); - auto *FTy = dyn_cast<FunctionType>(Ty); + Type *FullFTy = getFullyStructuredTypeByID(Record[0]); + Type *FTy = flattenPointerTypes(FullFTy); if (!FTy) + return error("Invalid record"); + if (isa<PointerType>(FTy)) + std::tie(FullFTy, FTy) = getPointerElementTypes(FullFTy); + + if (!isa<FunctionType>(FTy)) return error("Invalid type for value"); auto CC = static_cast<CallingConv::ID>(Record[1]); if (CC & ~CallingConv::MaxID) @@ -2998,8 +3214,13 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { if (Record.size() > 16) AddrSpace = Record[16]; - Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage, - AddrSpace, Name, TheModule); + Function *Func = + Function::Create(cast<FunctionType>(FTy), GlobalValue::ExternalLinkage, + AddrSpace, Name, TheModule); + + assert(Func->getFunctionType() == flattenPointerTypes(FullFTy) && + "Incorrect fully specified type provided for function"); + FunctionTypes[Func] = cast<FunctionType>(FullFTy); Func->setCallingConv(CC); bool isProto = Record[2]; @@ -3007,6 +3228,19 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { Func->setLinkage(getDecodedLinkage(RawLinkage)); Func->setAttributes(getAttributes(Record[4])); + // Upgrade any old-style byval without a type by propagating the argument's + // pointee type. There should be no opaque pointers where the byval type is + // implicit. + for (unsigned i = 0; i != Func->arg_size(); ++i) { + if (!Func->hasParamAttribute(i, Attribute::ByVal)) + continue; + + Type *PTy = cast<FunctionType>(FullFTy)->getParamType(i); + Func->removeParamAttr(i, Attribute::ByVal); + Func->addParamAttr(i, Attribute::getWithByValType( + Context, getPointerElementFlatType(PTy))); + } + unsigned Alignment; if (Error Err = parseAlignmentValue(Record[5], Alignment)) return Err; @@ -3058,7 +3292,16 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { } inferDSOLocal(Func); - ValueList.push_back(Func); + // Record[16] is the address space number. + + // Check whether we have enough values to read a partition name. + if (Record.size() > 18) + Func->setPartition(StringRef(Strtab.data() + Record[17], Record[18])); + + Type *FullTy = PointerType::get(FullFTy, AddrSpace); + assert(Func->getType() == flattenPointerTypes(FullTy) && + "Incorrect fully specified type provided for Function"); + ValueList.push_back(Func, FullTy); // If this is a function with a body, remember the prototype we are // creating now, so that we can match up the body with them later. @@ -3087,7 +3330,8 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( if (Record.size() < (3 + (unsigned)NewRecord)) return error("Invalid record"); unsigned OpNum = 0; - Type *Ty = getTypeByID(Record[OpNum++]); + Type *FullTy = getFullyStructuredTypeByID(Record[OpNum++]); + Type *Ty = flattenPointerTypes(FullTy); if (!Ty) return error("Invalid record"); @@ -3096,7 +3340,7 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( auto *PTy = dyn_cast<PointerType>(Ty); if (!PTy) return error("Invalid type for value"); - Ty = PTy->getElementType(); + std::tie(FullTy, Ty) = getPointerElementTypes(FullTy); AddrSpace = PTy->getAddressSpace(); } else { AddrSpace = Record[OpNum++]; @@ -3112,6 +3356,9 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( else NewGA = GlobalIFunc::create(Ty, AddrSpace, getDecodedLinkage(Linkage), Name, nullptr, TheModule); + + assert(NewGA->getValueType() == flattenPointerTypes(FullTy) && + "Incorrect fully structured type provided for GlobalIndirectSymbol"); // Old bitcode files didn't have visibility field. // Local linkage must have default visibility. if (OpNum != Record.size()) { @@ -3135,23 +3382,37 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( NewGA->setDSOLocal(getDecodedDSOLocal(Record[OpNum++])); inferDSOLocal(NewGA); - ValueList.push_back(NewGA); + // Check whether we have enough values to read a partition name. + if (OpNum + 1 < Record.size()) { + NewGA->setPartition( + StringRef(Strtab.data() + Record[OpNum], Record[OpNum + 1])); + OpNum += 2; + } + + FullTy = PointerType::get(FullTy, AddrSpace); + assert(NewGA->getType() == flattenPointerTypes(FullTy) && + "Incorrect fully structured type provided for GlobalIndirectSymbol"); + ValueList.push_back(NewGA, FullTy); IndirectSymbolInits.push_back(std::make_pair(NewGA, Val)); return Error::success(); } Error BitcodeReader::parseModule(uint64_t ResumeBit, bool ShouldLazyLoadMetadata) { - if (ResumeBit) - Stream.JumpToBit(ResumeBit); - else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); + if (ResumeBit) { + if (Error JumpFailed = Stream.JumpToBit(ResumeBit)) + return JumpFailed; + } else if (Error Err = Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; // Read all the records for this module. while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::Error: @@ -3162,8 +3423,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, case BitstreamEntry::SubBlock: switch (Entry.ID) { default: // Skip unknown content. - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; break; case bitc::BLOCKINFO_BLOCK_ID: if (readBlockInfo()) @@ -3196,8 +3457,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, // We must have had a VST forward declaration record, which caused // the parser to jump to and parse the VST earlier. assert(VSTOffset > 0); - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; } break; case bitc::CONSTANTS_BLOCK_ID: @@ -3249,8 +3510,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, // materializing functions. The ResumeBit points to the // start of the last function block recorded in the // DeferredFunctionInfo map. Skip it. - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; continue; } } @@ -3294,8 +3555,10 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, } // Read a record. - auto BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (unsigned BitCode = MaybeBitCode.get()) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_VERSION: { Expected<unsigned> VersionOrErr = parseVersionRecord(Record); @@ -3407,10 +3670,23 @@ Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) { return Error::success(); } +void BitcodeReader::propagateByValTypes(CallBase *CB, + ArrayRef<Type *> ArgsFullTys) { + for (unsigned i = 0; i != CB->arg_size(); ++i) { + if (!CB->paramHasAttr(i, Attribute::ByVal)) + continue; + + CB->removeParamAttr(i, Attribute::ByVal); + CB->addParamAttr( + i, Attribute::getWithByValType( + Context, getPointerElementFlatType(ArgsFullTys[i]))); + } +} + /// Lazily parse the specified function body block. Error BitcodeReader::parseFunctionBody(Function *F) { - if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID)) + return Err; // Unexpected unresolved metadata when parsing function. if (MDLoader->hasFwdRefs()) @@ -3421,9 +3697,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned ModuleMDLoaderSize = MDLoader->size(); // Add all the function arguments to the value table. - for (Argument &I : F->args()) - ValueList.push_back(&I); - + unsigned ArgNo = 0; + FunctionType *FullFTy = FunctionTypes[F]; + for (Argument &I : F->args()) { + assert(I.getType() == flattenPointerTypes(FullFTy->getParamType(ArgNo)) && + "Incorrect fully specified type for Function Argument"); + ValueList.push_back(&I, FullFTy->getParamType(ArgNo++)); + } unsigned NextValueNo = ValueList.size(); BasicBlock *CurBB = nullptr; unsigned CurBBNo = 0; @@ -3444,7 +3724,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) { SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::Error: @@ -3455,8 +3738,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case BitstreamEntry::SubBlock: switch (Entry.ID) { default: // Skip unknown content. - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; break; case bitc::CONSTANTS_BLOCK_ID: if (Error Err = parseConstants()) @@ -3492,8 +3775,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // Read a record. Record.clear(); Instruction *I = nullptr; - unsigned BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Type *FullTy = nullptr; + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (unsigned BitCode = MaybeBitCode.get()) { default: // Default behavior: reject return error("Invalid value"); case bitc::FUNC_CODE_DECLAREBLOCKS: { // DECLAREBLOCKS: [nblocks] @@ -3634,7 +3920,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { OpNum+2 != Record.size()) return error("Invalid record"); - Type *ResTy = getTypeByID(Record[OpNum]); + FullTy = getFullyStructuredTypeByID(Record[OpNum]); + Type *ResTy = flattenPointerTypes(FullTy); int Opc = getDecodedCastOpcode(Record[OpNum + 1]); if (Opc == -1 || !ResTy) return error("Invalid record"); @@ -3663,22 +3950,22 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (BitCode == bitc::FUNC_CODE_INST_GEP) { InBounds = Record[OpNum++]; - Ty = getTypeByID(Record[OpNum++]); + FullTy = getFullyStructuredTypeByID(Record[OpNum++]); + Ty = flattenPointerTypes(FullTy); } else { InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD; Ty = nullptr; } Value *BasePtr; - if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr)) + Type *FullBaseTy = nullptr; + if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr, &FullBaseTy)) return error("Invalid record"); - if (!Ty) - Ty = cast<PointerType>(BasePtr->getType()->getScalarType()) - ->getElementType(); - else if (Ty != - cast<PointerType>(BasePtr->getType()->getScalarType()) - ->getElementType()) + if (!Ty) { + std::tie(FullTy, Ty) = + getPointerElementTypes(FullBaseTy->getScalarType()); + } else if (Ty != getPointerElementFlatType(FullBaseTy->getScalarType())) return error( "Explicit gep type does not match pointee type of pointer operand"); @@ -3691,6 +3978,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx); + FullTy = GetElementPtrInst::getGEPReturnType(FullTy, I, GEPIdx); InstructionList.push_back(I); if (InBounds) @@ -3702,7 +3990,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // EXTRACTVAL: [opty, opval, n x indices] unsigned OpNum = 0; Value *Agg; - if (getValueTypePair(Record, OpNum, NextValueNo, Agg)) + if (getValueTypePair(Record, OpNum, NextValueNo, Agg, &FullTy)) return error("Invalid record"); unsigned RecSize = Record.size(); @@ -3710,26 +3998,25 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("EXTRACTVAL: Invalid instruction with 0 indices"); SmallVector<unsigned, 4> EXTRACTVALIdx; - Type *CurTy = Agg->getType(); for (; OpNum != RecSize; ++OpNum) { - bool IsArray = CurTy->isArrayTy(); - bool IsStruct = CurTy->isStructTy(); + bool IsArray = FullTy->isArrayTy(); + bool IsStruct = FullTy->isStructTy(); uint64_t Index = Record[OpNum]; if (!IsStruct && !IsArray) return error("EXTRACTVAL: Invalid type"); if ((unsigned)Index != Index) return error("Invalid value"); - if (IsStruct && Index >= CurTy->getStructNumElements()) + if (IsStruct && Index >= FullTy->getStructNumElements()) return error("EXTRACTVAL: Invalid struct index"); - if (IsArray && Index >= CurTy->getArrayNumElements()) + if (IsArray && Index >= FullTy->getArrayNumElements()) return error("EXTRACTVAL: Invalid array index"); EXTRACTVALIdx.push_back((unsigned)Index); if (IsStruct) - CurTy = CurTy->getStructElementType(Index); + FullTy = FullTy->getStructElementType(Index); else - CurTy = CurTy->getArrayElementType(); + FullTy = FullTy->getArrayElementType(); } I = ExtractValueInst::Create(Agg, EXTRACTVALIdx); @@ -3741,7 +4028,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // INSERTVAL: [opty, opval, opty, opval, n x indices] unsigned OpNum = 0; Value *Agg; - if (getValueTypePair(Record, OpNum, NextValueNo, Agg)) + if (getValueTypePair(Record, OpNum, NextValueNo, Agg, &FullTy)) return error("Invalid record"); Value *Val; if (getValueTypePair(Record, OpNum, NextValueNo, Val)) @@ -3787,7 +4074,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // handles select i1 ... in old bitcode unsigned OpNum = 0; Value *TrueVal, *FalseVal, *Cond; - if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) || + if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, &FullTy) || popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) || popValue(Record, OpNum, NextValueNo, Type::getInt1Ty(Context), Cond)) return error("Invalid record"); @@ -3802,7 +4089,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // handles select i1 or select [N x i1] unsigned OpNum = 0; Value *TrueVal, *FalseVal, *Cond; - if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) || + if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, &FullTy) || popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) || getValueTypePair(Record, OpNum, NextValueNo, Cond)) return error("Invalid record"); @@ -3821,18 +4108,24 @@ Error BitcodeReader::parseFunctionBody(Function *F) { I = SelectInst::Create(Cond, TrueVal, FalseVal); InstructionList.push_back(I); + if (OpNum < Record.size() && isa<FPMathOperator>(I)) { + FastMathFlags FMF = getDecodedFastMathFlags(Record[OpNum]); + if (FMF.any()) + I->setFastMathFlags(FMF); + } break; } case bitc::FUNC_CODE_INST_EXTRACTELT: { // EXTRACTELT: [opty, opval, opval] unsigned OpNum = 0; Value *Vec, *Idx; - if (getValueTypePair(Record, OpNum, NextValueNo, Vec) || + if (getValueTypePair(Record, OpNum, NextValueNo, Vec, &FullTy) || getValueTypePair(Record, OpNum, NextValueNo, Idx)) return error("Invalid record"); if (!Vec->getType()->isVectorTy()) return error("Invalid type for value"); I = ExtractElementInst::Create(Vec, Idx); + FullTy = FullTy->getVectorElementType(); InstructionList.push_back(I); break; } @@ -3840,7 +4133,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_INSERTELT: { // INSERTELT: [ty, opval,opval,opval] unsigned OpNum = 0; Value *Vec, *Elt, *Idx; - if (getValueTypePair(Record, OpNum, NextValueNo, Vec)) + if (getValueTypePair(Record, OpNum, NextValueNo, Vec, &FullTy)) return error("Invalid record"); if (!Vec->getType()->isVectorTy()) return error("Invalid type for value"); @@ -3856,7 +4149,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_SHUFFLEVEC: {// SHUFFLEVEC: [opval,ty,opval,opval] unsigned OpNum = 0; Value *Vec1, *Vec2, *Mask; - if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) || + if (getValueTypePair(Record, OpNum, NextValueNo, Vec1, &FullTy) || popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec2)) return error("Invalid record"); @@ -3865,6 +4158,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (!Vec1->getType()->isVectorTy() || !Vec2->getType()->isVectorTy()) return error("Invalid type for value"); I = new ShuffleVectorInst(Vec1, Vec2, Mask); + FullTy = VectorType::get(FullTy->getVectorElementType(), + Mask->getType()->getVectorNumElements()); InstructionList.push_back(I); break; } @@ -3882,6 +4177,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) { popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS)) return error("Invalid record"); + if (OpNum >= Record.size()) + return error( + "Invalid record: operand number exceeded available operands"); + unsigned PredVal = Record[OpNum]; bool IsFP = LHS->getType()->isFPOrFPVectorTy(); FastMathFlags FMF; @@ -4168,31 +4467,40 @@ Error BitcodeReader::parseFunctionBody(Function *F) { BasicBlock *UnwindBB = getBasicBlock(Record[OpNum++]); FunctionType *FTy = nullptr; - if (CCInfo >> 13 & 1 && - !(FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++])))) - return error("Explicit invoke type is not a function type"); + FunctionType *FullFTy = nullptr; + if ((CCInfo >> 13) & 1) { + FullFTy = + dyn_cast<FunctionType>(getFullyStructuredTypeByID(Record[OpNum++])); + if (!FullFTy) + return error("Explicit invoke type is not a function type"); + FTy = cast<FunctionType>(flattenPointerTypes(FullFTy)); + } Value *Callee; - if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) + if (getValueTypePair(Record, OpNum, NextValueNo, Callee, &FullTy)) return error("Invalid record"); PointerType *CalleeTy = dyn_cast<PointerType>(Callee->getType()); if (!CalleeTy) return error("Callee is not a pointer"); if (!FTy) { - FTy = dyn_cast<FunctionType>(CalleeTy->getElementType()); - if (!FTy) + FullFTy = + dyn_cast<FunctionType>(cast<PointerType>(FullTy)->getElementType()); + if (!FullFTy) return error("Callee is not of pointer to function type"); - } else if (CalleeTy->getElementType() != FTy) + FTy = cast<FunctionType>(flattenPointerTypes(FullFTy)); + } else if (getPointerElementFlatType(FullTy) != FTy) return error("Explicit invoke type does not match pointee type of " "callee operand"); if (Record.size() < FTy->getNumParams() + OpNum) return error("Insufficient operands to call"); SmallVector<Value*, 16> Ops; + SmallVector<Type *, 16> ArgsFullTys; for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { Ops.push_back(getValue(Record, OpNum, NextValueNo, FTy->getParamType(i))); + ArgsFullTys.push_back(FullFTy->getParamType(i)); if (!Ops.back()) return error("Invalid record"); } @@ -4204,18 +4512,24 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // Read type/value pairs for varargs params. while (OpNum != Record.size()) { Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + Type *FullTy; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy)) return error("Invalid record"); Ops.push_back(Op); + ArgsFullTys.push_back(FullTy); } } - I = InvokeInst::Create(Callee, NormalBB, UnwindBB, Ops, OperandBundles); + I = InvokeInst::Create(FTy, Callee, NormalBB, UnwindBB, Ops, + OperandBundles); + FullTy = FullFTy->getReturnType(); OperandBundles.clear(); InstructionList.push_back(I); cast<InvokeInst>(I)->setCallingConv( static_cast<CallingConv::ID>(CallingConv::MaxID & CCInfo)); cast<InvokeInst>(I)->setAttributes(PAL); + propagateByValTypes(cast<CallBase>(I), ArgsFullTys); + break; } case bitc::FUNC_CODE_INST_RESUME: { // RESUME: [opval] @@ -4227,6 +4541,82 @@ Error BitcodeReader::parseFunctionBody(Function *F) { InstructionList.push_back(I); break; } + case bitc::FUNC_CODE_INST_CALLBR: { + // CALLBR: [attr, cc, norm, transfs, fty, fnid, args] + unsigned OpNum = 0; + AttributeList PAL = getAttributes(Record[OpNum++]); + unsigned CCInfo = Record[OpNum++]; + + BasicBlock *DefaultDest = getBasicBlock(Record[OpNum++]); + unsigned NumIndirectDests = Record[OpNum++]; + SmallVector<BasicBlock *, 16> IndirectDests; + for (unsigned i = 0, e = NumIndirectDests; i != e; ++i) + IndirectDests.push_back(getBasicBlock(Record[OpNum++])); + + FunctionType *FTy = nullptr; + FunctionType *FullFTy = nullptr; + if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) { + FullFTy = + dyn_cast<FunctionType>(getFullyStructuredTypeByID(Record[OpNum++])); + if (!FullFTy) + return error("Explicit call type is not a function type"); + FTy = cast<FunctionType>(flattenPointerTypes(FullFTy)); + } + + Value *Callee; + if (getValueTypePair(Record, OpNum, NextValueNo, Callee, &FullTy)) + return error("Invalid record"); + + PointerType *OpTy = dyn_cast<PointerType>(Callee->getType()); + if (!OpTy) + return error("Callee is not a pointer type"); + if (!FTy) { + FullFTy = + dyn_cast<FunctionType>(cast<PointerType>(FullTy)->getElementType()); + if (!FullFTy) + return error("Callee is not of pointer to function type"); + FTy = cast<FunctionType>(flattenPointerTypes(FullFTy)); + } else if (getPointerElementFlatType(FullTy) != FTy) + return error("Explicit call type does not match pointee type of " + "callee operand"); + if (Record.size() < FTy->getNumParams() + OpNum) + return error("Insufficient operands to call"); + + SmallVector<Value*, 16> Args; + // Read the fixed params. + for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { + if (FTy->getParamType(i)->isLabelTy()) + Args.push_back(getBasicBlock(Record[OpNum])); + else + Args.push_back(getValue(Record, OpNum, NextValueNo, + FTy->getParamType(i))); + if (!Args.back()) + return error("Invalid record"); + } + + // Read type/value pairs for varargs params. + if (!FTy->isVarArg()) { + if (OpNum != Record.size()) + return error("Invalid record"); + } else { + while (OpNum != Record.size()) { + Value *Op; + if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + return error("Invalid record"); + Args.push_back(Op); + } + } + + I = CallBrInst::Create(FTy, Callee, DefaultDest, IndirectDests, Args, + OperandBundles); + FullTy = FullFTy->getReturnType(); + OperandBundles.clear(); + InstructionList.push_back(I); + cast<CallBrInst>(I)->setCallingConv( + static_cast<CallingConv::ID>((0x7ff & CCInfo) >> bitc::CALL_CCONV)); + cast<CallBrInst>(I)->setAttributes(PAL); + break; + } case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE I = new UnreachableInst(Context); InstructionList.push_back(I); @@ -4234,7 +4624,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...] if (Record.size() < 1 || ((Record.size()-1)&1)) return error("Invalid record"); - Type *Ty = getTypeByID(Record[0]); + FullTy = getFullyStructuredTypeByID(Record[0]); + Type *Ty = flattenPointerTypes(FullTy); if (!Ty) return error("Invalid record"); @@ -4271,7 +4662,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (Record.size() < 4) return error("Invalid record"); } - Type *Ty = getTypeByID(Record[Idx++]); + FullTy = getFullyStructuredTypeByID(Record[Idx++]); + Type *Ty = flattenPointerTypes(FullTy); if (!Ty) return error("Invalid record"); if (BitCode == bitc::FUNC_CODE_INST_LANDINGPAD_OLD) { @@ -4324,12 +4716,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) { SwiftErrorMask; bool InAlloca = AlignRecord & InAllocaMask; bool SwiftError = AlignRecord & SwiftErrorMask; - Type *Ty = getTypeByID(Record[0]); + FullTy = getFullyStructuredTypeByID(Record[0]); + Type *Ty = flattenPointerTypes(FullTy); if ((AlignRecord & ExplicitTypeMask) == 0) { auto *PTy = dyn_cast_or_null<PointerType>(Ty); if (!PTy) return error("Old-style alloca with a non-pointer type"); - Ty = PTy->getElementType(); + std::tie(FullTy, Ty) = getPointerElementTypes(FullTy); } Type *OpTy = getTypeByID(Record[1]); Value *Size = getFnValueByID(Record[2], OpTy); @@ -4348,29 +4741,34 @@ Error BitcodeReader::parseFunctionBody(Function *F) { AI->setUsedWithInAlloca(InAlloca); AI->setSwiftError(SwiftError); I = AI; + FullTy = PointerType::get(FullTy, AS); InstructionList.push_back(I); break; } case bitc::FUNC_CODE_INST_LOAD: { // LOAD: [opty, op, align, vol] unsigned OpNum = 0; Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op) || + if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy) || (OpNum + 2 != Record.size() && OpNum + 3 != Record.size())) return error("Invalid record"); + if (!isa<PointerType>(Op->getType())) + return error("Load operand is not a pointer type"); + Type *Ty = nullptr; - if (OpNum + 3 == Record.size()) - Ty = getTypeByID(Record[OpNum++]); + if (OpNum + 3 == Record.size()) { + FullTy = getFullyStructuredTypeByID(Record[OpNum++]); + Ty = flattenPointerTypes(FullTy); + } else + std::tie(FullTy, Ty) = getPointerElementTypes(FullTy); + if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType())) return Err; - if (!Ty) - Ty = cast<PointerType>(Op->getType())->getElementType(); unsigned Align; if (Error Err = parseAlignmentValue(Record[OpNum], Align)) return Err; I = new LoadInst(Ty, Op, "", Record[OpNum + 1], Align); - InstructionList.push_back(I); break; } @@ -4378,17 +4776,22 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // LOADATOMIC: [opty, op, align, vol, ordering, ssid] unsigned OpNum = 0; Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op) || + if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy) || (OpNum + 4 != Record.size() && OpNum + 5 != Record.size())) return error("Invalid record"); + if (!isa<PointerType>(Op->getType())) + return error("Load operand is not a pointer type"); + Type *Ty = nullptr; - if (OpNum + 5 == Record.size()) - Ty = getTypeByID(Record[OpNum++]); + if (OpNum + 5 == Record.size()) { + FullTy = getFullyStructuredTypeByID(Record[OpNum++]); + Ty = flattenPointerTypes(FullTy); + } else + std::tie(FullTy, Ty) = getPointerElementTypes(FullTy); + if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType())) return Err; - if (!Ty) - Ty = cast<PointerType>(Op->getType())->getElementType(); AtomicOrdering Ordering = getDecodedOrdering(Record[OpNum + 2]); if (Ordering == AtomicOrdering::NotAtomic || @@ -4402,8 +4805,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned Align; if (Error Err = parseAlignmentValue(Record[OpNum], Align)) return Err; - I = new LoadInst(Op, "", Record[OpNum+1], Align, Ordering, SSID); - + I = new LoadInst(Ty, Op, "", Record[OpNum + 1], Align, Ordering, SSID); InstructionList.push_back(I); break; } @@ -4411,12 +4813,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_STORE_OLD: { // STORE2:[ptrty, ptr, val, align, vol] unsigned OpNum = 0; Value *Val, *Ptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || + Type *FullTy; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy) || (BitCode == bitc::FUNC_CODE_INST_STORE ? getValueTypePair(Record, OpNum, NextValueNo, Val) : popValue(Record, OpNum, NextValueNo, - cast<PointerType>(Ptr->getType())->getElementType(), - Val)) || + getPointerElementFlatType(FullTy), Val)) || OpNum + 2 != Record.size()) return error("Invalid record"); @@ -4434,13 +4836,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, ssid] unsigned OpNum = 0; Value *Val, *Ptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || + Type *FullTy; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy) || !isa<PointerType>(Ptr->getType()) || (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC ? getValueTypePair(Record, OpNum, NextValueNo, Val) : popValue(Record, OpNum, NextValueNo, - cast<PointerType>(Ptr->getType())->getElementType(), - Val)) || + getPointerElementFlatType(FullTy), Val)) || OpNum + 4 != Record.size()) return error("Invalid record"); @@ -4468,15 +4870,25 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // failureordering?, isweak?] unsigned OpNum = 0; Value *Ptr, *Cmp, *New; - if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || - (BitCode == bitc::FUNC_CODE_INST_CMPXCHG - ? getValueTypePair(Record, OpNum, NextValueNo, Cmp) - : popValue(Record, OpNum, NextValueNo, - cast<PointerType>(Ptr->getType())->getElementType(), - Cmp)) || - popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) || + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy)) + return error("Invalid record"); + + if (!isa<PointerType>(Ptr->getType())) + return error("Cmpxchg operand is not a pointer type"); + + if (BitCode == bitc::FUNC_CODE_INST_CMPXCHG) { + if (getValueTypePair(Record, OpNum, NextValueNo, Cmp, &FullTy)) + return error("Invalid record"); + } else if (popValue(Record, OpNum, NextValueNo, + getPointerElementFlatType(FullTy), Cmp)) + return error("Invalid record"); + else + FullTy = cast<PointerType>(FullTy)->getElementType(); + + if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) || Record.size() < OpNum + 3 || Record.size() > OpNum + 5) return error("Invalid record"); + AtomicOrdering SuccessOrdering = getDecodedOrdering(Record[OpNum + 1]); if (SuccessOrdering == AtomicOrdering::NotAtomic || SuccessOrdering == AtomicOrdering::Unordered) @@ -4494,6 +4906,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { I = new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering, FailureOrdering, SSID); + FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)}); cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]); if (Record.size() < 8) { @@ -4502,6 +4915,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // expecting the first component of a modern cmpxchg. CurBB->getInstList().push_back(I); I = ExtractValueInst::Create(I, 0); + FullTy = cast<StructType>(FullTy)->getElementType(0); } else { cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum+4]); } @@ -4513,11 +4927,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // ATOMICRMW:[ptrty, ptr, val, op, vol, ordering, ssid] unsigned OpNum = 0; Value *Ptr, *Val; - if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy) || !isa<PointerType>(Ptr->getType()) || popValue(Record, OpNum, NextValueNo, - cast<PointerType>(Ptr->getType())->getElementType(), Val) || - OpNum+4 != Record.size()) + getPointerElementFlatType(FullTy), Val) || + OpNum + 4 != Record.size()) return error("Invalid record"); AtomicRMWInst::BinOp Operation = getDecodedRMWOperation(Record[OpNum]); if (Operation < AtomicRMWInst::FIRST_BINOP || @@ -4529,6 +4943,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("Invalid record"); SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 3]); I = new AtomicRMWInst(Operation, Ptr, Val, Ordering, SSID); + FullTy = getPointerElementFlatType(FullTy); cast<AtomicRMWInst>(I)->setVolatile(Record[OpNum+1]); InstructionList.push_back(I); break; @@ -4563,28 +4978,36 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } FunctionType *FTy = nullptr; - if (CCInfo >> bitc::CALL_EXPLICIT_TYPE & 1 && - !(FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++])))) - return error("Explicit call type is not a function type"); + FunctionType *FullFTy = nullptr; + if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) { + FullFTy = + dyn_cast<FunctionType>(getFullyStructuredTypeByID(Record[OpNum++])); + if (!FullFTy) + return error("Explicit call type is not a function type"); + FTy = cast<FunctionType>(flattenPointerTypes(FullFTy)); + } Value *Callee; - if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) + if (getValueTypePair(Record, OpNum, NextValueNo, Callee, &FullTy)) return error("Invalid record"); PointerType *OpTy = dyn_cast<PointerType>(Callee->getType()); if (!OpTy) return error("Callee is not a pointer type"); if (!FTy) { - FTy = dyn_cast<FunctionType>(OpTy->getElementType()); - if (!FTy) + FullFTy = + dyn_cast<FunctionType>(cast<PointerType>(FullTy)->getElementType()); + if (!FullFTy) return error("Callee is not of pointer to function type"); - } else if (OpTy->getElementType() != FTy) + FTy = cast<FunctionType>(flattenPointerTypes(FullFTy)); + } else if (getPointerElementFlatType(FullTy) != FTy) return error("Explicit call type does not match pointee type of " "callee operand"); if (Record.size() < FTy->getNumParams() + OpNum) return error("Insufficient operands to call"); SmallVector<Value*, 16> Args; + SmallVector<Type*, 16> ArgsFullTys; // Read the fixed params. for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { if (FTy->getParamType(i)->isLabelTy()) @@ -4592,6 +5015,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { else Args.push_back(getValue(Record, OpNum, NextValueNo, FTy->getParamType(i))); + ArgsFullTys.push_back(FullFTy->getParamType(i)); if (!Args.back()) return error("Invalid record"); } @@ -4603,13 +5027,16 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } else { while (OpNum != Record.size()) { Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + Type *FullTy; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy)) return error("Invalid record"); Args.push_back(Op); + ArgsFullTys.push_back(FullTy); } } I = CallInst::Create(FTy, Callee, Args, OperandBundles); + FullTy = FullFTy->getReturnType(); OperandBundles.clear(); InstructionList.push_back(I); cast<CallInst>(I)->setCallingConv( @@ -4623,6 +5050,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { TCK = CallInst::TCK_NoTail; cast<CallInst>(I)->setTailCallKind(TCK); cast<CallInst>(I)->setAttributes(PAL); + propagateByValTypes(cast<CallBase>(I), ArgsFullTys); if (FMF.any()) { if (!isa<FPMathOperator>(I)) return error("Fast-math-flags specified for call without " @@ -4636,7 +5064,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("Invalid record"); Type *OpTy = getTypeByID(Record[0]); Value *Op = getValue(Record, 1, NextValueNo, OpTy); - Type *ResTy = getTypeByID(Record[2]); + FullTy = getFullyStructuredTypeByID(Record[2]); + Type *ResTy = flattenPointerTypes(FullTy); if (!OpTy || !Op || !ResTy) return error("Invalid record"); I = new VAArgInst(Op, ResTy); @@ -4686,8 +5115,23 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } // Non-void values get registered in the value table for future use. - if (I && !I->getType()->isVoidTy()) - ValueList.assignValue(I, NextValueNo++); + if (I && !I->getType()->isVoidTy()) { + if (!FullTy) { + FullTy = I->getType(); + assert( + !FullTy->isPointerTy() && !isa<StructType>(FullTy) && + !isa<ArrayType>(FullTy) && + (!isa<VectorType>(FullTy) || + FullTy->getVectorElementType()->isFloatingPointTy() || + FullTy->getVectorElementType()->isIntegerTy()) && + "Structured types must be assigned with corresponding non-opaque " + "pointer type"); + } + + assert(I->getType() == flattenPointerTypes(FullTy) && + "Incorrect fully structured type provided for Instruction"); + ValueList.assignValue(I, NextValueNo++, FullTy); + } } OutOfRecordLoop: @@ -4769,8 +5213,8 @@ Error BitcodeReader::materialize(GlobalValue *GV) { return Err; // Move the bit stream to the saved position of the deferred function body. - Stream.JumpToBit(DFII->second); - + if (Error JumpFailed = Stream.JumpToBit(DFII->second)) + return JumpFailed; if (Error Err = parseFunctionBody(F)) return Err; F->setIsMaterializable(false); @@ -4933,10 +5377,13 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( return Error::success(); assert(Offset > 0 && "Expected non-zero VST offset"); - uint64_t CurrentBit = jumpToValueSymbolTable(Offset, Stream); + Expected<uint64_t> MaybeCurrentBit = jumpToValueSymbolTable(Offset, Stream); + if (!MaybeCurrentBit) + return MaybeCurrentBit.takeError(); + uint64_t CurrentBit = MaybeCurrentBit.get(); - if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; @@ -4944,7 +5391,10 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( SmallString<128> ValueName; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -4952,7 +5402,8 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( return error("Malformed block"); case BitstreamEntry::EndBlock: // Done parsing VST, jump back to wherever we came from. - Stream.JumpToBit(CurrentBit); + if (Error JumpFailed = Stream.JumpToBit(CurrentBit)) + return JumpFailed; return Error::success(); case BitstreamEntry::Record: // The interesting case. @@ -4961,7 +5412,10 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( // Read a record. Record.clear(); - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: ignore (e.g. VST_CODE_BBENTRY records). break; case bitc::VST_CODE_ENTRY: { // VST_CODE_ENTRY: [valueid, namechar x N] @@ -5009,8 +5463,8 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( // At the end of this routine the module Index is populated with a map // from global value id to GlobalValueSummary objects. Error ModuleSummaryIndexBitcodeReader::parseModule() { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; DenseMap<unsigned, GlobalValue::LinkageTypes> ValueIdToLinkageMap; @@ -5018,7 +5472,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { // Read the index for this module. while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::Error: @@ -5029,8 +5486,8 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { case BitstreamEntry::SubBlock: switch (Entry.ID) { default: // Skip unknown content. - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; break; case bitc::BLOCKINFO_BLOCK_ID: // Need to parse these to get abbrev ids (e.g. for VST) @@ -5043,8 +5500,8 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { assert(((SeenValueSymbolTable && VSTOffset > 0) || !SeenGlobalValSummary) && "Expected early VST parse via VSTOffset record"); - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; break; case bitc::GLOBALVAL_SUMMARY_BLOCK_ID: case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID: @@ -5075,8 +5532,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { case BitstreamEntry::Record: { Record.clear(); - auto BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (MaybeBitCode.get()) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_VERSION: { @@ -5224,32 +5683,66 @@ static void parseTypeIdSummaryRecord(ArrayRef<uint64_t> Record, parseWholeProgramDevirtResolution(Record, Strtab, Slot, TypeId); } -static void setImmutableRefs(std::vector<ValueInfo> &Refs, unsigned Count) { - // Read-only refs are in the end of the refs list. - for (unsigned RefNo = Refs.size() - Count; RefNo < Refs.size(); ++RefNo) +void ModuleSummaryIndexBitcodeReader::parseTypeIdCompatibleVtableInfo( + ArrayRef<uint64_t> Record, size_t &Slot, + TypeIdCompatibleVtableInfo &TypeId) { + uint64_t Offset = Record[Slot++]; + ValueInfo Callee = getValueInfoFromValueId(Record[Slot++]).first; + TypeId.push_back({Offset, Callee}); +} + +void ModuleSummaryIndexBitcodeReader::parseTypeIdCompatibleVtableSummaryRecord( + ArrayRef<uint64_t> Record) { + size_t Slot = 0; + TypeIdCompatibleVtableInfo &TypeId = + TheIndex.getOrInsertTypeIdCompatibleVtableSummary( + {Strtab.data() + Record[Slot], + static_cast<size_t>(Record[Slot + 1])}); + Slot += 2; + + while (Slot < Record.size()) + parseTypeIdCompatibleVtableInfo(Record, Slot, TypeId); +} + +static void setSpecialRefs(std::vector<ValueInfo> &Refs, unsigned ROCnt, + unsigned WOCnt) { + // Readonly and writeonly refs are in the end of the refs list. + assert(ROCnt + WOCnt <= Refs.size()); + unsigned FirstWORef = Refs.size() - WOCnt; + unsigned RefNo = FirstWORef - ROCnt; + for (; RefNo < FirstWORef; ++RefNo) Refs[RefNo].setReadOnly(); + for (; RefNo < Refs.size(); ++RefNo) + Refs[RefNo].setWriteOnly(); } // Eagerly parse the entire summary block. This populates the GlobalValueSummary // objects in the index. Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { - if (Stream.EnterSubBlock(ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(ID)) + return Err; SmallVector<uint64_t, 64> Record; // Parse version { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); + if (Entry.Kind != BitstreamEntry::Record) return error("Invalid Summary Block: record for version expected"); - if (Stream.readRecord(Entry.ID, Record) != bitc::FS_VERSION) + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + if (MaybeRecord.get() != bitc::FS_VERSION) return error("Invalid Summary Block: version expected"); } const uint64_t Version = Record[0]; const bool IsOldProfileFormat = Version == 1; - if (Version < 1 || Version > 6) + if (Version < 1 || Version > 7) return error("Invalid summary version " + Twine(Version) + - ". Version should be in the range [1-6]."); + ". Version should be in the range [1-7]."); Record.clear(); // Keep around the last seen summary to be used when we see an optional @@ -5267,7 +5760,10 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { PendingTypeCheckedLoadConstVCalls; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -5288,8 +5784,10 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { // in the combined index VST entries). The records also contain // information used for ThinLTO renaming and importing. Record.clear(); - auto BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (unsigned BitCode = MaybeBitCode.get()) { default: // Default behavior: ignore. break; case bitc::FS_FLAGS: { // [flags] @@ -5343,15 +5841,19 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { unsigned InstCount = Record[2]; uint64_t RawFunFlags = 0; unsigned NumRefs = Record[3]; - unsigned NumImmutableRefs = 0; + unsigned NumRORefs = 0, NumWORefs = 0; int RefListStartIndex = 4; if (Version >= 4) { RawFunFlags = Record[3]; NumRefs = Record[4]; RefListStartIndex = 5; if (Version >= 5) { - NumImmutableRefs = Record[5]; + NumRORefs = Record[5]; RefListStartIndex = 6; + if (Version >= 7) { + NumWORefs = Record[6]; + RefListStartIndex = 7; + } } } @@ -5371,7 +5873,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { std::vector<FunctionSummary::EdgeTy> Calls = makeCallList( ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex), IsOldProfileFormat, HasProfile, HasRelBF); - setImmutableRefs(Refs, NumImmutableRefs); + setSpecialRefs(Refs, NumRORefs, NumWORefs); auto FS = llvm::make_unique<FunctionSummary>( Flags, InstCount, getDecodedFFlags(RawFunFlags), /*EntryCount=*/0, std::move(Refs), std::move(Calls), std::move(PendingTypeTests), @@ -5406,14 +5908,11 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { // ownership. AS->setModulePath(getThisModule()->first()); - GlobalValue::GUID AliaseeGUID = - getValueInfoFromValueId(AliaseeID).first.getGUID(); - auto AliaseeInModule = - TheIndex.findSummaryInModule(AliaseeGUID, ModulePath); + auto AliaseeVI = getValueInfoFromValueId(AliaseeID).first; + auto AliaseeInModule = TheIndex.findSummaryInModule(AliaseeVI, ModulePath); if (!AliaseeInModule) return error("Alias expects aliasee summary to be parsed"); - AS->setAliasee(AliaseeInModule); - AS->setAliaseeGUID(AliaseeGUID); + AS->setAliasee(AliaseeVI, AliaseeInModule); auto GUID = getValueInfoFromValueId(ValueID); AS->setOriginalName(GUID.second); @@ -5425,7 +5924,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { unsigned ValueID = Record[0]; uint64_t RawFlags = Record[1]; unsigned RefArrayStart = 2; - GlobalVarSummary::GVarFlags GVF; + GlobalVarSummary::GVarFlags GVF(/* ReadOnly */ false, + /* WriteOnly */ false); auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); if (Version >= 5) { GVF = getDecodedGVarFlags(Record[2]); @@ -5441,6 +5941,34 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { TheIndex.addGlobalValueSummary(GUID.first, std::move(FS)); break; } + // FS_PERMODULE_VTABLE_GLOBALVAR_INIT_REFS: [valueid, flags, varflags, + // numrefs, numrefs x valueid, + // n x (valueid, offset)] + case bitc::FS_PERMODULE_VTABLE_GLOBALVAR_INIT_REFS: { + unsigned ValueID = Record[0]; + uint64_t RawFlags = Record[1]; + GlobalVarSummary::GVarFlags GVF = getDecodedGVarFlags(Record[2]); + unsigned NumRefs = Record[3]; + unsigned RefListStartIndex = 4; + unsigned VTableListStartIndex = RefListStartIndex + NumRefs; + auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); + std::vector<ValueInfo> Refs = makeRefList( + ArrayRef<uint64_t>(Record).slice(RefListStartIndex, NumRefs)); + VTableFuncList VTableFuncs; + for (unsigned I = VTableListStartIndex, E = Record.size(); I != E; ++I) { + ValueInfo Callee = getValueInfoFromValueId(Record[I]).first; + uint64_t Offset = Record[++I]; + VTableFuncs.push_back({Callee, Offset}); + } + auto VS = + llvm::make_unique<GlobalVarSummary>(Flags, GVF, std::move(Refs)); + VS->setModulePath(getThisModule()->first()); + VS->setVTableFuncs(VTableFuncs); + auto GUID = getValueInfoFromValueId(ValueID); + VS->setOriginalName(GUID.second); + TheIndex.addGlobalValueSummary(GUID.first, std::move(VS)); + break; + } // FS_COMBINED: [valueid, modid, flags, instcount, fflags, numrefs, // numrefs x valueid, n x (valueid)] // FS_COMBINED_PROFILE: [valueid, modid, flags, instcount, fflags, numrefs, @@ -5454,7 +5982,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { uint64_t RawFunFlags = 0; uint64_t EntryCount = 0; unsigned NumRefs = Record[4]; - unsigned NumImmutableRefs = 0; + unsigned NumRORefs = 0, NumWORefs = 0; int RefListStartIndex = 5; if (Version >= 4) { @@ -5462,13 +5990,19 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { RefListStartIndex = 6; size_t NumRefsIndex = 5; if (Version >= 5) { + unsigned NumRORefsOffset = 1; RefListStartIndex = 7; if (Version >= 6) { NumRefsIndex = 6; EntryCount = Record[5]; RefListStartIndex = 8; + if (Version >= 7) { + RefListStartIndex = 9; + NumWORefs = Record[8]; + NumRORefsOffset = 2; + } } - NumImmutableRefs = Record[RefListStartIndex - 1]; + NumRORefs = Record[RefListStartIndex - NumRORefsOffset]; } NumRefs = Record[NumRefsIndex]; } @@ -5484,7 +6018,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex), IsOldProfileFormat, HasProfile, false); ValueInfo VI = getValueInfoFromValueId(ValueID).first; - setImmutableRefs(Refs, NumImmutableRefs); + setSpecialRefs(Refs, NumRORefs, NumWORefs); auto FS = llvm::make_unique<FunctionSummary>( Flags, InstCount, getDecodedFFlags(RawFunFlags), EntryCount, std::move(Refs), std::move(Edges), std::move(PendingTypeTests), @@ -5516,12 +6050,9 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { LastSeenSummary = AS.get(); AS->setModulePath(ModuleIdMap[ModuleId]); - auto AliaseeGUID = - getValueInfoFromValueId(AliaseeValueId).first.getGUID(); - auto AliaseeInModule = - TheIndex.findSummaryInModule(AliaseeGUID, AS->modulePath()); - AS->setAliasee(AliaseeInModule); - AS->setAliaseeGUID(AliaseeGUID); + auto AliaseeVI = getValueInfoFromValueId(AliaseeValueId).first; + auto AliaseeInModule = TheIndex.findSummaryInModule(AliaseeVI, AS->modulePath()); + AS->setAliasee(AliaseeVI, AliaseeInModule); ValueInfo VI = getValueInfoFromValueId(ValueID).first; LastSeenGUID = VI.getGUID(); @@ -5534,7 +6065,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { uint64_t ModuleId = Record[1]; uint64_t RawFlags = Record[2]; unsigned RefArrayStart = 3; - GlobalVarSummary::GVarFlags GVF; + GlobalVarSummary::GVarFlags GVF(/* ReadOnly */ false, + /* WriteOnly */ false); auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); if (Version >= 5) { GVF = getDecodedGVarFlags(Record[3]); @@ -5610,6 +6142,10 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { case bitc::FS_TYPE_ID: parseTypeIdSummaryRecord(Record, Strtab, TheIndex); break; + + case bitc::FS_TYPE_ID_METADATA: + parseTypeIdCompatibleVtableSummaryRecord(Record); + break; } } llvm_unreachable("Exit infinite loop"); @@ -5618,8 +6154,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { // Parse the module string table block into the Index. // This populates the ModulePathStringTable map in the index. Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() { - if (Stream.EnterSubBlock(bitc::MODULE_STRTAB_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::MODULE_STRTAB_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; @@ -5627,7 +6163,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() { ModuleSummaryIndex::ModuleInfo *LastSeenModule = nullptr; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -5641,7 +6180,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() { } Record.clear(); - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: ignore. break; case bitc::MST_CODE_ENTRY: { @@ -5707,12 +6249,16 @@ const std::error_category &llvm::BitcodeErrorCategory() { static Expected<StringRef> readBlobInRecord(BitstreamCursor &Stream, unsigned Block, unsigned RecordID) { - if (Stream.EnterSubBlock(Block)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(Block)) + return std::move(Err); StringRef Strtab; while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); + switch (Entry.Kind) { case BitstreamEntry::EndBlock: return Strtab; @@ -5721,14 +6267,18 @@ static Expected<StringRef> readBlobInRecord(BitstreamCursor &Stream, return error("Malformed block"); case BitstreamEntry::SubBlock: - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); break; case BitstreamEntry::Record: StringRef Blob; SmallVector<uint64_t, 1> Record; - if (Stream.readRecord(Entry.ID, Record, &Blob) == RecordID) + Expected<unsigned> MaybeRecord = + Stream.readRecord(Entry.ID, Record, &Blob); + if (!MaybeRecord) + return MaybeRecord.takeError(); + if (MaybeRecord.get() == RecordID) Strtab = Blob; break; } @@ -5764,7 +6314,11 @@ llvm::getBitcodeFileContents(MemoryBufferRef Buffer) { if (BCBegin + 8 >= Stream.getBitcodeBytes().size()) return F; - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); + switch (Entry.Kind) { case BitstreamEntry::EndBlock: case BitstreamEntry::Error: @@ -5774,10 +6328,16 @@ llvm::getBitcodeFileContents(MemoryBufferRef Buffer) { uint64_t IdentificationBit = -1ull; if (Entry.ID == bitc::IDENTIFICATION_BLOCK_ID) { IdentificationBit = Stream.GetCurrentBitNo() - BCBegin * 8; - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); + + { + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + Entry = MaybeEntry.get(); + } - Entry = Stream.advance(); if (Entry.Kind != BitstreamEntry::SubBlock || Entry.ID != bitc::MODULE_BLOCK_ID) return error("Malformed block"); @@ -5785,8 +6345,8 @@ llvm::getBitcodeFileContents(MemoryBufferRef Buffer) { if (Entry.ID == bitc::MODULE_BLOCK_ID) { uint64_t ModuleBit = Stream.GetCurrentBitNo() - BCBegin * 8; - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); F.Mods.push_back({Stream.getBitcodeBytes().slice( BCBegin, Stream.getCurrentByteNo() - BCBegin), @@ -5834,13 +6394,15 @@ llvm::getBitcodeFileContents(MemoryBufferRef Buffer) { continue; } - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); continue; } case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; + if (Expected<unsigned> StreamFailed = Stream.skipRecord(Entry.ID)) + continue; + else + return StreamFailed.takeError(); } } } @@ -5860,7 +6422,8 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll, std::string ProducerIdentification; if (IdentificationBit != -1ull) { - Stream.JumpToBit(IdentificationBit); + if (Error JumpFailed = Stream.JumpToBit(IdentificationBit)) + return std::move(JumpFailed); Expected<std::string> ProducerIdentificationOrErr = readIdentificationBlock(Stream); if (!ProducerIdentificationOrErr) @@ -5869,7 +6432,8 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll, ProducerIdentification = *ProducerIdentificationOrErr; } - Stream.JumpToBit(ModuleBit); + if (Error JumpFailed = Stream.JumpToBit(ModuleBit)) + return std::move(JumpFailed); auto *R = new BitcodeReader(std::move(Stream), Strtab, ProducerIdentification, Context); @@ -5907,7 +6471,8 @@ BitcodeModule::getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata, Error BitcodeModule::readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, uint64_t ModuleId) { BitstreamCursor Stream(Buffer); - Stream.JumpToBit(ModuleBit); + if (Error JumpFailed = Stream.JumpToBit(ModuleBit)) + return JumpFailed; ModuleSummaryIndexBitcodeReader R(std::move(Stream), Strtab, CombinedIndex, ModulePath, ModuleId); @@ -5917,7 +6482,8 @@ Error BitcodeModule::readSummary(ModuleSummaryIndex &CombinedIndex, // Parse the specified bitcode buffer, returning the function info index. Expected<std::unique_ptr<ModuleSummaryIndex>> BitcodeModule::getSummary() { BitstreamCursor Stream(Buffer); - Stream.JumpToBit(ModuleBit); + if (Error JumpFailed = Stream.JumpToBit(ModuleBit)) + return std::move(JumpFailed); auto Index = llvm::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false); ModuleSummaryIndexBitcodeReader R(std::move(Stream), Strtab, *Index, @@ -5931,12 +6497,15 @@ Expected<std::unique_ptr<ModuleSummaryIndex>> BitcodeModule::getSummary() { static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, unsigned ID) { - if (Stream.EnterSubBlock(ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(ID)) + return std::move(Err); SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -5953,8 +6522,10 @@ static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, // Look for the FS_FLAGS record. Record.clear(); - auto BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (MaybeBitCode.get()) { default: // Default behavior: ignore. break; case bitc::FS_FLAGS: { // [flags] @@ -5972,13 +6543,17 @@ static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, // Check if the given bitcode buffer contains a global value summary block. Expected<BitcodeLTOInfo> BitcodeModule::getLTOInfo() { BitstreamCursor Stream(Buffer); - Stream.JumpToBit(ModuleBit); + if (Error JumpFailed = Stream.JumpToBit(ModuleBit)) + return std::move(JumpFailed); - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return std::move(Err); while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::Error: @@ -6007,13 +6582,15 @@ Expected<BitcodeLTOInfo> BitcodeModule::getLTOInfo() { } // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); continue; case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; + if (Expected<unsigned> StreamFailed = Stream.skipRecord(Entry.ID)) + continue; + else + return StreamFailed.takeError(); } } } |