diff --git a/hpvm/llvm_patches/lib/Bitcode/Reader/BitcodeReader.cpp b/hpvm/llvm_patches/lib/Bitcode/Reader/BitcodeReader.cpp index ba22f47cd7dcdac82491bcd1e65a9aec58297470..c6530f992bab22d36a1273f1b1c454970270c928 100644 --- a/hpvm/llvm_patches/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/hpvm/llvm_patches/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1,52 +1,50 @@ //===- 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 // //===----------------------------------------------------------------------===// #include "llvm/Bitcode/BitcodeReader.h" #include "MetadataLoader.h" #include "ValueList.h" - #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #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" #include "llvm/IR/Attributes.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/BasicBlock.h" -#include "llvm/IR/CallingConv.h" #include "llvm/IR/CallSite.h" +#include "llvm/IR/CallingConv.h" #include "llvm/IR/Comdat.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/DiagnosticInfo.h" -#include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/Function.h" +#include "llvm/IR/GVMaterializer.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalIFunc.h" #include "llvm/IR/GlobalIndirectSymbol.h" #include "llvm/IR/GlobalObject.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalVariable.h" -#include "llvm/IR/GVMaterializer.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/InstrTypes.h" @@ -54,13 +52,12 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/ModuleSummaryIndex.h" -#include "llvm/IR/OperandTraits.h" #include "llvm/IR/Operator.h" -#include "llvm/IR/TrackingMDRef.h" #include "llvm/IR/Type.h" -#include "llvm/IR/ValueHandle.h" +#include "llvm/IR/Value.h" #include "llvm/IR/Verifier.h" #include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Casting.h" @@ -69,7 +66,9 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> @@ -77,9 +76,9 @@ #include <cstddef> #include <cstdint> #include <deque> -#include <limits> #include <map> #include <memory> +#include <set> #include <string> #include <system_error> #include <tuple> @@ -99,26 +98,35 @@ enum { SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex }; -Error error(const Twine &Message) { +} // end anonymous namespace + +static Error error(const Twine &Message) { return make_error<StringError>( Message, make_error_code(BitcodeError::CorruptedBitcode)); } -/// Helper to read the header common to all bitcode files. -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(); } -Expected<BitstreamCursor> initStream(MemoryBufferRef Buffer) { +static Expected<BitstreamCursor> initStream(MemoryBufferRef Buffer) { const unsigned char *BufPtr = (const unsigned char *)Buffer.getBufferStart(); const unsigned char *BufEnd = BufPtr + Buffer.getBufferSize(); @@ -132,8 +140,8 @@ 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); } @@ -151,7 +159,7 @@ static bool convertToString(ArrayRef<uint64_t> Record, unsigned Idx, } // Strip all the TBAA attachment for the module. -void stripTBAA(Module *M) { +static void stripTBAA(Module *M) { for (auto &F : *M) { if (F.isMaterializable()) continue; @@ -162,9 +170,9 @@ 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. -Expected<std::string> readIdentificationBlock(BitstreamCursor &Stream) { - if (Stream.EnterSubBlock(bitc::IDENTIFICATION_BLOCK_ID)) - return error("Invalid record"); +static Expected<std::string> readIdentificationBlock(BitstreamCursor &Stream) { + if (Error Err = Stream.EnterSubBlock(bitc::IDENTIFICATION_BLOCK_ID)) + return std::move(Err); // Read all the records. SmallVector<uint64_t, 64> Record; @@ -172,7 +180,11 @@ 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: @@ -187,8 +199,10 @@ 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] @@ -206,14 +220,19 @@ Expected<std::string> readIdentificationBlock(BitstreamCursor &Stream) { } } -Expected<std::string> readIdentificationCode(BitstreamCursor &Stream) { +static Expected<std::string> readIdentificationCode(BitstreamCursor &Stream) { // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. while (true) { 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: @@ -224,25 +243,30 @@ 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(); } } } -Expected<bool> hasObjCCategoryInModule(BitstreamCursor &Stream) { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); +static Expected<bool> hasObjCCategoryInModule(BitstreamCursor &Stream) { + 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. @@ -256,7 +280,10 @@ 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] @@ -264,7 +291,7 @@ Expected<bool> hasObjCCategoryInModule(BitstreamCursor &Stream) { if (convertToString(Record, 0, S)) return error("Invalid record"); // Check for the i386 and other (x86_64, ARM) conventions - if (S.find("__DATA, __objc_catlist") != std::string::npos || + if (S.find("__DATA,__objc_catlist") != std::string::npos || S.find("__OBJC,__category") != std::string::npos) return true; break; @@ -275,11 +302,15 @@ Expected<bool> hasObjCCategoryInModule(BitstreamCursor &Stream) { llvm_unreachable("Exit infinite loop"); } -Expected<bool> hasObjCCategory(BitstreamCursor &Stream) { +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: @@ -292,20 +323,22 @@ 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(); } } } -Expected<std::string> readModuleTriple(BitstreamCursor &Stream) { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); +static Expected<std::string> readModuleTriple(BitstreamCursor &Stream) { + if (Error Err = Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return std::move(Err); SmallVector<uint64_t, 64> Record; @@ -313,7 +346,10 @@ 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. @@ -327,7 +363,10 @@ 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; @@ -342,11 +381,14 @@ Expected<std::string> readModuleTriple(BitstreamCursor &Stream) { llvm_unreachable("Exit infinite loop"); } -Expected<std::string> readTriple(BitstreamCursor &Stream) { +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: @@ -359,25 +401,43 @@ 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(); } } } +namespace { + class BitcodeReaderBase { protected: - BitcodeReaderBase(BitstreamCursor Stream) : Stream(std::move(Stream)) { + BitcodeReaderBase(BitstreamCursor Stream, StringRef Strtab) + : Stream(std::move(Stream)), Strtab(Strtab) { this->Stream.setBlockInfo(&BlockInfo); } BitstreamBlockInfo BlockInfo; BitstreamCursor Stream; + StringRef Strtab; + + /// In version 2 of the bitcode we store names of global values and comdats in + /// a string table rather than in the VST. + bool UseStrtab = false; + + Expected<unsigned> parseVersionRecord(ArrayRef<uint64_t> Record); + + /// If this module uses a string table, pop the reference to the string table + /// and return the referenced string and the rest of the record. Otherwise + /// just return the record itself. + std::pair<StringRef, ArrayRef<uint64_t>> + readNameFromStrtab(ArrayRef<uint64_t> Record); bool readBlockInfo(); @@ -387,6 +447,8 @@ protected: Error error(const Twine &Message); }; +} // end anonymous namespace + Error BitcodeReaderBase::error(const Twine &Message) { std::string FullMsg = Message.str(); if (!ProducerIdentification.empty()) @@ -395,6 +457,29 @@ Error BitcodeReaderBase::error(const Twine &Message) { return ::error(FullMsg); } +Expected<unsigned> +BitcodeReaderBase::parseVersionRecord(ArrayRef<uint64_t> Record) { + if (Record.empty()) + return error("Invalid record"); + unsigned ModuleVersion = Record[0]; + if (ModuleVersion > 2) + return error("Invalid value"); + UseStrtab = ModuleVersion >= 2; + return ModuleVersion; +} + +std::pair<StringRef, ArrayRef<uint64_t>> +BitcodeReaderBase::readNameFromStrtab(ArrayRef<uint64_t> Record) { + if (!UseStrtab) + return {"", Record}; + // Invalid reference. Let the caller complain about the record being empty. + if (Record[0] + Record[1] > Strtab.size()) + return {"", {}}; + return {StringRef(Strtab.data() + Record[0], Record[1]), Record.slice(2)}; +} + +namespace { + class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { LLVMContext &Context; Module *TheModule = nullptr; @@ -405,24 +490,28 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { bool SeenValueSymbolTable = false; uint64_t VSTOffset = 0; + std::vector<std::string> SectionTable; + std::vector<std::string> GCTable; + std::vector<Type*> TypeList; + DenseMap<Function *, FunctionType *> FunctionTypes; BitcodeReaderValueList ValueList; Optional<MetadataLoader> MDLoader; std::vector<Comdat *> ComdatList; SmallVector<Instruction *, 64> InstructionList; - std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits; - std::vector<std::pair<GlobalIndirectSymbol*, unsigned> > IndirectSymbolInits; - std::vector<std::pair<Function*, unsigned> > FunctionPrefixes; - std::vector<std::pair<Function*, unsigned> > FunctionPrologues; - std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFns; + std::vector<std::pair<GlobalVariable *, unsigned>> GlobalInits; + std::vector<std::pair<GlobalIndirectSymbol *, unsigned>> IndirectSymbolInits; + std::vector<std::pair<Function *, unsigned>> FunctionPrefixes; + std::vector<std::pair<Function *, unsigned>> FunctionPrologues; + std::vector<std::pair<Function *, unsigned>> FunctionPersonalityFns; /// The set of attributes by index. Index zero in the file is for null, and /// is thus not represented here. As such all indices are off by one. - std::vector<AttributeSet> MAttributes; + std::vector<AttributeList> MAttributes; /// The set of attribute groups. - std::map<unsigned, AttributeSet> MAttributeGroups; + std::map<unsigned, AttributeList> MAttributeGroups; /// While parsing a function body, this is a list of the basic blocks for the /// function. @@ -434,7 +523,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { // When intrinsic functions are encountered which require upgrading they are // stored here with their replacement function. - typedef DenseMap<Function*, Function*> UpdatedIntrinsicMap; + using UpdatedIntrinsicMap = DenseMap<Function *, Function *>; UpdatedIntrinsicMap UpgradedIntrinsics; // Intrinsics which were remangled because of types rename UpdatedIntrinsicMap RemangledIntrinsics; @@ -475,10 +564,11 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { TBAAVerifier TBAAVerifyHelper; std::vector<std::string> BundleTags; + SmallVector<SyncScope::ID, 8> SSIDs; public: - BitcodeReader(BitstreamCursor Stream, StringRef ProducerIdentification, - LLVMContext &Context); + BitcodeReader(BitstreamCursor Stream, StringRef Strtab, + StringRef ProducerIdentification, LLVMContext &Context); Error materializeForwardReferencedFunctions(); @@ -486,7 +576,7 @@ public: Error materializeModule() override; std::vector<StructType *> getIdentifiedStructTypes() const override; - /// \brief Main interface to parsing a bitcode buffer. + /// Main interface to parsing a bitcode buffer. /// \returns true if an error occurred. Error parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata = false, bool IsImporting = false); @@ -503,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)); + } + + /// Return the flattened type (suitable for use in a Value) + /// specified by the given \param ID . + Type *getTypeByID(unsigned ID) { + return flattenPointerTypes(getFullyStructuredTypeByID(ID)); + } - Value *getFnValueByID(unsigned ID, Type *Ty) { + /// 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) { @@ -520,17 +640,18 @@ private: return FunctionBBs[ID]; } - AttributeSet getAttributes(unsigned i) const { + AttributeList getAttributes(unsigned i) const { if (i-1 < MAttributes.size()) return MAttributes[i-1]; - return AttributeSet(); + return AttributeList(); } /// Read a value/type pair out of the specified record from slot 'Slot'. /// 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. @@ -539,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()) @@ -547,6 +668,8 @@ private: unsigned TypeNo = (unsigned)Record[Slot++]; ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo)); + if (FullTy) + *FullTy = getFullyStructuredTypeByID(TypeNo); return ResVal == nullptr; } @@ -592,21 +715,36 @@ 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. Error parseAlignmentValue(uint64_t Exponent, unsigned &Alignment); Error parseAttrKind(uint64_t Code, Attribute::AttrKind *Kind); Error parseModule(uint64_t ResumeBit, bool ShouldLazyLoadMetadata = false); + + Error parseComdatRecord(ArrayRef<uint64_t> Record); + Error parseGlobalVarRecord(ArrayRef<uint64_t> Record); + Error parseFunctionRecord(ArrayRef<uint64_t> Record); + Error parseGlobalIndirectSymbolRecord(unsigned BitCode, + ArrayRef<uint64_t> Record); + Error parseAttributeBlock(); Error parseAttributeGroupBlock(); Error parseTypeTable(); Error parseTypeTableBody(); Error parseOperandBundleTags(); + Error parseSyncScopeNames(); Expected<Value *> recordValue(SmallVectorImpl<uint64_t> &Record, unsigned NameIndex, Triple &TT); + void setDeferredFunctionInfo(unsigned FuncBitcodeOffsetDelta, Function *F, + ArrayRef<uint64_t> Record); Error parseValueSymbolTable(uint64_t Offset = 0); + Error parseGlobalValueSymbolTable(); Error parseConstants(); Error rememberAndSkipFunctionBodies(); Error rememberAndSkipFunctionBody(); @@ -620,6 +758,8 @@ private: Error findFunctionInStream( Function *F, DenseMap<Function *, uint64_t>::iterator DeferredFunctionInfoIterator); + + SyncScope::ID getDecodedSyncScopeID(unsigned Val); }; /// Class to manage reading and parsing function summary index bitcode @@ -639,15 +779,16 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase { /// Used to enable on-demand parsing of the VST. uint64_t VSTOffset = 0; - // Map to save ValueId to GUID association that was recorded in the + // Map to save ValueId to ValueInfo association that was recorded in the // ValueSymbolTable. It is used after the VST is parsed to convert // call graph edges read from the function summary from referencing - // callees by their ValueId to using the GUID instead, which is how + // callees by their ValueId to using the ValueInfo instead, which is how // they are recorded in the summary index being built. - // We save a second GUID which is the same as the first one, but ignoring the - // linkage, i.e. for value other than local linkage they are identical. - DenseMap<unsigned, std::pair<GlobalValue::GUID, GlobalValue::GUID>> - ValueIdToCallGraphGUIDMap; + // We save a GUID which refers to the same global as the ValueInfo, but + // ignoring the linkage, i.e. for values other than local linkage they are + // identical. + DenseMap<unsigned, std::pair<ValueInfo, GlobalValue::GUID>> + ValueIdToValueInfoMap; /// Map populated during module path string table parsing, from the /// module ID to a string reference owned by the index's module @@ -658,25 +799,44 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase { /// Original source file name recorded in a bitcode record. std::string SourceFileName; + /// The string identifier given to this module by the client, normally the + /// path to the bitcode file. + StringRef ModulePath; + + /// For per-module summary indexes, the unique numerical identifier given to + /// this module by the client. + unsigned ModuleId; + public: - ModuleSummaryIndexBitcodeReader( - BitstreamCursor Stream, ModuleSummaryIndex &TheIndex); + ModuleSummaryIndexBitcodeReader(BitstreamCursor Stream, StringRef Strtab, + ModuleSummaryIndex &TheIndex, + StringRef ModulePath, unsigned ModuleId); - Error parseModule(StringRef ModulePath); + Error parseModule(); private: + void setValueGUID(uint64_t ValueID, StringRef ValueName, + GlobalValue::LinkageTypes Linkage, + StringRef SourceFileName); Error parseValueSymbolTable( uint64_t Offset, DenseMap<unsigned, GlobalValue::LinkageTypes> &ValueIdToLinkageMap); std::vector<ValueInfo> makeRefList(ArrayRef<uint64_t> Record); std::vector<FunctionSummary::EdgeTy> makeCallList(ArrayRef<uint64_t> Record, bool IsOldProfileFormat, - bool HasProfile); - Error parseEntireSummary(StringRef ModulePath); + bool HasProfile, + 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); - std::pair<GlobalValue::GUID, GlobalValue::GUID> - getGUIDFromValueId(unsigned ValueId); + void addThisModule(); + ModuleSummaryIndex::ModuleInfo *getThisModule(); }; } // end anonymous namespace @@ -694,11 +854,11 @@ std::error_code llvm::errorToErrorCodeAndEmitErrors(LLVMContext &Ctx, return std::error_code(); } -BitcodeReader::BitcodeReader(BitstreamCursor Stream, +BitcodeReader::BitcodeReader(BitstreamCursor Stream, StringRef Strtab, StringRef ProducerIdentification, LLVMContext &Context) - : BitcodeReaderBase(std::move(Stream)), Context(Context), - ValueList(Context) { + : BitcodeReaderBase(std::move(Stream), Strtab), Context(Context), + ValueList(Context, Stream.SizeInBytes()) { this->ProducerIdentification = ProducerIdentification; } @@ -793,6 +953,16 @@ static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) { } } +static FunctionSummary::FFlags getDecodedFFlags(uint64_t RawFlags) { + FunctionSummary::FFlags Flags; + Flags.ReadNone = RawFlags & 0x1; + Flags.ReadOnly = (RawFlags >> 1) & 0x1; + Flags.NoRecurse = (RawFlags >> 2) & 0x1; + Flags.ReturnDoesNotAlias = (RawFlags >> 3) & 0x1; + Flags.NoInline = (RawFlags >> 4) & 0x1; + return Flags; +} + /// Decode the flags for GlobalValue in the summary. static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags, uint64_t Version) { @@ -802,11 +972,20 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags, auto Linkage = GlobalValue::LinkageTypes(RawFlags & 0xF); // 4 bits RawFlags = RawFlags >> 4; bool NotEligibleToImport = (RawFlags & 0x1) || Version < 3; - // The LiveRoot flag wasn't introduced until version 3. For dead stripping + // The Live flag wasn't introduced until version 3. For dead stripping // to work correctly on earlier versions, we must conservatively treat all // values as live. - bool LiveRoot = (RawFlags & 0x2) || Version < 3; - return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, LiveRoot); + bool Live = (RawFlags & 0x2) || Version < 3; + bool Local = (RawFlags & 0x4); + bool AutoHide = (RawFlags & 0x8); + + 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, + (RawFlags & 0x2) ? true : false); } static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) { @@ -828,6 +1007,14 @@ getDecodedDLLStorageClass(unsigned Val) { } } +static bool getDecodedDSOLocal(unsigned Val) { + switch(Val) { + default: // Map unknown values to preemptable. + case 0: return false; + case 1: return true; + } +} + static GlobalVariable::ThreadLocalMode getDecodedThreadLocalMode(unsigned Val) { switch (Val) { case 0: return GlobalVariable::NotThreadLocal; @@ -867,6 +1054,20 @@ static int getDecodedCastOpcode(unsigned Val) { } } +static int getDecodedUnaryOpcode(unsigned Val, Type *Ty) { + bool IsFP = Ty->isFPOrFPVectorTy(); + // UnOps are only valid for int/fp or vector of int/fp types + if (!IsFP && !Ty->isIntOrIntVectorTy()) + return -1; + + switch (Val) { + default: + return -1; + case bitc::UNOP_NEG: + return IsFP ? Instruction::FNeg : -1; + } +} + static int getDecodedBinaryOpcode(unsigned Val, Type *Ty) { bool IsFP = Ty->isFPOrFPVectorTy(); // BinOps are only valid for int/fp or vector of int/fp types @@ -919,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; } } @@ -935,14 +1138,6 @@ static AtomicOrdering getDecodedOrdering(unsigned Val) { } } -static SynchronizationScope getDecodedSynchScope(unsigned Val) { - switch (Val) { - case bitc::SYNCHSCOPE_SINGLETHREAD: return SingleThread; - default: // Map unknown scopes to cross-thread. - case bitc::SYNCHSCOPE_CROSSTHREAD: return CrossThread; - } -} - static Comdat::SelectionKind getDecodedComdatSelectionKind(unsigned Val) { switch (Val) { default: // Map unknown selection kinds to any. @@ -961,16 +1156,22 @@ static Comdat::SelectionKind getDecodedComdatSelectionKind(unsigned Val) { static FastMathFlags getDecodedFastMathFlags(unsigned Val) { FastMathFlags FMF; - if (0 != (Val & FastMathFlags::UnsafeAlgebra)) - FMF.setUnsafeAlgebra(); - if (0 != (Val & FastMathFlags::NoNaNs)) + if (0 != (Val & bitc::UnsafeAlgebra)) + FMF.setFast(); + if (0 != (Val & bitc::AllowReassoc)) + FMF.setAllowReassoc(); + if (0 != (Val & bitc::NoNaNs)) FMF.setNoNaNs(); - if (0 != (Val & FastMathFlags::NoInfs)) + if (0 != (Val & bitc::NoInfs)) FMF.setNoInfs(); - if (0 != (Val & FastMathFlags::NoSignedZeros)) + if (0 != (Val & bitc::NoSignedZeros)) FMF.setNoSignedZeros(); - if (0 != (Val & FastMathFlags::AllowReciprocal)) + if (0 != (Val & bitc::AllowReciprocal)) FMF.setAllowReciprocal(); + if (0 != (Val & bitc::AllowContract)) + FMF.setAllowContract(true); + if (0 != (Val & bitc::ApproxFunc)) + FMF.setApproxFunc(); return FMF; } @@ -981,8 +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; @@ -1066,12 +1266,29 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) { case Attribute::SwiftSelf: return 1ULL << 51; case Attribute::SwiftError: return 1ULL << 52; case Attribute::WriteOnly: return 1ULL << 53; - - // VISC Attributes - case Attribute::In: return 1ULL << 54; - case Attribute::Out: return 1ULL << 55; - case Attribute::InOut: return 1ULL << 56; - + case Attribute::Speculatable: return 1ULL << 54; + case Attribute::StrictFP: return 1ULL << 55; + case Attribute::SanitizeHWAddress: return 1ULL << 56; + case Attribute::NoCfCheck: return 1ULL << 57; + case Attribute::OptForFuzzing: return 1ULL << 58; + 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; + + // VISC Attributes + case Attribute::In: return 3ULL << 0; + case Attribute::Out: return 3ULL << 1; + case Attribute::InOut: return 3ULL << 2; + + 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; @@ -1085,6 +1302,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"); } @@ -1094,10 +1314,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) @@ -1110,7 +1332,7 @@ static void addRawAttributeValue(AttrBuilder &B, uint64_t Val) { } } -/// \brief This fills an AttrBuilder object with the LLVM attributes that have +/// This fills an AttrBuilder object with the LLVM attributes that have /// been decoded from the given integer. This function must stay in sync with /// 'encodeLLVMAttributesForBitcode'. static void decodeLLVMAttributesForBitcode(AttrBuilder &B, @@ -1130,19 +1352,22 @@ 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"); SmallVector<uint64_t, 64> Record; - SmallVector<AttributeSet, 8> Attrs; + SmallVector<AttributeList, 8> Attrs; // 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. @@ -1157,10 +1382,13 @@ 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, ...] + case bitc::PARAMATTR_CODE_ENTRY_OLD: // ENTRY: [paramidx0, attr0, ...] // FIXME: Remove in 4.0. if (Record.size() & 1) return error("Invalid record"); @@ -1168,22 +1396,20 @@ Error BitcodeReader::parseAttributeBlock() { for (unsigned i = 0, e = Record.size(); i != e; i += 2) { AttrBuilder B; decodeLLVMAttributesForBitcode(B, Record[i+1]); - Attrs.push_back(AttributeSet::get(Context, Record[i], B)); + Attrs.push_back(AttributeList::get(Context, Record[i], B)); } - MAttributes.push_back(AttributeSet::get(Context, Attrs)); + MAttributes.push_back(AttributeList::get(Context, Attrs)); Attrs.clear(); break; - } - case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [attrgrp0, attrgrp1, ...] + case bitc::PARAMATTR_CODE_ENTRY: // ENTRY: [attrgrp0, attrgrp1, ...] for (unsigned i = 0, e = Record.size(); i != e; ++i) Attrs.push_back(MAttributeGroups[Record[i]]); - MAttributes.push_back(AttributeSet::get(Context, Attrs)); + MAttributes.push_back(AttributeList::get(Context, Attrs)); Attrs.clear(); break; } - } } } @@ -1232,6 +1458,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: @@ -1252,8 +1480,14 @@ 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: return Attribute::NoUnwind; + case bitc::ATTR_KIND_OPT_FOR_FUZZING: + return Attribute::OptForFuzzing; case bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE: return Attribute::OptimizeForSize; case bitc::ATTR_KIND_OPTIMIZE_NONE: @@ -1268,6 +1502,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::ReturnsTwice; case bitc::ATTR_KIND_S_EXT: return Attribute::SExt; + case bitc::ATTR_KIND_SPECULATABLE: + return Attribute::Speculatable; case bitc::ATTR_KIND_STACK_ALIGNMENT: return Attribute::StackAlignment; case bitc::ATTR_KIND_STACK_PROTECT: @@ -1278,24 +1514,38 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::StackProtectStrong; case bitc::ATTR_KIND_SAFESTACK: return Attribute::SafeStack; + case bitc::ATTR_KIND_SHADOWCALLSTACK: + return Attribute::ShadowCallStack; + case bitc::ATTR_KIND_STRICT_FP: + return Attribute::StrictFP; case bitc::ATTR_KIND_STRUCT_RET: return Attribute::StructRet; case bitc::ATTR_KIND_SANITIZE_ADDRESS: return Attribute::SanitizeAddress; + case bitc::ATTR_KIND_SANITIZE_HWADDRESS: + return Attribute::SanitizeHWAddress; case bitc::ATTR_KIND_SANITIZE_THREAD: return Attribute::SanitizeThread; case bitc::ATTR_KIND_SANITIZE_MEMORY: return Attribute::SanitizeMemory; + case bitc::ATTR_KIND_SPECULATIVE_LOAD_HARDENING: + return Attribute::SpeculativeLoadHardening; case bitc::ATTR_KIND_SWIFT_ERROR: return Attribute::SwiftError; case bitc::ATTR_KIND_SWIFT_SELF: 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; } } @@ -1317,8 +1567,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"); @@ -1327,7 +1577,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. @@ -1342,7 +1595,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, ...] @@ -1359,6 +1615,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; @@ -1374,9 +1636,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; @@ -1394,10 +1654,19 @@ 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); } } - MAttributeGroups[GrpID] = AttributeSet::get(Context, Idx, B); + MAttributeGroups[GrpID] = AttributeList::get(Context, Idx, B); break; } } @@ -1405,8 +1674,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(); } @@ -1422,7 +1691,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. @@ -1440,7 +1712,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] @@ -1625,7 +1900,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) @@ -1633,7 +1909,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; } @@ -1648,8 +1925,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"); @@ -1657,7 +1934,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. @@ -1672,7 +1952,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] @@ -1683,6 +1966,51 @@ Error BitcodeReader::parseOperandBundleTags() { } } +Error BitcodeReader::parseSyncScopeNames() { + 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) { + 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: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + if (SSIDs.empty()) + return error("Invalid empty synchronization scope names block"); + return Error::success(); + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Synchronization scope names are implicitly mapped to synchronization + // scope IDs by their order. + + 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; + if (convertToString(Record, 0, SSN)) + return error("Invalid record"); + + SSIDs.push_back(Context.getOrInsertSyncScopeID(SSN)); + Record.clear(); + } +} + /// Associate a value with its name from the given index in the provided record. Expected<Value *> BitcodeReader::recordValue(SmallVectorImpl<uint64_t> &Record, unsigned NameIndex, Triple &TT) { @@ -1701,10 +2029,10 @@ Expected<Value *> BitcodeReader::recordValue(SmallVectorImpl<uint64_t> &Record, auto *GO = dyn_cast<GlobalObject>(V); if (GO) { if (GO->getComdat() == reinterpret_cast<Comdat *>(1)) { - if (TT.isOSBinFormatMachO()) - GO->setComdat(nullptr); - else + if (TT.supportsCOMDAT()) GO->setComdat(TheModule->getOrInsertComdat(V->getName())); + else + GO->setComdat(nullptr); } } return V; @@ -1712,25 +2040,75 @@ 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; } +void BitcodeReader::setDeferredFunctionInfo(unsigned FuncBitcodeOffsetDelta, + Function *F, + ArrayRef<uint64_t> Record) { + // Note that we subtract 1 here because the offset is relative to one word + // before the start of the identification or module block, which was + // historically always the start of the regular bitcode header. + uint64_t FuncWordOffset = Record[1] - 1; + uint64_t FuncBitOffset = FuncWordOffset * 32; + DeferredFunctionInfo[F] = FuncBitOffset + FuncBitcodeOffsetDelta; + // Set the LastFunctionBlockBit to point to the last function block. + // Later when parsing is resumed after function materialization, + // we can simply skip that last function block. + if (FuncBitOffset > LastFunctionBlockBit) + LastFunctionBlockBit = FuncBitOffset; +} + +/// Read a new-style GlobalValue symbol table. +Error BitcodeReader::parseGlobalValueSymbolTable() { + unsigned FuncBitcodeOffsetDelta = + Stream.getAbbrevIDWidth() + bitc::BlockIDWidth; + + if (Error Err = Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) + return Err; + + SmallVector<uint64_t, 64> Record; + while (true) { + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return Error::success(); + case BitstreamEntry::Record: + break; + } + + Record.clear(); + 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); + break; + } + } +} + /// Parse the value symbol table at either the current parsing location or /// at the given bit offset if provided. Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { @@ -1738,8 +2116,22 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { // Pass in the Offset to distinguish between calling for the module-level // 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); + if (Offset > 0) { + 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; + 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, + // and will contain symbol names. + } // Compute the delta between the bitcode indices in the VST (the word offset // to the word-aligned ENTER_SUBBLOCK for the function block, and that @@ -1755,8 +2147,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; @@ -1766,7 +2158,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. @@ -1774,7 +2169,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. @@ -1783,7 +2179,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] @@ -1800,29 +2199,10 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { return Err; Value *V = ValOrErr.get(); - auto *GO = dyn_cast<GlobalObject>(V); - if (!GO) { - // If this is an alias, need to get the actual Function object - // it aliases, in order to set up the DeferredFunctionInfo entry below. - auto *GA = dyn_cast<GlobalAlias>(V); - if (GA) - GO = GA->getBaseObject(); - assert(GO); - } - - // Note that we subtract 1 here because the offset is relative to one word - // before the start of the identification or module block, which was - // historically always the start of the regular bitcode header. - uint64_t FuncWordOffset = Record[1] - 1; - Function *F = dyn_cast<Function>(GO); - assert(F); - uint64_t FuncBitOffset = FuncWordOffset * 32; - DeferredFunctionInfo[F] = FuncBitOffset + FuncBitcodeOffsetDelta; - // Set the LastFunctionBlockBit to point to the last function block. - // Later when parsing is resumed after function materialization, - // we can simply skip that last function block. - if (FuncBitOffset > LastFunctionBlockBit) - LastFunctionBlockBit = FuncBitOffset; + // Ignore function offsets emitted for aliases of functions in older + // versions of LLVM. + if (auto *F = dyn_cast<Function>(V)) + setDeferredFunctionInfo(FuncBitcodeOffsetDelta, F, Record); break; } case bitc::VST_CODE_BBENTRY: { @@ -1853,12 +2233,12 @@ uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) { /// Resolve all of the initializers for global values and aliases that we can. Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() { - std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist; - std::vector<std::pair<GlobalIndirectSymbol*, unsigned> > + std::vector<std::pair<GlobalVariable *, unsigned>> GlobalInitWorklist; + std::vector<std::pair<GlobalIndirectSymbol *, unsigned>> IndirectSymbolInitWorklist; - std::vector<std::pair<Function*, unsigned> > FunctionPrefixWorklist; - std::vector<std::pair<Function*, unsigned> > FunctionPrologueWorklist; - std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFnWorklist; + std::vector<std::pair<Function *, unsigned>> FunctionPrefixWorklist; + std::vector<std::pair<Function *, unsigned>> FunctionPrologueWorklist; + std::vector<std::pair<Function *, unsigned>> FunctionPersonalityFnWorklist; GlobalInitWorklist.swap(GlobalInits); IndirectSymbolInitWorklist.swap(IndirectSymbolInits); @@ -1947,17 +2327,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. @@ -1980,8 +2364,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); @@ -1993,7 +2379,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); @@ -2132,6 +2519,19 @@ Error BitcodeReader::parseConstants() { } break; } + case bitc::CST_CODE_CE_UNOP: { // CE_UNOP: [opcode, opval] + if (Record.size() < 2) + return error("Invalid record"); + int Opc = getDecodedUnaryOpcode(Record[0], CurTy); + if (Opc < 0) { + V = UndefValue::get(CurTy); // Unknown unop. + } else { + Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy); + unsigned Flags = 0; + V = ConstantExpr::get(Opc, LHS, Flags); + } + break; + } case bitc::CST_CODE_CE_BINOP: { // CE_BINOP: [opcode, opval, opval] if (Record.size() < 3) return error("Invalid record"); @@ -2199,23 +2599,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); @@ -2343,9 +2747,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); - V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack); + UpgradeInlineAsmString(&AsmStr); + V = InlineAsm::get( + cast<FunctionType>(getPointerElementFlatType(CurFullTy)), AsmStr, + ConstrStr, HasSideEffects, IsAlignStack); break; } // This version adds support for the asm dialect keywords (e.g., @@ -2368,10 +2773,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); - V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack, - InlineAsm::AsmDialect(AsmDialect)); + UpgradeInlineAsmString(&AsmStr); + V = InlineAsm::get( + cast<FunctionType>(getPointerElementFlatType(CurFullTy)), AsmStr, + ConstrStr, HasSideEffects, IsAlignStack, + InlineAsm::AsmDialect(AsmDialect)); break; } case bitc::CST_CODE_BLOCKADDRESS:{ @@ -2417,20 +2823,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. @@ -2446,7 +2857,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: @@ -2495,18 +2909,29 @@ 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; } + + // Upgrade "Linker Options" module flag to "llvm.linker.options" module-level + // metadata. + if (Metadata *Val = TheModule->getModuleFlag("Linker Options")) { + NamedMDNode *LinkerOpts = + TheModule->getOrInsertNamedMetadata("llvm.linker.options"); + for (const MDOperand &MDOptions : cast<MDNode>(Val)->operands()) + LinkerOpts->addOperand(cast<MDNode>(MDOptions)); + } + DeferredMetadataInfo.clear(); return Error::success(); } @@ -2531,8 +2956,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(); } @@ -2545,6 +2970,7 @@ Error BitcodeReader::globalCleanup() { // Look for intrinsic functions which need to be upgraded at some point for (Function &F : *TheModule) { + MDLoader->upgradeDebugIntrinsics(F); Function *NewFn; if (UpgradeIntrinsicFunction(&F, NewFn)) UpgradedIntrinsics[&F] = NewFn; @@ -2556,13 +2982,19 @@ 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. - std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits); - std::vector<std::pair<GlobalIndirectSymbol*, unsigned> >().swap( + std::vector<std::pair<GlobalVariable *, unsigned>>().swap(GlobalInits); + std::vector<std::pair<GlobalIndirectSymbol *, unsigned>>().swap( IndirectSymbolInits); return Error::success(); } @@ -2572,7 +3004,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"); @@ -2587,7 +3020,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"); @@ -2606,73 +3043,428 @@ 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); return false; } -Error BitcodeReader::parseModule(uint64_t ResumeBit, - bool ShouldLazyLoadMetadata) { - if (ResumeBit) - Stream.JumpToBit(ResumeBit); - else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) +Error BitcodeReader::parseComdatRecord(ArrayRef<uint64_t> Record) { + // v1: [selection_kind, name] + // v2: [strtab_offset, strtab_size, selection_kind] + StringRef Name; + std::tie(Name, Record) = readNameFromStrtab(Record); + + if (Record.empty()) return error("Invalid record"); + Comdat::SelectionKind SK = getDecodedComdatSelectionKind(Record[0]); + std::string OldFormatName; + if (!UseStrtab) { + if (Record.size() < 2) + return error("Invalid record"); + unsigned ComdatNameSize = Record[1]; + OldFormatName.reserve(ComdatNameSize); + for (unsigned i = 0; i != ComdatNameSize; ++i) + OldFormatName += (char)Record[2 + i]; + Name = OldFormatName; + } + Comdat *C = TheModule->getOrInsertComdat(Name); + C->setSelectionKind(SK); + ComdatList.push_back(C); + return Error::success(); +} - SmallVector<uint64_t, 64> Record; - std::vector<std::string> SectionTable; - std::vector<std::string> GCTable; +static void inferDSOLocal(GlobalValue *GV) { + // infer dso_local from linkage and visibility if it is not encoded. + if (GV->hasLocalLinkage() || + (!GV->hasDefaultVisibility() && !GV->hasExternalWeakLinkage())) + GV->setDSOLocal(true); +} - // Read all the records for this module. - while (true) { - BitstreamEntry Entry = Stream.advance(); +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, + // partition strtab offset, partition strtab size] (name in VST) + // v2: [strtab_offset, strtab_size, v1] + StringRef Name; + std::tie(Name, Record) = readNameFromStrtab(Record); - switch (Entry.Kind) { - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return globalCleanup(); + if (Record.size() < 6) + return error("Invalid record"); + Type *FullTy = getFullyStructuredTypeByID(Record[0]); + Type *Ty = flattenPointerTypes(FullTy); + if (!Ty) + return error("Invalid record"); + bool isConstant = Record[1] & 1; + bool explicitType = Record[1] & 2; + unsigned AddressSpace; + if (explicitType) { + AddressSpace = Record[1] >> 2; + } else { + if (!Ty->isPointerTy()) + return error("Invalid type for value"); + AddressSpace = cast<PointerType>(Ty)->getAddressSpace(); + std::tie(FullTy, Ty) = getPointerElementTypes(FullTy); + } - case BitstreamEntry::SubBlock: - switch (Entry.ID) { - default: // Skip unknown content. - if (Stream.SkipBlock()) - return error("Invalid record"); - break; - case bitc::BLOCKINFO_BLOCK_ID: - if (readBlockInfo()) - return error("Malformed block"); - break; - case bitc::PARAMATTR_BLOCK_ID: - if (Error Err = parseAttributeBlock()) - return Err; - break; - case bitc::PARAMATTR_GROUP_BLOCK_ID: - if (Error Err = parseAttributeGroupBlock()) - return Err; - break; - case bitc::TYPE_BLOCK_ID_NEW: - if (Error Err = parseTypeTable()) - return Err; - break; - case bitc::VALUE_SYMTAB_BLOCK_ID: - if (!SeenValueSymbolTable) { - // Either this is an old form VST without function index and an - // associated VST forward declaration record (which would have caused - // the VST to be jumped to and parsed before it was encountered - // normally in the stream), or there were no function blocks to - // trigger an earlier parsing of the VST. - assert(VSTOffset == 0 || FunctionsWithBodies.empty()); - if (Error Err = parseValueSymbolTable()) - return Err; + uint64_t RawLinkage = Record[3]; + GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage); + unsigned Alignment; + if (Error Err = parseAlignmentValue(Record[4], Alignment)) + return Err; + std::string Section; + if (Record[5]) { + if (Record[5] - 1 >= SectionTable.size()) + return error("Invalid ID"); + Section = SectionTable[Record[5] - 1]; + } + GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility; + // Local linkage must have default visibility. + if (Record.size() > 6 && !GlobalValue::isLocalLinkage(Linkage)) + // FIXME: Change to an error if non-default in 4.0. + Visibility = getDecodedVisibility(Record[6]); + + GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal; + if (Record.size() > 7) + TLM = getDecodedThreadLocalMode(Record[7]); + + GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None; + if (Record.size() > 8) + UnnamedAddr = getDecodedUnnamedAddrType(Record[8]); + + bool ExternallyInitialized = false; + if (Record.size() > 9) + ExternallyInitialized = Record[9]; + + GlobalVariable *NewGV = + new GlobalVariable(*TheModule, Ty, isConstant, Linkage, nullptr, Name, + nullptr, TLM, AddressSpace, ExternallyInitialized); + NewGV->setAlignment(Alignment); + if (!Section.empty()) + NewGV->setSection(Section); + NewGV->setVisibility(Visibility); + NewGV->setUnnamedAddr(UnnamedAddr); + + if (Record.size() > 10) + NewGV->setDLLStorageClass(getDecodedDLLStorageClass(Record[10])); + else + upgradeDLLImportExportLinkage(NewGV, RawLinkage); + + 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]) + GlobalInits.push_back(std::make_pair(NewGV, InitID - 1)); + + if (Record.size() > 11) { + if (unsigned ComdatID = Record[11]) { + if (ComdatID > ComdatList.size()) + return error("Invalid global variable comdat ID"); + NewGV->setComdat(ComdatList[ComdatID - 1]); + } + } else if (hasImplicitComdat(RawLinkage)) { + NewGV->setComdat(reinterpret_cast<Comdat *>(1)); + } + + if (Record.size() > 12) { + auto AS = getAttributes(Record[12]).getFnAttributes(); + NewGV->setAttributes(AS); + } + + if (Record.size() > 13) { + NewGV->setDSOLocal(getDecodedDSOLocal(Record[13])); + } + 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(); +} + +Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { + // v1: [type, callingconv, isproto, linkage, paramattr, alignment, section, + // visibility, gc, unnamed_addr, prologuedata, dllstorageclass, comdat, + // prefixdata, personalityfn, preemption specifier, addrspace] (name in VST) + // v2: [strtab_offset, strtab_size, v1] + StringRef Name; + std::tie(Name, Record) = readNameFromStrtab(Record); + + if (Record.size() < 8) + return error("Invalid record"); + 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) + return error("Invalid calling convention ID"); + + unsigned AddrSpace = TheModule->getDataLayout().getProgramAddressSpace(); + if (Record.size() > 16) + AddrSpace = Record[16]; + + 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]; + uint64_t RawLinkage = Record[3]; + 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; + Func->setAlignment(Alignment); + if (Record[6]) { + if (Record[6] - 1 >= SectionTable.size()) + return error("Invalid ID"); + Func->setSection(SectionTable[Record[6] - 1]); + } + // Local linkage must have default visibility. + if (!Func->hasLocalLinkage()) + // FIXME: Change to an error if non-default in 4.0. + Func->setVisibility(getDecodedVisibility(Record[7])); + if (Record.size() > 8 && Record[8]) { + if (Record[8] - 1 >= GCTable.size()) + return error("Invalid ID"); + Func->setGC(GCTable[Record[8] - 1]); + } + GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None; + if (Record.size() > 9) + UnnamedAddr = getDecodedUnnamedAddrType(Record[9]); + Func->setUnnamedAddr(UnnamedAddr); + if (Record.size() > 10 && Record[10] != 0) + FunctionPrologues.push_back(std::make_pair(Func, Record[10] - 1)); + + if (Record.size() > 11) + Func->setDLLStorageClass(getDecodedDLLStorageClass(Record[11])); + else + upgradeDLLImportExportLinkage(Func, RawLinkage); + + if (Record.size() > 12) { + if (unsigned ComdatID = Record[12]) { + if (ComdatID > ComdatList.size()) + return error("Invalid function comdat ID"); + Func->setComdat(ComdatList[ComdatID - 1]); + } + } else if (hasImplicitComdat(RawLinkage)) { + Func->setComdat(reinterpret_cast<Comdat *>(1)); + } + + if (Record.size() > 13 && Record[13] != 0) + FunctionPrefixes.push_back(std::make_pair(Func, Record[13] - 1)); + + if (Record.size() > 14 && Record[14] != 0) + FunctionPersonalityFns.push_back(std::make_pair(Func, Record[14] - 1)); + + if (Record.size() > 15) { + Func->setDSOLocal(getDecodedDSOLocal(Record[15])); + } + inferDSOLocal(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. + if (!isProto) { + Func->setIsMaterializable(true); + FunctionsWithBodies.push_back(Func); + DeferredFunctionInfo[Func] = 0; + } + return Error::success(); +} + +Error BitcodeReader::parseGlobalIndirectSymbolRecord( + unsigned BitCode, ArrayRef<uint64_t> Record) { + // v1 ALIAS_OLD: [alias type, aliasee val#, linkage] (name in VST) + // v1 ALIAS: [alias type, addrspace, aliasee val#, linkage, visibility, + // dllstorageclass, threadlocal, unnamed_addr, + // preemption specifier] (name in VST) + // v1 IFUNC: [alias type, addrspace, aliasee val#, linkage, + // visibility, dllstorageclass, threadlocal, unnamed_addr, + // preemption specifier] (name in VST) + // v2: [strtab_offset, strtab_size, v1] + StringRef Name; + std::tie(Name, Record) = readNameFromStrtab(Record); + + bool NewRecord = BitCode != bitc::MODULE_CODE_ALIAS_OLD; + if (Record.size() < (3 + (unsigned)NewRecord)) + return error("Invalid record"); + unsigned OpNum = 0; + Type *FullTy = getFullyStructuredTypeByID(Record[OpNum++]); + Type *Ty = flattenPointerTypes(FullTy); + if (!Ty) + return error("Invalid record"); + + unsigned AddrSpace; + if (!NewRecord) { + auto *PTy = dyn_cast<PointerType>(Ty); + if (!PTy) + return error("Invalid type for value"); + std::tie(FullTy, Ty) = getPointerElementTypes(FullTy); + AddrSpace = PTy->getAddressSpace(); + } else { + AddrSpace = Record[OpNum++]; + } + + auto Val = Record[OpNum++]; + auto Linkage = Record[OpNum++]; + GlobalIndirectSymbol *NewGA; + if (BitCode == bitc::MODULE_CODE_ALIAS || + BitCode == bitc::MODULE_CODE_ALIAS_OLD) + NewGA = GlobalAlias::create(Ty, AddrSpace, getDecodedLinkage(Linkage), Name, + TheModule); + 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()) { + auto VisInd = OpNum++; + if (!NewGA->hasLocalLinkage()) + // FIXME: Change to an error if non-default in 4.0. + NewGA->setVisibility(getDecodedVisibility(Record[VisInd])); + } + if (BitCode == bitc::MODULE_CODE_ALIAS || + BitCode == bitc::MODULE_CODE_ALIAS_OLD) { + if (OpNum != Record.size()) + NewGA->setDLLStorageClass(getDecodedDLLStorageClass(Record[OpNum++])); + else + upgradeDLLImportExportLinkage(NewGA, Linkage); + if (OpNum != Record.size()) + NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[OpNum++])); + if (OpNum != Record.size()) + NewGA->setUnnamedAddr(getDecodedUnnamedAddrType(Record[OpNum++])); + } + if (OpNum != Record.size()) + NewGA->setDSOLocal(getDecodedDSOLocal(Record[OpNum++])); + inferDSOLocal(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) { + 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) { + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); + + switch (Entry.Kind) { + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return globalCleanup(); + + case BitstreamEntry::SubBlock: + switch (Entry.ID) { + default: // Skip unknown content. + if (Error Err = Stream.SkipBlock()) + return Err; + break; + case bitc::BLOCKINFO_BLOCK_ID: + if (readBlockInfo()) + return error("Malformed block"); + break; + case bitc::PARAMATTR_BLOCK_ID: + if (Error Err = parseAttributeBlock()) + return Err; + break; + case bitc::PARAMATTR_GROUP_BLOCK_ID: + if (Error Err = parseAttributeGroupBlock()) + return Err; + break; + case bitc::TYPE_BLOCK_ID_NEW: + if (Error Err = parseTypeTable()) + return Err; + break; + case bitc::VALUE_SYMTAB_BLOCK_ID: + if (!SeenValueSymbolTable) { + // Either this is an old form VST without function index and an + // associated VST forward declaration record (which would have caused + // the VST to be jumped to and parsed before it was encountered + // normally in the stream), or there were no function blocks to + // trigger an earlier parsing of the VST. + assert(VSTOffset == 0 || FunctionsWithBodies.empty()); + if (Error Err = parseValueSymbolTable()) + return Err; SeenValueSymbolTable = true; } else { // 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: @@ -2724,8 +3516,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; } } @@ -2756,6 +3548,10 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, if (Error Err = parseOperandBundleTags()) return Err; break; + case bitc::SYNC_SCOPE_NAMES_BLOCK_ID: + if (Error Err = parseSyncScopeNames()) + return Err; + break; } continue; @@ -2765,24 +3561,16 @@ 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: { // VERSION: [version#] - if (Record.size() < 1) - return error("Invalid record"); - // Only version #0 and #1 are supported so far. - unsigned module_version = Record[0]; - switch (module_version) { - default: - return error("Invalid value"); - case 0: - UseRelativeIDs = false; - break; - case 1: - UseRelativeIDs = true; - break; - } + case bitc::MODULE_CODE_VERSION: { + Expected<unsigned> VersionOrErr = parseVersionRecord(Record); + if (!VersionOrErr) + return VersionOrErr.takeError(); + UseRelativeIDs = *VersionOrErr >= 1; break; } case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] @@ -2828,248 +3616,23 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, GCTable.push_back(S); break; } - case bitc::MODULE_CODE_COMDAT: { // COMDAT: [selection_kind, name] - if (Record.size() < 2) - return error("Invalid record"); - Comdat::SelectionKind SK = getDecodedComdatSelectionKind(Record[0]); - unsigned ComdatNameSize = Record[1]; - std::string ComdatName; - ComdatName.reserve(ComdatNameSize); - for (unsigned i = 0; i != ComdatNameSize; ++i) - ComdatName += (char)Record[2 + i]; - Comdat *C = TheModule->getOrInsertComdat(ComdatName); - C->setSelectionKind(SK); - ComdatList.push_back(C); - break; - } - // GLOBALVAR: [pointer type, isconst, initid, - // linkage, alignment, section, visibility, threadlocal, - // unnamed_addr, externally_initialized, dllstorageclass, - // comdat] - case bitc::MODULE_CODE_GLOBALVAR: { - if (Record.size() < 6) - return error("Invalid record"); - Type *Ty = getTypeByID(Record[0]); - if (!Ty) - return error("Invalid record"); - bool isConstant = Record[1] & 1; - bool explicitType = Record[1] & 2; - unsigned AddressSpace; - if (explicitType) { - AddressSpace = Record[1] >> 2; - } else { - if (!Ty->isPointerTy()) - return error("Invalid type for value"); - AddressSpace = cast<PointerType>(Ty)->getAddressSpace(); - Ty = cast<PointerType>(Ty)->getElementType(); - } - - uint64_t RawLinkage = Record[3]; - GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage); - unsigned Alignment; - if (Error Err = parseAlignmentValue(Record[4], Alignment)) + case bitc::MODULE_CODE_COMDAT: + if (Error Err = parseComdatRecord(Record)) return Err; - std::string Section; - if (Record[5]) { - if (Record[5]-1 >= SectionTable.size()) - return error("Invalid ID"); - Section = SectionTable[Record[5]-1]; - } - GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility; - // Local linkage must have default visibility. - if (Record.size() > 6 && !GlobalValue::isLocalLinkage(Linkage)) - // FIXME: Change to an error if non-default in 4.0. - Visibility = getDecodedVisibility(Record[6]); - - GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal; - if (Record.size() > 7) - TLM = getDecodedThreadLocalMode(Record[7]); - - GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None; - if (Record.size() > 8) - UnnamedAddr = getDecodedUnnamedAddrType(Record[8]); - - bool ExternallyInitialized = false; - if (Record.size() > 9) - ExternallyInitialized = Record[9]; - - GlobalVariable *NewGV = - new GlobalVariable(*TheModule, Ty, isConstant, Linkage, nullptr, "", nullptr, - TLM, AddressSpace, ExternallyInitialized); - NewGV->setAlignment(Alignment); - if (!Section.empty()) - NewGV->setSection(Section); - NewGV->setVisibility(Visibility); - NewGV->setUnnamedAddr(UnnamedAddr); - - if (Record.size() > 10) - NewGV->setDLLStorageClass(getDecodedDLLStorageClass(Record[10])); - else - upgradeDLLImportExportLinkage(NewGV, RawLinkage); - - ValueList.push_back(NewGV); - - // Remember which value to use for the global initializer. - if (unsigned InitID = Record[2]) - GlobalInits.push_back(std::make_pair(NewGV, InitID-1)); - - if (Record.size() > 11) { - if (unsigned ComdatID = Record[11]) { - if (ComdatID > ComdatList.size()) - return error("Invalid global variable comdat ID"); - NewGV->setComdat(ComdatList[ComdatID - 1]); - } - } else if (hasImplicitComdat(RawLinkage)) { - NewGV->setComdat(reinterpret_cast<Comdat *>(1)); - } - break; - } - // FUNCTION: [type, callingconv, isproto, linkage, paramattr, - // alignment, section, visibility, gc, unnamed_addr, - // prologuedata, dllstorageclass, comdat, prefixdata] - case bitc::MODULE_CODE_FUNCTION: { - 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); - if (!FTy) - return error("Invalid type for value"); - auto CC = static_cast<CallingConv::ID>(Record[1]); - if (CC & ~CallingConv::MaxID) - return error("Invalid calling convention ID"); - - Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage, - "", TheModule); - - Func->setCallingConv(CC); - bool isProto = Record[2]; - uint64_t RawLinkage = Record[3]; - Func->setLinkage(getDecodedLinkage(RawLinkage)); - Func->setAttributes(getAttributes(Record[4])); - - unsigned Alignment; - if (Error Err = parseAlignmentValue(Record[5], Alignment)) + case bitc::MODULE_CODE_GLOBALVAR: + if (Error Err = parseGlobalVarRecord(Record)) + return Err; + break; + case bitc::MODULE_CODE_FUNCTION: + if (Error Err = parseFunctionRecord(Record)) return Err; - Func->setAlignment(Alignment); - if (Record[6]) { - if (Record[6]-1 >= SectionTable.size()) - return error("Invalid ID"); - Func->setSection(SectionTable[Record[6]-1]); - } - // Local linkage must have default visibility. - if (!Func->hasLocalLinkage()) - // FIXME: Change to an error if non-default in 4.0. - Func->setVisibility(getDecodedVisibility(Record[7])); - if (Record.size() > 8 && Record[8]) { - if (Record[8]-1 >= GCTable.size()) - return error("Invalid ID"); - Func->setGC(GCTable[Record[8] - 1]); - } - GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None; - if (Record.size() > 9) - UnnamedAddr = getDecodedUnnamedAddrType(Record[9]); - Func->setUnnamedAddr(UnnamedAddr); - if (Record.size() > 10 && Record[10] != 0) - FunctionPrologues.push_back(std::make_pair(Func, Record[10]-1)); - - if (Record.size() > 11) - Func->setDLLStorageClass(getDecodedDLLStorageClass(Record[11])); - else - upgradeDLLImportExportLinkage(Func, RawLinkage); - - if (Record.size() > 12) { - if (unsigned ComdatID = Record[12]) { - if (ComdatID > ComdatList.size()) - return error("Invalid function comdat ID"); - Func->setComdat(ComdatList[ComdatID - 1]); - } - } else if (hasImplicitComdat(RawLinkage)) { - Func->setComdat(reinterpret_cast<Comdat *>(1)); - } - - if (Record.size() > 13 && Record[13] != 0) - FunctionPrefixes.push_back(std::make_pair(Func, Record[13]-1)); - - if (Record.size() > 14 && Record[14] != 0) - FunctionPersonalityFns.push_back(std::make_pair(Func, Record[14] - 1)); - - ValueList.push_back(Func); - - // 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. - if (!isProto) { - Func->setIsMaterializable(true); - FunctionsWithBodies.push_back(Func); - DeferredFunctionInfo[Func] = 0; - } break; - } - // ALIAS: [alias type, addrspace, aliasee val#, linkage] - // ALIAS: [alias type, addrspace, aliasee val#, linkage, visibility, dllstorageclass] - // IFUNC: [alias type, addrspace, aliasee val#, linkage, visibility, dllstorageclass] case bitc::MODULE_CODE_IFUNC: case bitc::MODULE_CODE_ALIAS: - case bitc::MODULE_CODE_ALIAS_OLD: { - bool NewRecord = BitCode != bitc::MODULE_CODE_ALIAS_OLD; - if (Record.size() < (3 + (unsigned)NewRecord)) - return error("Invalid record"); - unsigned OpNum = 0; - Type *Ty = getTypeByID(Record[OpNum++]); - if (!Ty) - return error("Invalid record"); - - unsigned AddrSpace; - if (!NewRecord) { - auto *PTy = dyn_cast<PointerType>(Ty); - if (!PTy) - return error("Invalid type for value"); - Ty = PTy->getElementType(); - AddrSpace = PTy->getAddressSpace(); - } else { - AddrSpace = Record[OpNum++]; - } - - auto Val = Record[OpNum++]; - auto Linkage = Record[OpNum++]; - GlobalIndirectSymbol *NewGA; - if (BitCode == bitc::MODULE_CODE_ALIAS || - BitCode == bitc::MODULE_CODE_ALIAS_OLD) - NewGA = GlobalAlias::create(Ty, AddrSpace, getDecodedLinkage(Linkage), - "", TheModule); - else - NewGA = GlobalIFunc::create(Ty, AddrSpace, getDecodedLinkage(Linkage), - "", nullptr, TheModule); - // Old bitcode files didn't have visibility field. - // Local linkage must have default visibility. - if (OpNum != Record.size()) { - auto VisInd = OpNum++; - if (!NewGA->hasLocalLinkage()) - // FIXME: Change to an error if non-default in 4.0. - NewGA->setVisibility(getDecodedVisibility(Record[VisInd])); - } - if (OpNum != Record.size()) - NewGA->setDLLStorageClass(getDecodedDLLStorageClass(Record[OpNum++])); - else - upgradeDLLImportExportLinkage(NewGA, Linkage); - if (OpNum != Record.size()) - NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[OpNum++])); - if (OpNum != Record.size()) - NewGA->setUnnamedAddr(getDecodedUnnamedAddrType(Record[OpNum++])); - ValueList.push_back(NewGA); - IndirectSymbolInits.push_back(std::make_pair(NewGA, Val)); - break; - } - /// MODULE_CODE_PURGEVALS: [numvals] - case bitc::MODULE_CODE_PURGEVALS: - // Trim down the value list to the specified size. - if (Record.size() < 1 || Record[0] > ValueList.size()) - return error("Invalid record"); - ValueList.shrinkTo(Record[0]); + case bitc::MODULE_CODE_ALIAS_OLD: + if (Error Err = parseGlobalIndirectSymbolRecord(BitCode, Record)) + return Err; break; /// MODULE_CODE_VSTOFFSET: [offset] case bitc::MODULE_CODE_VSTOFFSET: @@ -3100,7 +3663,6 @@ Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata, return parseModule(0, ShouldLazyLoadMetadata); } - Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) { if (!isa<PointerType>(PtrType)) return error("Load/Store operand is not a pointer type"); @@ -3114,10 +3676,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()) @@ -3128,9 +3703,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; @@ -3151,7 +3730,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: @@ -3162,8 +3744,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()) @@ -3199,8 +3781,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] @@ -3256,24 +3841,47 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned Line = Record[0], Col = Record[1]; unsigned ScopeID = Record[2], IAID = Record[3]; + bool isImplicitCode = Record.size() == 5 && Record[4]; MDNode *Scope = nullptr, *IA = nullptr; if (ScopeID) { - Scope = MDLoader->getMDNodeFwdRefOrNull(ScopeID - 1); + Scope = dyn_cast_or_null<MDNode>( + MDLoader->getMetadataFwdRefOrLoad(ScopeID - 1)); if (!Scope) return error("Invalid record"); } if (IAID) { - IA = MDLoader->getMDNodeFwdRefOrNull(IAID - 1); + IA = dyn_cast_or_null<MDNode>( + MDLoader->getMetadataFwdRefOrLoad(IAID - 1)); if (!IA) return error("Invalid record"); } - LastLoc = DebugLoc::get(Line, Col, Scope, IA); + LastLoc = DebugLoc::get(Line, Col, Scope, IA, isImplicitCode); I->setDebugLoc(LastLoc); I = nullptr; continue; } + case bitc::FUNC_CODE_INST_UNOP: { // UNOP: [opval, ty, opcode] + unsigned OpNum = 0; + Value *LHS; + if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || + OpNum+1 > Record.size()) + return error("Invalid record"); + int Opc = getDecodedUnaryOpcode(Record[OpNum++], LHS->getType()); + if (Opc == -1) + return error("Invalid record"); + I = UnaryOperator::Create((Instruction::UnaryOps)Opc, LHS); + InstructionList.push_back(I); + if (OpNum < Record.size()) { + if (isa<FPMathOperator>(I)) { + FastMathFlags FMF = getDecodedFastMathFlags(Record[OpNum]); + if (FMF.any()) + I->setFastMathFlags(FMF); + } + } + break; + } case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opval, ty, opval, opcode] unsigned OpNum = 0; Value *LHS, *RHS; @@ -3318,7 +3926,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"); @@ -3347,22 +3956,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"); @@ -3375,6 +3984,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx); + FullTy = GetElementPtrInst::getGEPReturnType(FullTy, I, GEPIdx); InstructionList.push_back(I); if (InBounds) @@ -3386,7 +3996,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(); @@ -3394,26 +4004,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->subtypes().size()) + 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->subtypes()[Index]; + FullTy = FullTy->getStructElementType(Index); else - CurTy = CurTy->subtypes()[0]; + FullTy = FullTy->getArrayElementType(); } I = ExtractValueInst::Create(Agg, EXTRACTVALIdx); @@ -3425,7 +4034,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)) @@ -3446,16 +4055,16 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("INSERTVAL: Invalid type"); if ((unsigned)Index != Index) return error("Invalid value"); - if (IsStruct && Index >= CurTy->subtypes().size()) + if (IsStruct && Index >= CurTy->getStructNumElements()) return error("INSERTVAL: Invalid struct index"); if (IsArray && Index >= CurTy->getArrayNumElements()) return error("INSERTVAL: Invalid array index"); INSERTVALIdx.push_back((unsigned)Index); if (IsStruct) - CurTy = CurTy->subtypes()[Index]; + CurTy = CurTy->getStructElementType(Index); else - CurTy = CurTy->subtypes()[0]; + CurTy = CurTy->getArrayElementType(); } if (CurTy != Val->getType()) @@ -3471,7 +4080,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"); @@ -3486,7 +4095,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"); @@ -3505,18 +4114,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; } @@ -3524,7 +4139,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"); @@ -3540,7 +4155,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"); @@ -3549,6 +4164,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; } @@ -3566,6 +4183,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; @@ -3846,37 +4467,46 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (Record.size() < 4) return error("Invalid record"); unsigned OpNum = 0; - AttributeSet PAL = getAttributes(Record[OpNum++]); + AttributeList PAL = getAttributes(Record[OpNum++]); unsigned CCInfo = Record[OpNum++]; BasicBlock *NormalBB = getBasicBlock(Record[OpNum++]); 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"); } @@ -3888,18 +4518,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] @@ -3911,6 +4547,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); @@ -3918,7 +4630,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"); @@ -3955,7 +4668,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) { @@ -4008,12 +4722,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); @@ -4023,51 +4738,66 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } if (!Ty || !Size) return error("Invalid record"); - AllocaInst *AI = new AllocaInst(Ty, Size, Align); + + // FIXME: Make this an optional field. + const DataLayout &DL = TheModule->getDataLayout(); + unsigned AS = DL.getAllocaAddrSpace(); + + AllocaInst *AI = new AllocaInst(Ty, AS, Size, Align); 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; } case bitc::FUNC_CODE_INST_LOADATOMIC: { - // LOADATOMIC: [opty, op, align, vol, ordering, synchscope] + // 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 || @@ -4076,13 +4806,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("Invalid record"); if (Ordering != AtomicOrdering::NotAtomic && Record[OpNum] == 0) return error("Invalid record"); - SynchronizationScope SynchScope = getDecodedSynchScope(Record[OpNum + 3]); + SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 3]); unsigned Align; if (Error Err = parseAlignmentValue(Record[OpNum], Align)) return Err; - I = new LoadInst(Op, "", Record[OpNum+1], Align, Ordering, SynchScope); - + I = new LoadInst(Ty, Op, "", Record[OpNum + 1], Align, Ordering, SSID); InstructionList.push_back(I); break; } @@ -4090,12 +4819,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"); @@ -4110,16 +4839,16 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } case bitc::FUNC_CODE_INST_STOREATOMIC: case bitc::FUNC_CODE_INST_STOREATOMIC_OLD: { - // STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, synchscope] + // 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"); @@ -4130,37 +4859,47 @@ Error BitcodeReader::parseFunctionBody(Function *F) { Ordering == AtomicOrdering::Acquire || Ordering == AtomicOrdering::AcquireRelease) return error("Invalid record"); - SynchronizationScope SynchScope = getDecodedSynchScope(Record[OpNum + 3]); + SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 3]); if (Ordering != AtomicOrdering::NotAtomic && Record[OpNum] == 0) return error("Invalid record"); unsigned Align; if (Error Err = parseAlignmentValue(Record[OpNum], Align)) return Err; - I = new StoreInst(Val, Ptr, Record[OpNum+1], Align, Ordering, SynchScope); + I = new StoreInst(Val, Ptr, Record[OpNum+1], Align, Ordering, SSID); InstructionList.push_back(I); break; } case bitc::FUNC_CODE_INST_CMPXCHG_OLD: case bitc::FUNC_CODE_INST_CMPXCHG: { - // CMPXCHG:[ptrty, ptr, cmp, new, vol, successordering, synchscope, + // CMPXCHG:[ptrty, ptr, cmp, new, vol, successordering, ssid, // 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) return error("Invalid record"); - SynchronizationScope SynchScope = getDecodedSynchScope(Record[OpNum + 2]); + SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 2]); if (Error Err = typeCheckLoadStoreInst(Cmp->getType(), Ptr->getType())) return Err; @@ -4172,7 +4911,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { FailureOrdering = getDecodedOrdering(Record[OpNum + 3]); I = new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering, FailureOrdering, - SynchScope); + SSID); + FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)}); cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]); if (Record.size() < 8) { @@ -4181,6 +4921,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]); } @@ -4189,14 +4930,14 @@ Error BitcodeReader::parseFunctionBody(Function *F) { break; } case bitc::FUNC_CODE_INST_ATOMICRMW: { - // ATOMICRMW:[ptrty, ptr, val, op, vol, ordering, synchscope] + // 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 || @@ -4206,13 +4947,14 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (Ordering == AtomicOrdering::NotAtomic || Ordering == AtomicOrdering::Unordered) return error("Invalid record"); - SynchronizationScope SynchScope = getDecodedSynchScope(Record[OpNum + 3]); - I = new AtomicRMWInst(Operation, Ptr, Val, Ordering, SynchScope); + 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; } - case bitc::FUNC_CODE_INST_FENCE: { // FENCE:[ordering, synchscope] + case bitc::FUNC_CODE_INST_FENCE: { // FENCE:[ordering, ssid] if (2 != Record.size()) return error("Invalid record"); AtomicOrdering Ordering = getDecodedOrdering(Record[0]); @@ -4220,8 +4962,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { Ordering == AtomicOrdering::Unordered || Ordering == AtomicOrdering::Monotonic) return error("Invalid record"); - SynchronizationScope SynchScope = getDecodedSynchScope(Record[1]); - I = new FenceInst(Context, Ordering, SynchScope); + SyncScope::ID SSID = getDecodedSyncScopeID(Record[1]); + I = new FenceInst(Context, Ordering, SSID); InstructionList.push_back(I); break; } @@ -4231,7 +4973,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("Invalid record"); unsigned OpNum = 0; - AttributeSet PAL = getAttributes(Record[OpNum++]); + AttributeList PAL = getAttributes(Record[OpNum++]); unsigned CCInfo = Record[OpNum++]; FastMathFlags FMF; @@ -4242,28 +4984,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()) @@ -4271,6 +5021,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"); } @@ -4282,13 +5033,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( @@ -4302,6 +5056,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 " @@ -4315,7 +5070,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); @@ -4349,24 +5105,39 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // Add instruction to end of current BB. If there is no current BB, reject // this file. if (!CurBB) { - delete I; + I->deleteValue(); return error("Invalid instruction with no BB"); } if (!OperandBundles.empty()) { - delete I; + I->deleteValue(); return error("Operand bundles found with no consumer"); } CurBB->getInstList().push_back(I); // If this was a terminator instruction, move to the next block. - if (isa<TerminatorInst>(I)) { + if (I->isTerminator()) { ++CurBBNo; CurBB = CurBBNo < FunctionBBs.size() ? FunctionBBs[CurBBNo] : nullptr; } // 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: @@ -4417,6 +5188,14 @@ Error BitcodeReader::findFunctionInStream( return Error::success(); } +SyncScope::ID BitcodeReader::getDecodedSyncScopeID(unsigned Val) { + if (Val == SyncScope::SingleThread || Val == SyncScope::System) + return SyncScope::ID(Val); + if (Val >= SSIDs.size()) + return SyncScope::System; // Map unknown synchronization scopes to system. + return SSIDs[Val]; +} + //===----------------------------------------------------------------------===// // GVMaterializer implementation //===----------------------------------------------------------------------===// @@ -4440,8 +5219,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); @@ -4538,6 +5317,9 @@ Error BitcodeReader::materializeModule() { UpgradeDebugInfo(*TheModule); UpgradeModuleFlags(*TheModule); + + UpgradeRetainReleaseMarker(*TheModule); + return Error::success(); } @@ -4546,14 +5328,48 @@ std::vector<StructType *> BitcodeReader::getIdentifiedStructTypes() const { } ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader( - BitstreamCursor Cursor, ModuleSummaryIndex &TheIndex) - : BitcodeReaderBase(std::move(Cursor)), TheIndex(TheIndex) {} - -std::pair<GlobalValue::GUID, GlobalValue::GUID> -ModuleSummaryIndexBitcodeReader::getGUIDFromValueId(unsigned ValueId) { - auto VGI = ValueIdToCallGraphGUIDMap.find(ValueId); - assert(VGI != ValueIdToCallGraphGUIDMap.end()); - return VGI->second; + BitstreamCursor Cursor, StringRef Strtab, ModuleSummaryIndex &TheIndex, + StringRef ModulePath, unsigned ModuleId) + : BitcodeReaderBase(std::move(Cursor), Strtab), TheIndex(TheIndex), + ModulePath(ModulePath), ModuleId(ModuleId) {} + +void ModuleSummaryIndexBitcodeReader::addThisModule() { + TheIndex.addModule(ModulePath, ModuleId); +} + +ModuleSummaryIndex::ModuleInfo * +ModuleSummaryIndexBitcodeReader::getThisModule() { + return TheIndex.getModule(ModulePath); +} + +std::pair<ValueInfo, GlobalValue::GUID> +ModuleSummaryIndexBitcodeReader::getValueInfoFromValueId(unsigned ValueId) { + auto VGI = ValueIdToValueInfoMap[ValueId]; + assert(VGI.first); + return VGI; +} + +void ModuleSummaryIndexBitcodeReader::setValueGUID( + uint64_t ValueID, StringRef ValueName, GlobalValue::LinkageTypes Linkage, + StringRef SourceFileName) { + std::string GlobalId = + GlobalValue::getGlobalIdentifier(ValueName, Linkage, SourceFileName); + auto ValueGUID = GlobalValue::getGUID(GlobalId); + auto OriginalNameID = ValueGUID; + if (GlobalValue::isLocalLinkage(Linkage)) + OriginalNameID = GlobalValue::getGUID(ValueName); + if (PrintSummaryGUIDs) + dbgs() << "GUID " << ValueGUID << "(" << OriginalNameID << ") is " + << ValueName << "\n"; + + // UseStrtab is false for legacy summary formats and value names are + // created on stack. In that case we save the name in a string saver in + // the index so that the value name can be recorded. + ValueIdToValueInfoMap[ValueID] = std::make_pair( + TheIndex.getOrInsertValueInfo( + ValueGUID, + UseStrtab ? ValueName : TheIndex.saveString(ValueName)), + OriginalNameID); } // Specialized value symbol table parser used when reading module index @@ -4562,11 +5378,18 @@ ModuleSummaryIndexBitcodeReader::getGUIDFromValueId(unsigned ValueId) { Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( uint64_t Offset, DenseMap<unsigned, GlobalValue::LinkageTypes> &ValueIdToLinkageMap) { + // With a strtab the VST is not required to parse the summary. + if (UseStrtab) + 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; @@ -4574,7 +5397,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. @@ -4582,7 +5408,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. @@ -4591,7 +5418,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] @@ -4603,17 +5433,7 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( assert(VLI != ValueIdToLinkageMap.end() && "No linkage found for VST entry?"); auto Linkage = VLI->second; - std::string GlobalId = - GlobalValue::getGlobalIdentifier(ValueName, Linkage, SourceFileName); - auto ValueGUID = GlobalValue::getGUID(GlobalId); - auto OriginalNameID = ValueGUID; - if (GlobalValue::isLocalLinkage(Linkage)) - OriginalNameID = GlobalValue::getGUID(ValueName); - if (PrintSummaryGUIDs) - dbgs() << "GUID " << ValueGUID << "(" << OriginalNameID << ") is " - << ValueName << "\n"; - ValueIdToCallGraphGUIDMap[ValueID] = - std::make_pair(ValueGUID, OriginalNameID); + setValueGUID(ValueID, ValueName, Linkage, SourceFileName); ValueName.clear(); break; } @@ -4627,18 +5447,7 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( assert(VLI != ValueIdToLinkageMap.end() && "No linkage found for VST entry?"); auto Linkage = VLI->second; - std::string FunctionGlobalId = GlobalValue::getGlobalIdentifier( - ValueName, VLI->second, SourceFileName); - auto FunctionGUID = GlobalValue::getGUID(FunctionGlobalId); - auto OriginalNameID = FunctionGUID; - if (GlobalValue::isLocalLinkage(Linkage)) - OriginalNameID = GlobalValue::getGUID(ValueName); - if (PrintSummaryGUIDs) - dbgs() << "GUID " << FunctionGUID << "(" << OriginalNameID << ") is " - << ValueName << "\n"; - ValueIdToCallGraphGUIDMap[ValueID] = - std::make_pair(FunctionGUID, OriginalNameID); - + setValueGUID(ValueID, ValueName, Linkage, SourceFileName); ValueName.clear(); break; } @@ -4648,7 +5457,8 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( GlobalValue::GUID RefGUID = Record[1]; // The "original name", which is the second value of the pair will be // overriden later by a FS_COMBINED_ORIGINAL_NAME in the combined index. - ValueIdToCallGraphGUIDMap[ValueID] = std::make_pair(RefGUID, RefGUID); + ValueIdToValueInfoMap[ValueID] = + std::make_pair(TheIndex.getOrInsertValueInfo(RefGUID), RefGUID); break; } } @@ -4658,9 +5468,9 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( // Parse just the blocks needed for building the index out of the module. // At the end of this routine the module Index is populated with a map // from global value id to GlobalValueSummary objects. -Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); +Error ModuleSummaryIndexBitcodeReader::parseModule() { + if (Error Err = Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; DenseMap<unsigned, GlobalValue::LinkageTypes> ValueIdToLinkageMap; @@ -4668,7 +5478,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) { // 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: @@ -4679,8 +5492,8 @@ Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) { 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) @@ -4693,10 +5506,14 @@ Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) { 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: + // Add the module if it is a per-module index (has a source file name). + if (!SourceFileName.empty()) + addThisModule(); assert(!SeenValueSymbolTable && "Already read VST when parsing summary block?"); // We might not have a VST if there were no values in the @@ -4709,7 +5526,7 @@ Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) { SeenValueSymbolTable = true; } SeenGlobalValSummary = true; - if (Error Err = parseEntireSummary(ModulePath)) + if (Error Err = parseEntireSummary(Entry.ID)) return Err; break; case bitc::MODULE_STRTAB_BLOCK_ID: @@ -4721,10 +5538,17 @@ Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) { 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: { + if (Error Err = parseVersionRecord(Record).takeError()) + return Err; + break; + } /// MODULE_CODE_SOURCE_FILENAME: [namechar x N] case bitc::MODULE_CODE_SOURCE_FILENAME: { SmallString<128> ValueName; @@ -4737,12 +5561,7 @@ Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) { case bitc::MODULE_CODE_HASH: { if (Record.size() != 5) return error("Invalid hash length " + Twine(Record.size()).str()); - if (TheIndex.modulePaths().empty()) - // We always seed the index with the module. - TheIndex.addModulePath(ModulePath, 0); - if (TheIndex.modulePaths().size() != 1) - return error("Don't expect multiple modules defined?"); - auto &Hash = TheIndex.modulePaths().begin()->second.second; + auto &Hash = getThisModule()->second.second; int Pos = 0; for (auto &Val : Record) { assert(!(Val >> 32) && "Unexpected high bits set"); @@ -4759,37 +5578,26 @@ Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) { // was historically always the start of the regular bitcode header. VSTOffset = Record[0] - 1; break; - // GLOBALVAR: [pointer type, isconst, initid, - // linkage, alignment, section, visibility, threadlocal, - // unnamed_addr, externally_initialized, dllstorageclass, - // comdat] - case bitc::MODULE_CODE_GLOBALVAR: { - if (Record.size() < 6) - return error("Invalid record"); - uint64_t RawLinkage = Record[3]; - GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage); - ValueIdToLinkageMap[ValueId++] = Linkage; - break; - } - // FUNCTION: [type, callingconv, isproto, linkage, paramattr, - // alignment, section, visibility, gc, unnamed_addr, - // prologuedata, dllstorageclass, comdat, prefixdata] - case bitc::MODULE_CODE_FUNCTION: { - if (Record.size() < 8) - return error("Invalid record"); - uint64_t RawLinkage = Record[3]; - GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage); - ValueIdToLinkageMap[ValueId++] = Linkage; - break; - } - // ALIAS: [alias type, addrspace, aliasee val#, linkage, visibility, - // dllstorageclass] + // v1 GLOBALVAR: [pointer type, isconst, initid, linkage, ...] + // v1 FUNCTION: [type, callingconv, isproto, linkage, ...] + // v1 ALIAS: [alias type, addrspace, aliasee val#, linkage, ...] + // v2: [strtab offset, strtab size, v1] + case bitc::MODULE_CODE_GLOBALVAR: + case bitc::MODULE_CODE_FUNCTION: case bitc::MODULE_CODE_ALIAS: { - if (Record.size() < 6) + StringRef Name; + ArrayRef<uint64_t> GVRecord; + std::tie(Name, GVRecord) = readNameFromStrtab(Record); + if (GVRecord.size() <= 3) return error("Invalid record"); - uint64_t RawLinkage = Record[3]; + uint64_t RawLinkage = GVRecord[3]; GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage); - ValueIdToLinkageMap[ValueId++] = Linkage; + if (!UseStrtab) { + ValueIdToLinkageMap[ValueId++] = Linkage; + break; + } + + setValueGUID(ValueId++, Name, Linkage, SourceFileName); break; } } @@ -4804,75 +5612,170 @@ ModuleSummaryIndexBitcodeReader::makeRefList(ArrayRef<uint64_t> Record) { std::vector<ValueInfo> Ret; Ret.reserve(Record.size()); for (uint64_t RefValueId : Record) - Ret.push_back(getGUIDFromValueId(RefValueId).first); + Ret.push_back(getValueInfoFromValueId(RefValueId).first); return Ret; } -std::vector<FunctionSummary::EdgeTy> ModuleSummaryIndexBitcodeReader::makeCallList( - ArrayRef<uint64_t> Record, bool IsOldProfileFormat, bool HasProfile) { +std::vector<FunctionSummary::EdgeTy> +ModuleSummaryIndexBitcodeReader::makeCallList(ArrayRef<uint64_t> Record, + bool IsOldProfileFormat, + bool HasProfile, bool HasRelBF) { std::vector<FunctionSummary::EdgeTy> Ret; Ret.reserve(Record.size()); for (unsigned I = 0, E = Record.size(); I != E; ++I) { CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown; - GlobalValue::GUID CalleeGUID = getGUIDFromValueId(Record[I]).first; + uint64_t RelBF = 0; + ValueInfo Callee = getValueInfoFromValueId(Record[I]).first; if (IsOldProfileFormat) { I += 1; // Skip old callsitecount field if (HasProfile) I += 1; // Skip old profilecount field } else if (HasProfile) Hotness = static_cast<CalleeInfo::HotnessType>(Record[++I]); - Ret.push_back(FunctionSummary::EdgeTy{CalleeGUID, CalleeInfo{Hotness}}); + else if (HasRelBF) + RelBF = Record[++I]; + Ret.push_back(FunctionSummary::EdgeTy{Callee, CalleeInfo(Hotness, RelBF)}); } return Ret; } +static void +parseWholeProgramDevirtResolutionByArg(ArrayRef<uint64_t> Record, size_t &Slot, + WholeProgramDevirtResolution &Wpd) { + uint64_t ArgNum = Record[Slot++]; + WholeProgramDevirtResolution::ByArg &B = + Wpd.ResByArg[{Record.begin() + Slot, Record.begin() + Slot + ArgNum}]; + Slot += ArgNum; + + B.TheKind = + static_cast<WholeProgramDevirtResolution::ByArg::Kind>(Record[Slot++]); + B.Info = Record[Slot++]; + B.Byte = Record[Slot++]; + B.Bit = Record[Slot++]; +} + +static void parseWholeProgramDevirtResolution(ArrayRef<uint64_t> Record, + StringRef Strtab, size_t &Slot, + TypeIdSummary &TypeId) { + uint64_t Id = Record[Slot++]; + WholeProgramDevirtResolution &Wpd = TypeId.WPDRes[Id]; + + Wpd.TheKind = static_cast<WholeProgramDevirtResolution::Kind>(Record[Slot++]); + Wpd.SingleImplName = {Strtab.data() + Record[Slot], + static_cast<size_t>(Record[Slot + 1])}; + Slot += 2; + + uint64_t ResByArgNum = Record[Slot++]; + for (uint64_t I = 0; I != ResByArgNum; ++I) + parseWholeProgramDevirtResolutionByArg(Record, Slot, Wpd); +} + +static void parseTypeIdSummaryRecord(ArrayRef<uint64_t> Record, + StringRef Strtab, + ModuleSummaryIndex &TheIndex) { + size_t Slot = 0; + TypeIdSummary &TypeId = TheIndex.getOrInsertTypeIdSummary( + {Strtab.data() + Record[Slot], static_cast<size_t>(Record[Slot + 1])}); + Slot += 2; + + TypeId.TTRes.TheKind = static_cast<TypeTestResolution::Kind>(Record[Slot++]); + TypeId.TTRes.SizeM1BitWidth = Record[Slot++]; + TypeId.TTRes.AlignLog2 = Record[Slot++]; + TypeId.TTRes.SizeM1 = Record[Slot++]; + TypeId.TTRes.BitMask = Record[Slot++]; + TypeId.TTRes.InlineBits = Record[Slot++]; + + while (Slot < Record.size()) + parseWholeProgramDevirtResolution(Record, Strtab, Slot, TypeId); +} + +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( - StringRef ModulePath) { - if (Stream.EnterSubBlock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID)) - return error("Invalid record"); +Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { + 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 > 3) + if (Version < 1 || Version > 7) return error("Invalid summary version " + Twine(Version) + - ", 1, 2 or 3 expected"); + ". Version should be in the range [1-7]."); Record.clear(); // Keep around the last seen summary to be used when we see an optional // "OriginalName" attachement. GlobalValueSummary *LastSeenSummary = nullptr; - bool Combined = false; + GlobalValue::GUID LastSeenGUID = 0; + + // We can expect to see any number of type ID information records before + // each function summary records; these variables store the information + // collected so far so that it can be used to create the summary object. std::vector<GlobalValue::GUID> PendingTypeTests; + std::vector<FunctionSummary::VFuncId> PendingTypeTestAssumeVCalls, + PendingTypeCheckedLoadVCalls; + std::vector<FunctionSummary::ConstVCall> PendingTypeTestAssumeConstVCalls, + 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. case BitstreamEntry::Error: return error("Malformed block"); case BitstreamEntry::EndBlock: - // For a per-module index, remove any entries that still have empty - // summaries. The VST parsing creates entries eagerly for all symbols, - // but not all have associated summaries (e.g. it doesn't know how to - // distinguish between VST_CODE_ENTRY for function declarations vs global - // variables with initializers that end up with a summary). Remove those - // entries now so that we don't need to rely on the combined index merger - // to clean them up (especially since that may not run for the first - // module's index if we merge into that). - if (!Combined) - TheIndex.removeEmptySummaryEntries(); return Error::success(); case BitstreamEntry::Record: // The interesting case. @@ -4887,45 +5790,112 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary( // 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; - // FS_PERMODULE: [valueid, flags, instcount, numrefs, numrefs x valueid, - // n x (valueid)] - // FS_PERMODULE_PROFILE: [valueid, flags, instcount, numrefs, + case bitc::FS_FLAGS: { // [flags] + uint64_t Flags = Record[0]; + // Scan flags. + assert(Flags <= 0x1f && "Unexpected bits in flag"); + + // 1 bit: WithGlobalValueDeadStripping flag. + // Set on combined index only. + if (Flags & 0x1) + TheIndex.setWithGlobalValueDeadStripping(); + // 1 bit: SkipModuleByDistributedBackend flag. + // Set on combined index only. + if (Flags & 0x2) + TheIndex.setSkipModuleByDistributedBackend(); + // 1 bit: HasSyntheticEntryCounts flag. + // Set on combined index only. + if (Flags & 0x4) + TheIndex.setHasSyntheticEntryCounts(); + // 1 bit: DisableSplitLTOUnit flag. + // Set on per module indexes. It is up to the client to validate + // the consistency of this flag across modules being linked. + if (Flags & 0x8) + TheIndex.setEnableSplitLTOUnit(); + // 1 bit: PartiallySplitLTOUnits flag. + // Set on combined index only. + if (Flags & 0x10) + TheIndex.setPartiallySplitLTOUnits(); + break; + } + case bitc::FS_VALUE_GUID: { // [valueid, refguid] + uint64_t ValueID = Record[0]; + GlobalValue::GUID RefGUID = Record[1]; + ValueIdToValueInfoMap[ValueID] = + std::make_pair(TheIndex.getOrInsertValueInfo(RefGUID), RefGUID); + break; + } + // FS_PERMODULE: [valueid, flags, instcount, fflags, numrefs, + // numrefs x valueid, n x (valueid)] + // FS_PERMODULE_PROFILE: [valueid, flags, instcount, fflags, numrefs, // numrefs x valueid, // n x (valueid, hotness)] + // FS_PERMODULE_RELBF: [valueid, flags, instcount, fflags, numrefs, + // numrefs x valueid, + // n x (valueid, relblockfreq)] case bitc::FS_PERMODULE: + case bitc::FS_PERMODULE_RELBF: case bitc::FS_PERMODULE_PROFILE: { unsigned ValueID = Record[0]; uint64_t RawFlags = Record[1]; unsigned InstCount = Record[2]; + uint64_t RawFunFlags = 0; unsigned NumRefs = Record[3]; + unsigned NumRORefs = 0, NumWORefs = 0; + int RefListStartIndex = 4; + if (Version >= 4) { + RawFunFlags = Record[3]; + NumRefs = Record[4]; + RefListStartIndex = 5; + if (Version >= 5) { + NumRORefs = Record[5]; + RefListStartIndex = 6; + if (Version >= 7) { + NumWORefs = Record[6]; + RefListStartIndex = 7; + } + } + } + auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); // The module path string ref set in the summary must be owned by the // index's module string table. Since we don't have a module path // string table section in the per-module index, we create a single // module path string table entry with an empty (0) ID to take // ownership. - static int RefListStartIndex = 4; int CallGraphEdgeStartIndex = RefListStartIndex + NumRefs; assert(Record.size() >= RefListStartIndex + NumRefs && "Record size inconsistent with number of references"); std::vector<ValueInfo> Refs = makeRefList( ArrayRef<uint64_t>(Record).slice(RefListStartIndex, NumRefs)); bool HasProfile = (BitCode == bitc::FS_PERMODULE_PROFILE); + bool HasRelBF = (BitCode == bitc::FS_PERMODULE_RELBF); std::vector<FunctionSummary::EdgeTy> Calls = makeCallList( ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex), - IsOldProfileFormat, HasProfile); + IsOldProfileFormat, HasProfile, HasRelBF); + setSpecialRefs(Refs, NumRORefs, NumWORefs); auto FS = llvm::make_unique<FunctionSummary>( - Flags, InstCount, std::move(Refs), std::move(Calls), - std::move(PendingTypeTests)); + Flags, InstCount, getDecodedFFlags(RawFunFlags), /*EntryCount=*/0, + std::move(Refs), std::move(Calls), std::move(PendingTypeTests), + std::move(PendingTypeTestAssumeVCalls), + std::move(PendingTypeCheckedLoadVCalls), + std::move(PendingTypeTestAssumeConstVCalls), + std::move(PendingTypeCheckedLoadConstVCalls)); PendingTypeTests.clear(); - auto GUID = getGUIDFromValueId(ValueID); - FS->setModulePath(TheIndex.addModulePath(ModulePath, 0)->first()); - FS->setOriginalName(GUID.second); - TheIndex.addGlobalValueSummary(GUID.first, std::move(FS)); + PendingTypeTestAssumeVCalls.clear(); + PendingTypeCheckedLoadVCalls.clear(); + PendingTypeTestAssumeConstVCalls.clear(); + PendingTypeCheckedLoadConstVCalls.clear(); + auto VIAndOriginalGUID = getValueInfoFromValueId(ValueID); + FS->setModulePath(getThisModule()->first()); + FS->setOriginalName(VIAndOriginalGUID.second); + TheIndex.addGlobalValueSummary(VIAndOriginalGUID.first, std::move(FS)); break; } // FS_ALIAS: [valueid, flags, valueid] @@ -4936,43 +5906,78 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary( uint64_t RawFlags = Record[1]; unsigned AliaseeID = Record[2]; auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); - auto AS = - llvm::make_unique<AliasSummary>(Flags, std::vector<ValueInfo>{}); + auto AS = llvm::make_unique<AliasSummary>(Flags); // The module path string ref set in the summary must be owned by the // index's module string table. Since we don't have a module path // string table section in the per-module index, we create a single // module path string table entry with an empty (0) ID to take // ownership. - AS->setModulePath(TheIndex.addModulePath(ModulePath, 0)->first()); + AS->setModulePath(getThisModule()->first()); - GlobalValue::GUID AliaseeGUID = getGUIDFromValueId(AliaseeID).first; - auto *AliaseeSummary = TheIndex.getGlobalValueSummary(AliaseeGUID); - if (!AliaseeSummary) + auto AliaseeVI = getValueInfoFromValueId(AliaseeID).first; + auto AliaseeInModule = TheIndex.findSummaryInModule(AliaseeVI, ModulePath); + if (!AliaseeInModule) return error("Alias expects aliasee summary to be parsed"); - AS->setAliasee(AliaseeSummary); + AS->setAliasee(AliaseeVI, AliaseeInModule); - auto GUID = getGUIDFromValueId(ValueID); + auto GUID = getValueInfoFromValueId(ValueID); AS->setOriginalName(GUID.second); TheIndex.addGlobalValueSummary(GUID.first, std::move(AS)); break; } - // FS_PERMODULE_GLOBALVAR_INIT_REFS: [valueid, flags, n x valueid] + // FS_PERMODULE_GLOBALVAR_INIT_REFS: [valueid, flags, varflags, n x valueid] case bitc::FS_PERMODULE_GLOBALVAR_INIT_REFS: { unsigned ValueID = Record[0]; uint64_t RawFlags = Record[1]; + unsigned RefArrayStart = 2; + GlobalVarSummary::GVarFlags GVF(/* ReadOnly */ false, + /* WriteOnly */ false); auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); + if (Version >= 5) { + GVF = getDecodedGVarFlags(Record[2]); + RefArrayStart = 3; + } std::vector<ValueInfo> Refs = - makeRefList(ArrayRef<uint64_t>(Record).slice(2)); - auto FS = llvm::make_unique<GlobalVarSummary>(Flags, std::move(Refs)); - FS->setModulePath(TheIndex.addModulePath(ModulePath, 0)->first()); - auto GUID = getGUIDFromValueId(ValueID); + makeRefList(ArrayRef<uint64_t>(Record).slice(RefArrayStart)); + auto FS = + llvm::make_unique<GlobalVarSummary>(Flags, GVF, std::move(Refs)); + FS->setModulePath(getThisModule()->first()); + auto GUID = getValueInfoFromValueId(ValueID); FS->setOriginalName(GUID.second); TheIndex.addGlobalValueSummary(GUID.first, std::move(FS)); break; } - // FS_COMBINED: [valueid, modid, flags, instcount, numrefs, + // 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, numrefs, + // FS_COMBINED_PROFILE: [valueid, modid, flags, instcount, fflags, numrefs, // numrefs x valueid, n x (valueid, hotness)] case bitc::FS_COMBINED: case bitc::FS_COMBINED_PROFILE: { @@ -4980,9 +5985,35 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary( uint64_t ModuleId = Record[1]; uint64_t RawFlags = Record[2]; unsigned InstCount = Record[3]; + uint64_t RawFunFlags = 0; + uint64_t EntryCount = 0; unsigned NumRefs = Record[4]; + unsigned NumRORefs = 0, NumWORefs = 0; + int RefListStartIndex = 5; + + if (Version >= 4) { + RawFunFlags = Record[4]; + 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; + } + } + NumRORefs = Record[RefListStartIndex - NumRORefsOffset]; + } + NumRefs = Record[NumRefsIndex]; + } + auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); - static int RefListStartIndex = 5; int CallGraphEdgeStartIndex = RefListStartIndex + NumRefs; assert(Record.size() >= RefListStartIndex + NumRefs && "Record size inconsistent with number of references"); @@ -4991,16 +6022,25 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary( bool HasProfile = (BitCode == bitc::FS_COMBINED_PROFILE); std::vector<FunctionSummary::EdgeTy> Edges = makeCallList( ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex), - IsOldProfileFormat, HasProfile); - GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first; + IsOldProfileFormat, HasProfile, false); + ValueInfo VI = getValueInfoFromValueId(ValueID).first; + setSpecialRefs(Refs, NumRORefs, NumWORefs); auto FS = llvm::make_unique<FunctionSummary>( - Flags, InstCount, std::move(Refs), std::move(Edges), - std::move(PendingTypeTests)); + Flags, InstCount, getDecodedFFlags(RawFunFlags), EntryCount, + std::move(Refs), std::move(Edges), std::move(PendingTypeTests), + std::move(PendingTypeTestAssumeVCalls), + std::move(PendingTypeCheckedLoadVCalls), + std::move(PendingTypeTestAssumeConstVCalls), + std::move(PendingTypeCheckedLoadConstVCalls)); PendingTypeTests.clear(); + PendingTypeTestAssumeVCalls.clear(); + PendingTypeCheckedLoadVCalls.clear(); + PendingTypeTestAssumeConstVCalls.clear(); + PendingTypeCheckedLoadConstVCalls.clear(); LastSeenSummary = FS.get(); + LastSeenGUID = VI.getGUID(); FS->setModulePath(ModuleIdMap[ModuleId]); - TheIndex.addGlobalValueSummary(GUID, std::move(FS)); - Combined = true; + TheIndex.addGlobalValueSummary(VI, std::move(FS)); break; } // FS_COMBINED_ALIAS: [valueid, modid, flags, valueid] @@ -5012,20 +6052,17 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary( uint64_t RawFlags = Record[2]; unsigned AliaseeValueId = Record[3]; auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); - auto AS = llvm::make_unique<AliasSummary>(Flags, std::vector<ValueInfo>{}); + auto AS = llvm::make_unique<AliasSummary>(Flags); LastSeenSummary = AS.get(); AS->setModulePath(ModuleIdMap[ModuleId]); - auto AliaseeGUID = getGUIDFromValueId(AliaseeValueId).first; - auto AliaseeInModule = - TheIndex.findSummaryInModule(AliaseeGUID, AS->modulePath()); - if (!AliaseeInModule) - return error("Alias expects aliasee summary to be parsed"); - AS->setAliasee(AliaseeInModule); + auto AliaseeVI = getValueInfoFromValueId(AliaseeValueId).first; + auto AliaseeInModule = TheIndex.findSummaryInModule(AliaseeVI, AS->modulePath()); + AS->setAliasee(AliaseeVI, AliaseeInModule); - GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first; - TheIndex.addGlobalValueSummary(GUID, std::move(AS)); - Combined = true; + ValueInfo VI = getValueInfoFromValueId(ValueID).first; + LastSeenGUID = VI.getGUID(); + TheIndex.addGlobalValueSummary(VI, std::move(AS)); break; } // FS_COMBINED_GLOBALVAR_INIT_REFS: [valueid, modid, flags, n x valueid] @@ -5033,15 +6070,23 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary( unsigned ValueID = Record[0]; uint64_t ModuleId = Record[1]; uint64_t RawFlags = Record[2]; + unsigned RefArrayStart = 3; + GlobalVarSummary::GVarFlags GVF(/* ReadOnly */ false, + /* WriteOnly */ false); auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); + if (Version >= 5) { + GVF = getDecodedGVarFlags(Record[3]); + RefArrayStart = 4; + } std::vector<ValueInfo> Refs = - makeRefList(ArrayRef<uint64_t>(Record).slice(3)); - auto FS = llvm::make_unique<GlobalVarSummary>(Flags, std::move(Refs)); + makeRefList(ArrayRef<uint64_t>(Record).slice(RefArrayStart)); + auto FS = + llvm::make_unique<GlobalVarSummary>(Flags, GVF, std::move(Refs)); LastSeenSummary = FS.get(); FS->setModulePath(ModuleIdMap[ModuleId]); - GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first; - TheIndex.addGlobalValueSummary(GUID, std::move(FS)); - Combined = true; + ValueInfo VI = getValueInfoFromValueId(ValueID).first; + LastSeenGUID = VI.getGUID(); + TheIndex.addGlobalValueSummary(VI, std::move(FS)); break; } // FS_COMBINED_ORIGINAL_NAME: [original_name] @@ -5050,16 +6095,63 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary( if (!LastSeenSummary) return error("Name attachment that does not follow a combined record"); LastSeenSummary->setOriginalName(OriginalName); + TheIndex.addOriginalName(LastSeenGUID, OriginalName); // Reset the LastSeenSummary LastSeenSummary = nullptr; + LastSeenGUID = 0; break; } - case bitc::FS_TYPE_TESTS: { + case bitc::FS_TYPE_TESTS: assert(PendingTypeTests.empty()); PendingTypeTests.insert(PendingTypeTests.end(), Record.begin(), Record.end()); break; + + case bitc::FS_TYPE_TEST_ASSUME_VCALLS: + assert(PendingTypeTestAssumeVCalls.empty()); + for (unsigned I = 0; I != Record.size(); I += 2) + PendingTypeTestAssumeVCalls.push_back({Record[I], Record[I+1]}); + break; + + case bitc::FS_TYPE_CHECKED_LOAD_VCALLS: + assert(PendingTypeCheckedLoadVCalls.empty()); + for (unsigned I = 0; I != Record.size(); I += 2) + PendingTypeCheckedLoadVCalls.push_back({Record[I], Record[I+1]}); + break; + + case bitc::FS_TYPE_TEST_ASSUME_CONST_VCALL: + PendingTypeTestAssumeConstVCalls.push_back( + {{Record[0], Record[1]}, {Record.begin() + 2, Record.end()}}); + break; + + case bitc::FS_TYPE_CHECKED_LOAD_CONST_VCALL: + PendingTypeCheckedLoadConstVCalls.push_back( + {{Record[0], Record[1]}, {Record.begin() + 2, Record.end()}}); + break; + + case bitc::FS_CFI_FUNCTION_DEFS: { + std::set<std::string> &CfiFunctionDefs = TheIndex.cfiFunctionDefs(); + for (unsigned I = 0; I != Record.size(); I += 2) + CfiFunctionDefs.insert( + {Strtab.data() + Record[I], static_cast<size_t>(Record[I + 1])}); + break; } + + case bitc::FS_CFI_FUNCTION_DECLS: { + std::set<std::string> &CfiFunctionDecls = TheIndex.cfiFunctionDecls(); + for (unsigned I = 0; I != Record.size(); I += 2) + CfiFunctionDecls.insert( + {Strtab.data() + Record[I], static_cast<size_t>(Record[I + 1])}); + break; + } + + case bitc::FS_TYPE_ID: + parseTypeIdSummaryRecord(Record, Strtab, TheIndex); + break; + + case bitc::FS_TYPE_ID_METADATA: + parseTypeIdCompatibleVtableSummaryRecord(Record); + break; } } llvm_unreachable("Exit infinite loop"); @@ -5068,16 +6160,19 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary( // 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; SmallString<128> ModulePath; - ModulePathStringTableTy::iterator LastSeenModulePath; + 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. @@ -5091,7 +6186,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: { @@ -5101,8 +6199,8 @@ Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() { if (convertToString(Record, 1, ModulePath)) return error("Invalid record"); - LastSeenModulePath = TheIndex.addModulePath(ModulePath, ModuleId); - ModuleIdMap[ModuleId] = LastSeenModulePath->first(); + LastSeenModule = TheIndex.addModule(ModulePath, ModuleId); + ModuleIdMap[ModuleId] = LastSeenModule->first(); ModulePath.clear(); break; @@ -5111,15 +6209,15 @@ Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() { case bitc::MST_CODE_HASH: { if (Record.size() != 5) return error("Invalid hash length " + Twine(Record.size()).str()); - if (LastSeenModulePath == TheIndex.modulePaths().end()) + if (!LastSeenModule) return error("Invalid hash that does not follow a module path"); int Pos = 0; for (auto &Val : Record) { assert(!(Val >> 32) && "Unexpected high bits set"); - LastSeenModulePath->second.second[Pos++] = Val; + LastSeenModule->second.second[Pos++] = Val; } - // Reset LastSeenModulePath to avoid overriding the hash unexpectedly. - LastSeenModulePath = TheIndex.modulePaths().end(); + // Reset LastSeenModule to avoid overriding the hash unexpectedly. + LastSeenModule = nullptr; break; } } @@ -5136,6 +6234,7 @@ class BitcodeErrorCategoryType : public std::error_category { const char *name() const noexcept override { return "llvm.bitcode"; } + std::string message(int IE) const override { BitcodeError E = static_cast<BitcodeError>(IE); switch (E) { @@ -5154,18 +6253,64 @@ const std::error_category &llvm::BitcodeErrorCategory() { return *ErrorCategory; } +static Expected<StringRef> readBlobInRecord(BitstreamCursor &Stream, + unsigned Block, unsigned RecordID) { + if (Error Err = Stream.EnterSubBlock(Block)) + return std::move(Err); + + StringRef Strtab; + while (true) { + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); + + switch (Entry.Kind) { + case BitstreamEntry::EndBlock: + return Strtab; + + case BitstreamEntry::Error: + return error("Malformed block"); + + case BitstreamEntry::SubBlock: + if (Error Err = Stream.SkipBlock()) + return std::move(Err); + break; + + case BitstreamEntry::Record: + StringRef Blob; + SmallVector<uint64_t, 1> Record; + Expected<unsigned> MaybeRecord = + Stream.readRecord(Entry.ID, Record, &Blob); + if (!MaybeRecord) + return MaybeRecord.takeError(); + if (MaybeRecord.get() == RecordID) + Strtab = Blob; + break; + } + } +} + //===----------------------------------------------------------------------===// // External interface //===----------------------------------------------------------------------===// Expected<std::vector<BitcodeModule>> llvm::getBitcodeModuleList(MemoryBufferRef Buffer) { + auto FOrErr = getBitcodeFileContents(Buffer); + if (!FOrErr) + return FOrErr.takeError(); + return std::move(FOrErr->Mods); +} + +Expected<BitcodeFileContents> +llvm::getBitcodeFileContents(MemoryBufferRef Buffer) { Expected<BitstreamCursor> StreamOrErr = initStream(Buffer); if (!StreamOrErr) return StreamOrErr.takeError(); BitstreamCursor &Stream = *StreamOrErr; - std::vector<BitcodeModule> Modules; + BitcodeFileContents F; while (true) { uint64_t BCBegin = Stream.getCurrentByteNo(); @@ -5173,9 +6318,13 @@ llvm::getBitcodeModuleList(MemoryBufferRef Buffer) { // of the bitcode stream (e.g. Apple's ar tool). If we are close enough to // the end that there cannot possibly be another module, stop looking. if (BCBegin + 8 >= Stream.getBitcodeBytes().size()) - return Modules; + return F; + + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); - BitstreamEntry Entry = Stream.advance(); switch (Entry.Kind) { case BitstreamEntry::EndBlock: case BitstreamEntry::Error: @@ -5185,10 +6334,16 @@ llvm::getBitcodeModuleList(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"); @@ -5196,28 +6351,69 @@ llvm::getBitcodeModuleList(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); - Modules.push_back({Stream.getBitcodeBytes().slice( - BCBegin, Stream.getCurrentByteNo() - BCBegin), - Buffer.getBufferIdentifier(), IdentificationBit, - ModuleBit}); + F.Mods.push_back({Stream.getBitcodeBytes().slice( + BCBegin, Stream.getCurrentByteNo() - BCBegin), + Buffer.getBufferIdentifier(), IdentificationBit, + ModuleBit}); continue; } - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Entry.ID == bitc::STRTAB_BLOCK_ID) { + Expected<StringRef> Strtab = + readBlobInRecord(Stream, bitc::STRTAB_BLOCK_ID, bitc::STRTAB_BLOB); + if (!Strtab) + return Strtab.takeError(); + // This string table is used by every preceding bitcode module that does + // not have its own string table. A bitcode file may have multiple + // string tables if it was created by binary concatenation, for example + // with "llvm-cat -b". + for (auto I = F.Mods.rbegin(), E = F.Mods.rend(); I != E; ++I) { + if (!I->Strtab.empty()) + break; + I->Strtab = *Strtab; + } + // Similarly, the string table is used by every preceding symbol table; + // normally there will be just one unless the bitcode file was created + // by binary concatenation. + if (!F.Symtab.empty() && F.StrtabForSymtab.empty()) + F.StrtabForSymtab = *Strtab; + continue; + } + + if (Entry.ID == bitc::SYMTAB_BLOCK_ID) { + Expected<StringRef> SymtabOrErr = + readBlobInRecord(Stream, bitc::SYMTAB_BLOCK_ID, bitc::SYMTAB_BLOB); + if (!SymtabOrErr) + return SymtabOrErr.takeError(); + + // We can expect the bitcode file to have multiple symbol tables if it + // was created by binary concatenation. In that case we silently + // ignore any subsequent symbol tables, which is fine because this is a + // low level function. The client is expected to notice that the number + // of modules in the symbol table does not match the number of modules + // in the input file and regenerate the symbol table. + if (F.Symtab.empty()) + F.Symtab = *SymtabOrErr; + continue; + } + + 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(); } } } -/// \brief Get a lazy one-at-time loading module from bitcode. +/// Get a lazy one-at-time loading module from bitcode. /// /// This isn't always used in a lazy context. In particular, it's also used by /// \a parseModule(). If this is truly lazy, then we need to eagerly pull @@ -5232,7 +6428,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) @@ -5241,9 +6438,10 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll, ProducerIdentification = *ProducerIdentificationOrErr; } - Stream.JumpToBit(ModuleBit); - auto *R = - new BitcodeReader(std::move(Stream), ProducerIdentification, Context); + if (Error JumpFailed = Stream.JumpToBit(ModuleBit)) + return std::move(JumpFailed); + auto *R = new BitcodeReader(std::move(Stream), Strtab, ProducerIdentification, + Context); std::unique_ptr<Module> M = llvm::make_unique<Module>(ModuleIdentifier, Context); @@ -5272,49 +6470,133 @@ BitcodeModule::getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata, return getModuleImpl(Context, false, ShouldLazyLoadMetadata, IsImporting); } +// Parse the specified bitcode buffer and merge the index into CombinedIndex. +// We don't use ModuleIdentifier here because the client may need to control the +// module path used in the combined summary (e.g. when reading summaries for +// regular LTO modules). +Error BitcodeModule::readSummary(ModuleSummaryIndex &CombinedIndex, + StringRef ModulePath, uint64_t ModuleId) { + BitstreamCursor Stream(Buffer); + if (Error JumpFailed = Stream.JumpToBit(ModuleBit)) + return JumpFailed; + + ModuleSummaryIndexBitcodeReader R(std::move(Stream), Strtab, CombinedIndex, + ModulePath, ModuleId); + return R.parseModule(); +} + // 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>(); - ModuleSummaryIndexBitcodeReader R(std::move(Stream), *Index); + auto Index = llvm::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false); + ModuleSummaryIndexBitcodeReader R(std::move(Stream), Strtab, *Index, + ModuleIdentifier, 0); - if (Error Err = R.parseModule(ModuleIdentifier)) + if (Error Err = R.parseModule()) return std::move(Err); return std::move(Index); } +static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, + unsigned ID) { + if (Error Err = Stream.EnterSubBlock(ID)) + return std::move(Err); + SmallVector<uint64_t, 64> Record; + + while (true) { + 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: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + // If no flags record found, conservatively return true to mimic + // behavior before this flag was added. + return true; + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Look for the FS_FLAGS record. + Record.clear(); + 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] + uint64_t Flags = Record[0]; + // Scan flags. + assert(Flags <= 0x1f && "Unexpected bits in flag"); + + return Flags & 0x8; + } + } + } + llvm_unreachable("Exit infinite loop"); +} + // Check if the given bitcode buffer contains a global value summary block. -Expected<bool> BitcodeModule::hasSummary() { +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: return error("Malformed block"); case BitstreamEntry::EndBlock: - return false; + return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/false, + /*EnableSplitLTOUnit=*/false}; case BitstreamEntry::SubBlock: - if (Entry.ID == bitc::GLOBALVAL_SUMMARY_BLOCK_ID) - return true; + if (Entry.ID == bitc::GLOBALVAL_SUMMARY_BLOCK_ID) { + Expected<bool> EnableSplitLTOUnit = + getEnableSplitLTOUnitFlag(Stream, Entry.ID); + if (!EnableSplitLTOUnit) + return EnableSplitLTOUnit.takeError(); + return BitcodeLTOInfo{/*IsThinLTO=*/true, /*HasSummary=*/true, + *EnableSplitLTOUnit}; + } + + if (Entry.ID == bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID) { + Expected<bool> EnableSplitLTOUnit = + getEnableSplitLTOUnitFlag(Stream, Entry.ID); + if (!EnableSplitLTOUnit) + return EnableSplitLTOUnit.takeError(); + return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/true, + *EnableSplitLTOUnit}; + } // 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(); } } } @@ -5390,6 +6672,16 @@ Expected<std::string> llvm::getBitcodeProducerString(MemoryBufferRef Buffer) { return readIdentificationCode(*StreamOrErr); } +Error llvm::readModuleSummaryIndex(MemoryBufferRef Buffer, + ModuleSummaryIndex &CombinedIndex, + uint64_t ModuleId) { + Expected<BitcodeModule> BM = getSingleModule(Buffer); + if (!BM) + return BM.takeError(); + + return BM->readSummary(CombinedIndex, BM->getModuleIdentifier(), ModuleId); +} + Expected<std::unique_ptr<ModuleSummaryIndex>> llvm::getModuleSummaryIndex(MemoryBufferRef Buffer) { Expected<BitcodeModule> BM = getSingleModule(Buffer); @@ -5399,10 +6691,22 @@ llvm::getModuleSummaryIndex(MemoryBufferRef Buffer) { return BM->getSummary(); } -Expected<bool> llvm::hasGlobalValueSummary(MemoryBufferRef Buffer) { +Expected<BitcodeLTOInfo> llvm::getBitcodeLTOInfo(MemoryBufferRef Buffer) { Expected<BitcodeModule> BM = getSingleModule(Buffer); if (!BM) return BM.takeError(); - return BM->hasSummary(); + return BM->getLTOInfo(); +} + +Expected<std::unique_ptr<ModuleSummaryIndex>> +llvm::getModuleSummaryIndexForFile(StringRef Path, + bool IgnoreEmptyThinLTOIndexFile) { + ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = + MemoryBuffer::getFileOrSTDIN(Path); + if (!FileOrErr) + return errorCodeToError(FileOrErr.getError()); + if (IgnoreEmptyThinLTOIndexFile && !(*FileOrErr)->getBufferSize()) + return nullptr; + return getModuleSummaryIndex(**FileOrErr); }