summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Bitcode/Reader
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Bitcode/Reader')
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp1299
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/MetadataLoader.cpp240
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/MetadataLoader.h3
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/ValueList.cpp6
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/ValueList.h2
5 files changed, 1027 insertions, 523 deletions
diff --git a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index a46e49c..2b4970a 100644
--- a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -28,8 +28,8 @@
#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"
@@ -40,13 +40,13 @@
#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"
@@ -372,12 +372,26 @@ Expected<std::string> readTriple(BitstreamCursor &Stream) {
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();
@@ -395,6 +409,27 @@ Error BitcodeReaderBase::error(const Twine &Message) {
return ::error(FullMsg);
}
+Expected<unsigned>
+BitcodeReaderBase::parseVersionRecord(ArrayRef<uint64_t> Record) {
+ if (Record.size() < 1)
+ 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)};
+}
+
class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
LLVMContext &Context;
Module *TheModule = nullptr;
@@ -405,6 +440,9 @@ 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;
BitcodeReaderValueList ValueList;
Optional<MetadataLoader> MDLoader;
@@ -419,10 +457,10 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
/// 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.
@@ -475,10 +513,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();
@@ -520,10 +559,10 @@ 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'.
@@ -598,15 +637,26 @@ private:
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 +670,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 +691,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,13 +711,25 @@ 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);
@@ -672,11 +737,13 @@ private:
std::vector<FunctionSummary::EdgeTy> makeCallList(ArrayRef<uint64_t> Record,
bool IsOldProfileFormat,
bool HasProfile);
- Error parseEntireSummary(StringRef ModulePath);
+ Error parseEntireSummary(unsigned ID);
Error parseModuleStringTable();
- std::pair<GlobalValue::GUID, GlobalValue::GUID>
- getGUIDFromValueId(unsigned ValueId);
+ std::pair<ValueInfo, GlobalValue::GUID>
+ getValueInfoFromValueId(unsigned ValueId);
+
+ ModuleSummaryIndex::ModuleInfo *addThisModule();
};
} // end anonymous namespace
@@ -694,10 +761,10 @@ 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),
+ : BitcodeReaderBase(std::move(Stream), Strtab), Context(Context),
ValueList(Context) {
this->ProducerIdentification = ProducerIdentification;
}
@@ -802,11 +869,11 @@ 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;
+ return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, Live);
}
static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) {
@@ -935,14 +1002,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.
@@ -971,6 +1030,8 @@ static FastMathFlags getDecodedFastMathFlags(unsigned Val) {
FMF.setNoSignedZeros();
if (0 != (Val & FastMathFlags::AllowReciprocal))
FMF.setAllowReciprocal();
+ if (0 != (Val & FastMathFlags::AllowContract))
+ FMF.setAllowContract(true);
return FMF;
}
@@ -1066,6 +1127,7 @@ 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;
+ case Attribute::Speculatable: return 1ULL << 54;
case Attribute::Dereferenceable:
llvm_unreachable("dereferenceable attribute not supported in raw format");
break;
@@ -1132,7 +1194,7 @@ Error BitcodeReader::parseAttributeBlock() {
SmallVector<uint64_t, 64> Record;
- SmallVector<AttributeSet, 8> Attrs;
+ SmallVector<AttributeList, 8> Attrs;
// Read all the records.
while (true) {
@@ -1162,10 +1224,10 @@ 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;
}
@@ -1173,7 +1235,7 @@ Error BitcodeReader::parseAttributeBlock() {
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;
}
@@ -1262,6 +1324,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:
@@ -1391,7 +1455,7 @@ Error BitcodeReader::parseAttributeGroupBlock() {
}
}
- MAttributeGroups[GrpID] = AttributeSet::get(Context, Idx, B);
+ MAttributeGroups[GrpID] = AttributeList::get(Context, Idx, B);
break;
}
}
@@ -1677,6 +1741,44 @@ Error BitcodeReader::parseOperandBundleTags() {
}
}
+Error BitcodeReader::parseSyncScopeNames() {
+ if (Stream.EnterSubBlock(bitc::SYNC_SCOPE_NAMES_BLOCK_ID))
+ return error("Invalid record");
+
+ if (!SSIDs.empty())
+ return error("Invalid multiple synchronization scope names blocks");
+
+ SmallVector<uint64_t, 64> Record;
+ while (true) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+ 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.
+
+ if (Stream.readRecord(Entry.ID, Record) != 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) {
@@ -1725,6 +1827,54 @@ static uint64_t jumpToValueSymbolTable(uint64_t Offset,
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 (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID))
+ return error("Invalid record");
+
+ SmallVector<uint64_t, 64> Record;
+ while (true) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ 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();
+ switch (Stream.readRecord(Entry.ID, Record)) {
+ 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) {
@@ -1732,8 +1882,18 @@ 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)
+ if (Offset > 0) {
CurrentBit = jumpToValueSymbolTable(Offset, Stream);
+ // If this module uses a string table, read this as a module-level VST.
+ if (UseStrtab) {
+ if (Error Err = parseGlobalValueSymbolTable())
+ return Err;
+ Stream.JumpToBit(CurrentBit);
+ 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
@@ -1794,29 +1954,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: {
@@ -2501,6 +2642,16 @@ Error BitcodeReader::materializeMetadata() {
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();
}
@@ -2539,6 +2690,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;
@@ -2607,6 +2759,272 @@ bool BitcodeReaderBase::readBlockInfo() {
return false;
}
+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.size() < 1)
+ 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();
+}
+
+Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
+ // v1: [pointer type, isconst, initid, linkage, alignment, section,
+ // visibility, threadlocal, unnamed_addr, externally_initialized,
+ // dllstorageclass, comdat, attributes] (name in VST)
+ // v2: [strtab_offset, strtab_size, v1]
+ StringRef Name;
+ std::tie(Name, Record) = readNameFromStrtab(Record);
+
+ if (Record.size() < 6)
+ return error("Invalid record");
+ Type *Ty = getTypeByID(Record[0]);
+ 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))
+ 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);
+
+ 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));
+ }
+
+ if (Record.size() > 12) {
+ auto AS = getAttributes(Record[12]).getFnAttributes();
+ NewGV->setAttributes(AS);
+ }
+ 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] (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 *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, Name, 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))
+ 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;
+ }
+ 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] (name in VST)
+ // v1 IFUNC: [alias type, addrspace, aliasee val#, linkage,
+ // visibility, dllstorageclass] (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 *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), Name,
+ TheModule);
+ else
+ NewGA = GlobalIFunc::create(Ty, AddrSpace, getDecodedLinkage(Linkage), Name,
+ 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));
+ return Error::success();
+}
+
Error BitcodeReader::parseModule(uint64_t ResumeBit,
bool ShouldLazyLoadMetadata) {
if (ResumeBit)
@@ -2615,8 +3033,6 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
return error("Invalid record");
SmallVector<uint64_t, 64> Record;
- std::vector<std::string> SectionTable;
- std::vector<std::string> GCTable;
// Read all the records for this module.
while (true) {
@@ -2750,6 +3166,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;
@@ -2762,21 +3182,11 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
auto BitCode = Stream.readRecord(Entry.ID, Record);
switch (BitCode) {
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]
@@ -2822,249 +3232,28 @@ 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_COMDAT: {
+ if (Error Err = parseComdatRecord(Record))
+ return Err;
+ break;
+ }
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))
+ if (Error Err = parseGlobalVarRecord(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))
+ 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]);
+ if (Error Err = parseGlobalIndirectSymbolRecord(BitCode, Record))
+ return Err;
break;
+ }
/// MODULE_CODE_VSTOFFSET: [offset]
case bitc::MODULE_CODE_VSTOFFSET:
if (Record.size() < 1)
@@ -3840,7 +4029,7 @@ 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++]);
@@ -4017,7 +4206,12 @@ 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;
@@ -4048,7 +4242,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
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) ||
@@ -4070,12 +4264,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(Op, "", Record[OpNum+1], Align, Ordering, SSID);
InstructionList.push_back(I);
break;
@@ -4104,7 +4298,7 @@ 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) ||
@@ -4124,20 +4318,20 @@ 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;
@@ -4154,7 +4348,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
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;
@@ -4166,7 +4360,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
FailureOrdering = getDecodedOrdering(Record[OpNum + 3]);
I = new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering, FailureOrdering,
- SynchScope);
+ SSID);
cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
if (Record.size() < 8) {
@@ -4183,7 +4377,7 @@ 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) ||
@@ -4200,13 +4394,13 @@ 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);
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]);
@@ -4214,8 +4408,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;
}
@@ -4225,7 +4419,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;
@@ -4343,11 +4537,11 @@ 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);
@@ -4411,6 +4605,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
//===----------------------------------------------------------------------===//
@@ -4540,14 +4742,37 @@ 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) {}
+
+ModuleSummaryIndex::ModuleInfo *
+ModuleSummaryIndexBitcodeReader::addThisModule() {
+ return TheIndex.addModule(ModulePath, ModuleId);
+}
+
+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";
+ ValueIdToValueInfoMap[ValueID] =
+ std::make_pair(TheIndex.getOrInsertValueInfo(ValueGUID), OriginalNameID);
}
// Specialized value symbol table parser used when reading module index
@@ -4556,6 +4781,10 @@ 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);
@@ -4597,17 +4826,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;
}
@@ -4621,18 +4840,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;
}
@@ -4642,7 +4850,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;
}
}
@@ -4652,7 +4861,7 @@ 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) {
+Error ModuleSummaryIndexBitcodeReader::parseModule() {
if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
return error("Invalid record");
@@ -4691,6 +4900,7 @@ Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) {
return error("Invalid record");
break;
case bitc::GLOBALVAL_SUMMARY_BLOCK_ID:
+ case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID:
assert(!SeenValueSymbolTable &&
"Already read VST when parsing summary block?");
// We might not have a VST if there were no values in the
@@ -4703,7 +4913,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:
@@ -4719,6 +4929,11 @@ Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) {
switch (BitCode) {
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;
@@ -4731,12 +4946,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 = addThisModule()->second.second;
int Pos = 0;
for (auto &Val : Record) {
assert(!(Val >> 32) && "Unexpected high bits set");
@@ -4753,37 +4963,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;
}
}
@@ -4798,7 +4997,7 @@ 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;
}
@@ -4808,23 +5007,22 @@ std::vector<FunctionSummary::EdgeTy> ModuleSummaryIndexBitcodeReader::makeCallLi
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;
+ 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}});
+ Ret.push_back(FunctionSummary::EdgeTy{Callee, CalleeInfo{Hotness}});
}
return Ret;
}
// 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))
+Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
+ if (Stream.EnterSubBlock(ID))
return error("Invalid record");
SmallVector<uint64_t, 64> Record;
@@ -4846,8 +5044,16 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
// 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();
@@ -4857,16 +5063,6 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
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.
@@ -4885,6 +5081,13 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
switch (BitCode) {
default: // Default behavior: ignore.
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, numrefs, numrefs x valueid,
// n x (valueid)]
// FS_PERMODULE_PROFILE: [valueid, flags, instcount, numrefs,
@@ -4914,12 +5117,19 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
IsOldProfileFormat, HasProfile);
auto FS = llvm::make_unique<FunctionSummary>(
Flags, InstCount, std::move(Refs), std::move(Calls),
- std::move(PendingTypeTests));
+ 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(addThisModule()->first());
+ FS->setOriginalName(VIAndOriginalGUID.second);
+ TheIndex.addGlobalValueSummary(VIAndOriginalGUID.first, std::move(FS));
break;
}
// FS_ALIAS: [valueid, flags, valueid]
@@ -4937,15 +5147,17 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
// 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(addThisModule()->first());
- GlobalValue::GUID AliaseeGUID = getGUIDFromValueId(AliaseeID).first;
- auto *AliaseeSummary = TheIndex.getGlobalValueSummary(AliaseeGUID);
- if (!AliaseeSummary)
+ GlobalValue::GUID AliaseeGUID =
+ getValueInfoFromValueId(AliaseeID).first.getGUID();
+ auto AliaseeInModule =
+ TheIndex.findSummaryInModule(AliaseeGUID, ModulePath);
+ if (!AliaseeInModule)
return error("Alias expects aliasee summary to be parsed");
- AS->setAliasee(AliaseeSummary);
+ AS->setAliasee(AliaseeInModule);
- auto GUID = getGUIDFromValueId(ValueID);
+ auto GUID = getValueInfoFromValueId(ValueID);
AS->setOriginalName(GUID.second);
TheIndex.addGlobalValueSummary(GUID.first, std::move(AS));
break;
@@ -4958,8 +5170,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
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);
+ FS->setModulePath(addThisModule()->first());
+ auto GUID = getValueInfoFromValueId(ValueID);
FS->setOriginalName(GUID.second);
TheIndex.addGlobalValueSummary(GUID.first, std::move(FS));
break;
@@ -4986,15 +5198,22 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
std::vector<FunctionSummary::EdgeTy> Edges = makeCallList(
ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex),
IsOldProfileFormat, HasProfile);
- GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first;
+ ValueInfo VI = getValueInfoFromValueId(ValueID).first;
auto FS = llvm::make_unique<FunctionSummary>(
Flags, InstCount, std::move(Refs), std::move(Edges),
- std::move(PendingTypeTests));
+ 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]
@@ -5010,16 +5229,17 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
LastSeenSummary = AS.get();
AS->setModulePath(ModuleIdMap[ModuleId]);
- auto AliaseeGUID = getGUIDFromValueId(AliaseeValueId).first;
+ auto AliaseeGUID =
+ getValueInfoFromValueId(AliaseeValueId).first.getGUID();
auto AliaseeInModule =
TheIndex.findSummaryInModule(AliaseeGUID, AS->modulePath());
if (!AliaseeInModule)
return error("Alias expects aliasee summary to be parsed");
AS->setAliasee(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,9 +5253,9 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
auto FS = llvm::make_unique<GlobalVarSummary>(Flags, 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]
@@ -5044,8 +5264,10 @@ 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: {
@@ -5054,6 +5276,42 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
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;
+ }
}
}
llvm_unreachable("Exit infinite loop");
@@ -5068,7 +5326,7 @@ Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() {
SmallVector<uint64_t, 64> Record;
SmallString<128> ModulePath;
- ModulePathStringTableTy::iterator LastSeenModulePath;
+ ModuleSummaryIndex::ModuleInfo *LastSeenModule = nullptr;
while (true) {
BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
@@ -5095,8 +5353,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;
@@ -5105,15 +5363,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;
}
}
@@ -5148,18 +5406,56 @@ const std::error_category &llvm::BitcodeErrorCategory() {
return *ErrorCategory;
}
+static Expected<StringRef> readBlobInRecord(BitstreamCursor &Stream,
+ unsigned Block, unsigned RecordID) {
+ if (Stream.EnterSubBlock(Block))
+ return error("Invalid record");
+
+ StringRef Strtab;
+ while (1) {
+ BitstreamEntry Entry = Stream.advance();
+ switch (Entry.Kind) {
+ case BitstreamEntry::EndBlock:
+ return Strtab;
+
+ case BitstreamEntry::Error:
+ return error("Malformed block");
+
+ case BitstreamEntry::SubBlock:
+ if (Stream.SkipBlock())
+ return error("Malformed block");
+ break;
+
+ case BitstreamEntry::Record:
+ StringRef Blob;
+ SmallVector<uint64_t, 1> Record;
+ if (Stream.readRecord(Entry.ID, Record, &Blob) == 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();
@@ -5167,7 +5463,7 @@ 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;
BitstreamEntry Entry = Stream.advance();
switch (Entry.Kind) {
@@ -5193,10 +5489,49 @@ llvm::getBitcodeModuleList(MemoryBufferRef Buffer) {
if (Stream.SkipBlock())
return error("Malformed block");
- 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 (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;
}
@@ -5236,8 +5571,8 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll,
}
Stream.JumpToBit(ModuleBit);
- auto *R =
- new BitcodeReader(std::move(Stream), ProducerIdentification, Context);
+ auto *R = new BitcodeReader(std::move(Stream), Strtab, ProducerIdentification,
+ Context);
std::unique_ptr<Module> M =
llvm::make_unique<Module>(ModuleIdentifier, Context);
@@ -5266,22 +5601,37 @@ 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);
+ Stream.JumpToBit(ModuleBit);
+
+ 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);
auto Index = llvm::make_unique<ModuleSummaryIndex>();
- ModuleSummaryIndexBitcodeReader R(std::move(Stream), *Index);
+ 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);
}
// 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);
@@ -5295,11 +5645,14 @@ Expected<bool> BitcodeModule::hasSummary() {
case BitstreamEntry::Error:
return error("Malformed block");
case BitstreamEntry::EndBlock:
- return false;
+ return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/false};
case BitstreamEntry::SubBlock:
if (Entry.ID == bitc::GLOBALVAL_SUMMARY_BLOCK_ID)
- return true;
+ return BitcodeLTOInfo{/*IsThinLTO=*/true, /*HasSummary=*/true};
+
+ if (Entry.ID == bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID)
+ return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/true};
// Ignore other sub-blocks.
if (Stream.SkipBlock())
@@ -5384,6 +5737,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);
@@ -5393,10 +5756,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);
}
diff --git a/contrib/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/contrib/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index b89f5be..10fbcde 100644
--- a/contrib/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/contrib/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -53,6 +53,7 @@
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
@@ -358,6 +359,9 @@ class PlaceholderQueue {
std::deque<DistinctMDOperandPlaceholder> PHs;
public:
+ ~PlaceholderQueue() {
+ assert(empty() && "PlaceholderQueue hasn't been flushed before being destroyed");
+ }
bool empty() { return PHs.empty(); }
DistinctMDOperandPlaceholder &getPlaceholderOp(unsigned ID);
void flush(BitcodeReaderMetadataList &MetadataList);
@@ -403,6 +407,11 @@ void PlaceholderQueue::flush(BitcodeReaderMetadataList &MetadataList) {
} // anonynous namespace
+static Error error(const Twine &Message) {
+ return make_error<StringError>(
+ Message, make_error_code(BitcodeError::CorruptedBitcode));
+}
+
class MetadataLoader::MetadataLoaderImpl {
BitcodeReaderMetadataList MetadataList;
BitcodeReaderValueList &ValueList;
@@ -449,6 +458,7 @@ class MetadataLoader::MetadataLoaderImpl {
bool StripTBAA = false;
bool HasSeenOldLoopTags = false;
bool NeedUpgradeToDIGlobalVariableExpression = false;
+ bool NeedDeclareExpressionUpgrade = false;
/// True if metadata is being parsed for a module being ThinLTO imported.
bool IsImporting = false;
@@ -457,7 +467,7 @@ class MetadataLoader::MetadataLoaderImpl {
PlaceholderQueue &Placeholders, StringRef Blob,
unsigned &NextMetadataNo);
Error parseMetadataStrings(ArrayRef<uint64_t> Record, StringRef Blob,
- std::function<void(StringRef)> CallBack);
+ function_ref<void(StringRef)> CallBack);
Error parseGlobalObjectAttachment(GlobalObject &GO,
ArrayRef<uint64_t> Record);
Error parseMetadataKindRecord(SmallVectorImpl<uint64_t> &Record);
@@ -469,8 +479,8 @@ class MetadataLoader::MetadataLoaderImpl {
for (auto CU_SP : CUSubprograms)
if (auto *SPs = dyn_cast_or_null<MDTuple>(CU_SP.second))
for (auto &Op : SPs->operands())
- if (auto *SP = dyn_cast_or_null<MDNode>(Op))
- SP->replaceOperandWith(7, CU_SP.first);
+ if (auto *SP = dyn_cast_or_null<DISubprogram>(Op))
+ SP->replaceUnit(CU_SP.first);
CUSubprograms.clear();
}
@@ -495,7 +505,7 @@ class MetadataLoader::MetadataLoaderImpl {
// Upgrade variables attached to globals.
for (auto &GV : TheModule.globals()) {
- SmallVector<MDNode *, 1> MDs, NewMDs;
+ SmallVector<MDNode *, 1> MDs;
GV.getMetadata(LLVMContext::MD_dbg, MDs);
GV.eraseMetadata(LLVMContext::MD_dbg);
for (auto *MD : MDs)
@@ -508,6 +518,108 @@ class MetadataLoader::MetadataLoaderImpl {
}
}
+ /// Remove a leading DW_OP_deref from DIExpressions in a dbg.declare that
+ /// describes a function argument.
+ void upgradeDeclareExpressions(Function &F) {
+ if (!NeedDeclareExpressionUpgrade)
+ return;
+
+ for (auto &BB : F)
+ for (auto &I : BB)
+ if (auto *DDI = dyn_cast<DbgDeclareInst>(&I))
+ if (auto *DIExpr = DDI->getExpression())
+ if (DIExpr->startsWithDeref() &&
+ dyn_cast_or_null<Argument>(DDI->getAddress())) {
+ SmallVector<uint64_t, 8> Ops;
+ Ops.append(std::next(DIExpr->elements_begin()),
+ DIExpr->elements_end());
+ auto *E = DIExpression::get(Context, Ops);
+ DDI->setOperand(2, MetadataAsValue::get(Context, E));
+ }
+ }
+
+ /// Upgrade the expression from previous versions.
+ Error upgradeDIExpression(uint64_t FromVersion,
+ MutableArrayRef<uint64_t> &Expr,
+ SmallVectorImpl<uint64_t> &Buffer) {
+ auto N = Expr.size();
+ switch (FromVersion) {
+ default:
+ return error("Invalid record");
+ case 0:
+ if (N >= 3 && Expr[N - 3] == dwarf::DW_OP_bit_piece)
+ Expr[N - 3] = dwarf::DW_OP_LLVM_fragment;
+ LLVM_FALLTHROUGH;
+ case 1:
+ // Move DW_OP_deref to the end.
+ if (N && Expr[0] == dwarf::DW_OP_deref) {
+ auto End = Expr.end();
+ if (Expr.size() >= 3 &&
+ *std::prev(End, 3) == dwarf::DW_OP_LLVM_fragment)
+ End = std::prev(End, 3);
+ std::move(std::next(Expr.begin()), End, Expr.begin());
+ *std::prev(End) = dwarf::DW_OP_deref;
+ }
+ NeedDeclareExpressionUpgrade = true;
+ LLVM_FALLTHROUGH;
+ case 2: {
+ // Change DW_OP_plus to DW_OP_plus_uconst.
+ // Change DW_OP_minus to DW_OP_uconst, DW_OP_minus
+ auto SubExpr = ArrayRef<uint64_t>(Expr);
+ while (!SubExpr.empty()) {
+ // Skip past other operators with their operands
+ // for this version of the IR, obtained from
+ // from historic DIExpression::ExprOperand::getSize().
+ size_t HistoricSize;
+ switch (SubExpr.front()) {
+ default:
+ HistoricSize = 1;
+ break;
+ case dwarf::DW_OP_constu:
+ case dwarf::DW_OP_minus:
+ case dwarf::DW_OP_plus:
+ HistoricSize = 2;
+ break;
+ case dwarf::DW_OP_LLVM_fragment:
+ HistoricSize = 3;
+ break;
+ }
+
+ // If the expression is malformed, make sure we don't
+ // copy more elements than we should.
+ HistoricSize = std::min(SubExpr.size(), HistoricSize);
+ ArrayRef<uint64_t> Args = SubExpr.slice(1, HistoricSize-1);
+
+ switch (SubExpr.front()) {
+ case dwarf::DW_OP_plus:
+ Buffer.push_back(dwarf::DW_OP_plus_uconst);
+ Buffer.append(Args.begin(), Args.end());
+ break;
+ case dwarf::DW_OP_minus:
+ Buffer.push_back(dwarf::DW_OP_constu);
+ Buffer.append(Args.begin(), Args.end());
+ Buffer.push_back(dwarf::DW_OP_minus);
+ break;
+ default:
+ Buffer.push_back(*SubExpr.begin());
+ Buffer.append(Args.begin(), Args.end());
+ break;
+ }
+
+ // Continue with remaining elements.
+ SubExpr = SubExpr.slice(HistoricSize);
+ }
+ Expr = MutableArrayRef<uint64_t>(Buffer);
+ LLVM_FALLTHROUGH;
+ }
+ case 3:
+ // Up-to-date!
+ break;
+ }
+
+ return Error::success();
+ }
+
void upgradeDebugInfo() {
upgradeCUSubprograms();
upgradeCUVariables();
@@ -520,7 +632,7 @@ public:
bool IsImporting)
: MetadataList(TheModule.getContext()), ValueList(ValueList),
Stream(Stream), Context(TheModule.getContext()), TheModule(TheModule),
- getTypeByID(getTypeByID), IsImporting(IsImporting) {}
+ getTypeByID(std::move(getTypeByID)), IsImporting(IsImporting) {}
Error parseMetadata(bool ModuleLevel);
@@ -562,13 +674,9 @@ public:
unsigned size() const { return MetadataList.size(); }
void shrinkTo(unsigned N) { MetadataList.shrinkTo(N); }
+ void upgradeDebugIntrinsics(Function &F) { upgradeDeclareExpressions(F); }
};
-Error error(const Twine &Message) {
- return make_error<StringError>(
- Message, make_error_code(BitcodeError::CorruptedBitcode));
-}
-
Expected<bool>
MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() {
IndexCursor = Stream;
@@ -1107,9 +1215,15 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_DERIVED_TYPE: {
- if (Record.size() != 12)
+ if (Record.size() < 12 || Record.size() > 13)
return error("Invalid record");
+ // DWARF address space is encoded as N->getDWARFAddressSpace() + 1. 0 means
+ // that there is no DWARF address space associated with DIDerivedType.
+ Optional<unsigned> DWARFAddressSpace;
+ if (Record.size() > 12 && Record[12])
+ DWARFAddressSpace = Record[12] - 1;
+
IsDistinct = Record[0];
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
MetadataList.assignValue(
@@ -1118,7 +1232,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
getMDOrNull(Record[3]), Record[4],
getDITypeRefOrNull(Record[5]),
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
- Record[9], Flags, getDITypeRefOrNull(Record[11]))),
+ Record[9], DWARFAddressSpace, Flags,
+ getDITypeRefOrNull(Record[11]))),
NextMetadataNo);
NextMetadataNo++;
break;
@@ -1240,7 +1355,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_COMPILE_UNIT: {
- if (Record.size() < 14 || Record.size() > 17)
+ if (Record.size() < 14 || Record.size() > 18)
return error("Invalid record");
// Ignore Record[0], which indicates whether this compile unit is
@@ -1253,7 +1368,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
getMDOrNull(Record[12]), getMDOrNull(Record[13]),
Record.size() <= 15 ? nullptr : getMDOrNull(Record[15]),
Record.size() <= 14 ? 0 : Record[14],
- Record.size() <= 16 ? true : Record[16]);
+ Record.size() <= 16 ? true : Record[16],
+ Record.size() <= 17 ? false : Record[17]);
MetadataList.assignValue(CU, NextMetadataNo);
NextMetadataNo++;
@@ -1264,7 +1380,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_SUBPROGRAM: {
- if (Record.size() < 18 || Record.size() > 20)
+ if (Record.size() < 18 || Record.size() > 21)
return error("Invalid record");
IsDistinct =
@@ -1280,29 +1396,31 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
unsigned Offset = Record.size() >= 19 ? 1 : 0;
bool HasFn = Offset && !HasUnit;
bool HasThisAdj = Record.size() >= 20;
+ bool HasThrownTypes = Record.size() >= 21;
DISubprogram *SP = GET_OR_DISTINCT(
- DISubprogram, (Context,
- getDITypeRefOrNull(Record[1]), // scope
- getMDString(Record[2]), // name
- getMDString(Record[3]), // linkageName
- getMDOrNull(Record[4]), // file
- Record[5], // line
- getMDOrNull(Record[6]), // type
- Record[7], // isLocal
- Record[8], // isDefinition
- Record[9], // scopeLine
- getDITypeRefOrNull(Record[10]), // containingType
- Record[11], // virtuality
- Record[12], // virtualIndex
- HasThisAdj ? Record[19] : 0, // thisAdjustment
- static_cast<DINode::DIFlags>(Record[13] // flags
- ),
- Record[14], // isOptimized
- HasUnit ? CUorFn : nullptr, // unit
- getMDOrNull(Record[15 + Offset]), // templateParams
- getMDOrNull(Record[16 + Offset]), // declaration
- getMDOrNull(Record[17 + Offset]) // variables
- ));
+ DISubprogram,
+ (Context,
+ getDITypeRefOrNull(Record[1]), // scope
+ getMDString(Record[2]), // name
+ getMDString(Record[3]), // linkageName
+ getMDOrNull(Record[4]), // file
+ Record[5], // line
+ getMDOrNull(Record[6]), // type
+ Record[7], // isLocal
+ Record[8], // isDefinition
+ Record[9], // scopeLine
+ getDITypeRefOrNull(Record[10]), // containingType
+ Record[11], // virtuality
+ Record[12], // virtualIndex
+ HasThisAdj ? Record[19] : 0, // thisAdjustment
+ static_cast<DINode::DIFlags>(Record[13]), // flags
+ Record[14], // isOptimized
+ HasUnit ? CUorFn : nullptr, // unit
+ getMDOrNull(Record[15 + Offset]), // templateParams
+ getMDOrNull(Record[16 + Offset]), // declaration
+ getMDOrNull(Record[17 + Offset]), // variables
+ HasThrownTypes ? getMDOrNull(Record[20]) : nullptr // thrownTypes
+ ));
MetadataList.assignValue(SP, NextMetadataNo);
NextMetadataNo++;
@@ -1347,16 +1465,20 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_NAMESPACE: {
- if (Record.size() != 5)
+ // Newer versions of DINamespace dropped file and line.
+ MDString *Name;
+ if (Record.size() == 3)
+ Name = getMDString(Record[2]);
+ else if (Record.size() == 5)
+ Name = getMDString(Record[3]);
+ else
return error("Invalid record");
IsDistinct = Record[0] & 1;
bool ExportSymbols = Record[0] & 2;
MetadataList.assignValue(
GET_OR_DISTINCT(DINamespace,
- (Context, getMDOrNull(Record[1]),
- getMDOrNull(Record[2]), getMDString(Record[3]),
- Record[4], ExportSymbols)),
+ (Context, getMDOrNull(Record[1]), Name, ExportSymbols)),
NextMetadataNo);
NextMetadataNo++;
break;
@@ -1433,6 +1555,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
} else if (Version == 0) {
// Upgrade old metadata, which stored a global variable reference or a
// ConstantInt here.
+ NeedUpgradeToDIGlobalVariableExpression = true;
Metadata *Expr = getMDOrNull(Record[9]);
uint32_t AlignInBits = 0;
if (Record.size() > 11) {
@@ -1463,8 +1586,6 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
DIGlobalVariableExpression *DGVE = nullptr;
if (Attach || Expr)
DGVE = DIGlobalVariableExpression::getDistinct(Context, DGV, Expr);
- else
- NeedUpgradeToDIGlobalVariableExpression = true;
if (Attach)
Attach->addDebugInfo(DGVE);
@@ -1485,7 +1606,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
bool HasAlignment = Record[0] & 2;
// 2nd field used to be an artificial tag, either DW_TAG_auto_variable or
// DW_TAG_arg_variable, if we have alignment flag encoded it means, that
- // this is newer version of record which doesn't have artifical tag.
+ // this is newer version of record which doesn't have artificial tag.
bool HasTag = !HasAlignment && Record.size() > 8;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[7 + HasTag]);
uint32_t AlignInBits = 0;
@@ -1510,16 +1631,15 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
return error("Invalid record");
IsDistinct = Record[0] & 1;
- bool HasOpFragment = Record[0] & 2;
+ uint64_t Version = Record[0] >> 1;
auto Elts = MutableArrayRef<uint64_t>(Record).slice(1);
- if (!HasOpFragment)
- if (unsigned N = Elts.size())
- if (N >= 3 && Elts[N - 3] == dwarf::DW_OP_bit_piece)
- Elts[N - 3] = dwarf::DW_OP_LLVM_fragment;
+
+ SmallVector<uint64_t, 6> Buffer;
+ if (Error Err = upgradeDIExpression(Version, Elts, Buffer))
+ return Err;
MetadataList.assignValue(
- GET_OR_DISTINCT(DIExpression, (Context, makeArrayRef(Record).slice(1))),
- NextMetadataNo);
+ GET_OR_DISTINCT(DIExpression, (Context, Elts)), NextMetadataNo);
NextMetadataNo++;
break;
}
@@ -1551,15 +1671,17 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_IMPORTED_ENTITY: {
- if (Record.size() != 6)
+ if (Record.size() != 6 && Record.size() != 7)
return error("Invalid record");
IsDistinct = Record[0];
+ bool HasFile = (Record.size() == 7);
MetadataList.assignValue(
GET_OR_DISTINCT(DIImportedEntity,
(Context, Record[1], getMDOrNull(Record[2]),
- getDITypeRefOrNull(Record[3]), Record[4],
- getMDString(Record[5]))),
+ getDITypeRefOrNull(Record[3]),
+ HasFile ? getMDOrNull(Record[6]) : nullptr,
+ HasFile ? Record[4] : 0, getMDString(Record[5]))),
NextMetadataNo);
NextMetadataNo++;
break;
@@ -1611,7 +1733,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
Error MetadataLoader::MetadataLoaderImpl::parseMetadataStrings(
ArrayRef<uint64_t> Record, StringRef Blob,
- std::function<void(StringRef)> CallBack) {
+ function_ref<void(StringRef)> CallBack) {
// All the MDStrings in the block are emitted together in a single
// record. The strings are concatenated and stored in a blob along with
// their sizes.
@@ -1808,8 +1930,8 @@ MetadataLoader::MetadataLoader(BitstreamCursor &Stream, Module &TheModule,
BitcodeReaderValueList &ValueList,
bool IsImporting,
std::function<Type *(unsigned)> getTypeByID)
- : Pimpl(llvm::make_unique<MetadataLoaderImpl>(Stream, TheModule, ValueList,
- getTypeByID, IsImporting)) {}
+ : Pimpl(llvm::make_unique<MetadataLoaderImpl>(
+ Stream, TheModule, ValueList, std::move(getTypeByID), IsImporting)) {}
Error MetadataLoader::parseMetadata(bool ModuleLevel) {
return Pimpl->parseMetadata(ModuleLevel);
@@ -1848,3 +1970,7 @@ bool MetadataLoader::isStrippingTBAA() { return Pimpl->isStrippingTBAA(); }
unsigned MetadataLoader::size() const { return Pimpl->size(); }
void MetadataLoader::shrinkTo(unsigned N) { return Pimpl->shrinkTo(N); }
+
+void MetadataLoader::upgradeDebugIntrinsics(Function &F) {
+ return Pimpl->upgradeDebugIntrinsics(F);
+}
diff --git a/contrib/llvm/lib/Bitcode/Reader/MetadataLoader.h b/contrib/llvm/lib/Bitcode/Reader/MetadataLoader.h
index 442dfc9..f23dcc0 100644
--- a/contrib/llvm/lib/Bitcode/Reader/MetadataLoader.h
+++ b/contrib/llvm/lib/Bitcode/Reader/MetadataLoader.h
@@ -79,6 +79,9 @@ public:
unsigned size() const;
void shrinkTo(unsigned N);
+
+ /// Perform bitcode upgrades on llvm.dbg.* calls.
+ void upgradeDebugIntrinsics(Function &F);
};
}
diff --git a/contrib/llvm/lib/Bitcode/Reader/ValueList.cpp b/contrib/llvm/lib/Bitcode/Reader/ValueList.cpp
index 7152a51..f2a3439 100644
--- a/contrib/llvm/lib/Bitcode/Reader/ValueList.cpp
+++ b/contrib/llvm/lib/Bitcode/Reader/ValueList.cpp
@@ -58,7 +58,7 @@ void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) {
if (Idx >= size())
resize(Idx + 1);
- WeakVH &OldV = ValuePtrs[Idx];
+ WeakTrackingVH &OldV = ValuePtrs[Idx];
if (!OldV) {
OldV = V;
return;
@@ -73,7 +73,7 @@ void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) {
// If there was a forward reference to this value, replace it.
Value *PrevVal = OldV;
OldV->replaceAllUsesWith(V);
- delete PrevVal;
+ PrevVal->deleteValue();
}
}
@@ -194,6 +194,6 @@ void BitcodeReaderValueList::resolveConstantForwardRefs() {
// Update all ValueHandles, they should be the only users at this point.
Placeholder->replaceAllUsesWith(RealVal);
- delete Placeholder;
+ Placeholder->deleteValue();
}
}
diff --git a/contrib/llvm/lib/Bitcode/Reader/ValueList.h b/contrib/llvm/lib/Bitcode/Reader/ValueList.h
index 3119d77..72775a3 100644
--- a/contrib/llvm/lib/Bitcode/Reader/ValueList.h
+++ b/contrib/llvm/lib/Bitcode/Reader/ValueList.h
@@ -20,7 +20,7 @@ namespace llvm {
class Constant;
class BitcodeReaderValueList {
- std::vector<WeakVH> ValuePtrs;
+ std::vector<WeakTrackingVH> ValuePtrs;
/// As we resolve forward-referenced constants, we add information about them
/// to this vector. This allows us to resolve them in bulk instead of
OpenPOWER on IntegriCloud