summaryrefslogtreecommitdiff
path: root/lib/Bitcode
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:01:22 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:01:22 +0000
commit71d5a2540a98c81f5bcaeb48805e0e2881f530ef (patch)
tree5343938942df402b49ec7300a1c25a2d4ccd5821 /lib/Bitcode
parent31bbf64f3a4974a2d6c8b3b27ad2f519caf74057 (diff)
Notes
Diffstat (limited to 'lib/Bitcode')
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp658
-rw-r--r--lib/Bitcode/Reader/MetadataLoader.cpp36
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp155
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.cpp11
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.h22
5 files changed, 510 insertions, 372 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index a46e49ccde83e..24ab7e9a950cc 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -379,6 +379,8 @@ protected:
BitstreamBlockInfo BlockInfo;
BitstreamCursor Stream;
+ Expected<unsigned> parseVersionRecord(ArrayRef<uint64_t> Record);
+
bool readBlockInfo();
// Contains an arbitrary and optional string identifying the bitcode producer
@@ -395,6 +397,16 @@ 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 > 1)
+ return error("Invalid value");
+ return ModuleVersion;
+}
+
class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
LLVMContext &Context;
Module *TheModule = nullptr;
@@ -405,6 +417,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 +434,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.
@@ -520,10 +535,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,6 +613,13 @@ 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();
@@ -971,6 +993,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;
}
@@ -1132,7 +1156,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 +1186,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 +1197,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;
}
@@ -1391,7 +1415,7 @@ Error BitcodeReader::parseAttributeGroupBlock() {
}
}
- MAttributeGroups[GrpID] = AttributeSet::get(Context, Idx, B);
+ MAttributeGroups[GrpID] = AttributeList::get(Context, Idx, B);
break;
}
}
@@ -1794,22 +1818,16 @@ 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);
- }
+ auto *F = dyn_cast<Function>(V);
+ // Ignore function offsets emitted for aliases of functions in older
+ // versions of LLVM.
+ if (!F)
+ break;
// 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.
@@ -2607,6 +2625,246 @@ bool BitcodeReaderBase::readBlockInfo() {
return false;
}
+Error BitcodeReader::parseComdatRecord(ArrayRef<uint64_t> Record) {
+ // [selection_kind, name]
+ if (Record.size() < 2)
+ return error("Invalid record");
+ Comdat::SelectionKind SK = getDecodedComdatSelectionKind(Record[0]);
+ std::string Name;
+ unsigned ComdatNameSize = Record[1];
+ Name.reserve(ComdatNameSize);
+ for (unsigned i = 0; i != ComdatNameSize; ++i)
+ Name += (char)Record[2 + i];
+ Comdat *C = TheModule->getOrInsertComdat(Name);
+ C->setSelectionKind(SK);
+ ComdatList.push_back(C);
+ return Error::success();
+}
+
+Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
+ // [pointer type, isconst, initid, linkage, alignment, section,
+ // visibility, threadlocal, unnamed_addr, externally_initialized,
+ // dllstorageclass, comdat]
+ 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, "",
+ 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));
+ }
+ return Error::success();
+}
+
+Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
+ // [type, callingconv, isproto, linkage, paramattr, alignment, section,
+ // visibility, gc, unnamed_addr, prologuedata, dllstorageclass, comdat,
+ // prefixdata]
+ 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))
+ 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) {
+ // ALIAS_OLD: [alias type, aliasee val#, linkage]
+ // ALIAS: [alias type, addrspace, aliasee val#, linkage, visibility,
+ // dllstorageclass]
+ // IFUNC: [alias type, addrspace, aliasee val#, linkage,
+ // visibility, dllstorageclass]
+ 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));
+ return Error::success();
+}
+
Error BitcodeReader::parseModule(uint64_t ResumeBit,
bool ShouldLazyLoadMetadata) {
if (ResumeBit)
@@ -2615,8 +2873,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) {
@@ -2762,21 +3018,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 +3068,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 +3865,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 +4042,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;
@@ -4225,7 +4255,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;
@@ -4753,33 +4783,13 @@ 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]
+ // GLOBALVAR: [pointer type, isconst, initid, linkage, ...]
+ // FUNCTION: [type, callingconv, isproto, linkage, ...]
+ // ALIAS: [alias type, addrspace, aliasee val#, linkage, ...]
+ case bitc::MODULE_CODE_GLOBALVAR:
+ case bitc::MODULE_CODE_FUNCTION:
case bitc::MODULE_CODE_ALIAS: {
- if (Record.size() < 6)
+ if (Record.size() <= 3)
return error("Invalid record");
uint64_t RawLinkage = Record[3];
GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage);
@@ -4846,8 +4856,17 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
// Keep around the last seen summary to be used when we see an optional
// "OriginalName" attachement.
GlobalValueSummary *LastSeenSummary = nullptr;
+ GlobalValue::GUID LastSeenGUID = 0;
bool Combined = false;
+
+ // 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();
@@ -4914,8 +4933,15 @@ 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();
+ PendingTypeTestAssumeVCalls.clear();
+ PendingTypeCheckedLoadVCalls.clear();
+ PendingTypeTestAssumeConstVCalls.clear();
+ PendingTypeCheckedLoadConstVCalls.clear();
auto GUID = getGUIDFromValueId(ValueID);
FS->setModulePath(TheIndex.addModulePath(ModulePath, 0)->first());
FS->setOriginalName(GUID.second);
@@ -4989,9 +5015,17 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
GlobalValue::GUID GUID = getGUIDFromValueId(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 = GUID;
FS->setModulePath(ModuleIdMap[ModuleId]);
TheIndex.addGlobalValueSummary(GUID, std::move(FS));
Combined = true;
@@ -5018,6 +5052,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
AS->setAliasee(AliaseeInModule);
GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first;
+ LastSeenGUID = GUID;
TheIndex.addGlobalValueSummary(GUID, std::move(AS));
Combined = true;
break;
@@ -5034,6 +5069,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
LastSeenSummary = FS.get();
FS->setModulePath(ModuleIdMap[ModuleId]);
GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first;
+ LastSeenGUID = GUID;
TheIndex.addGlobalValueSummary(GUID, std::move(FS));
Combined = true;
break;
@@ -5044,8 +5080,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 +5092,28 @@ 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;
+ }
}
}
llvm_unreachable("Exit infinite loop");
diff --git a/lib/Bitcode/Reader/MetadataLoader.cpp b/lib/Bitcode/Reader/MetadataLoader.cpp
index b89f5be4a3692..274dfe89cce54 100644
--- a/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -358,6 +358,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);
@@ -457,7 +460,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);
@@ -520,7 +523,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);
@@ -564,7 +567,7 @@ public:
void shrinkTo(unsigned N) { MetadataList.shrinkTo(N); }
};
-Error error(const Twine &Message) {
+static Error error(const Twine &Message) {
return make_error<StringError>(
Message, make_error_code(BitcodeError::CorruptedBitcode));
}
@@ -1107,9 +1110,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 +1127,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 +1250,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 +1263,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++;
@@ -1433,6 +1444,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 +1475,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 +1495,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;
@@ -1611,7 +1621,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 +1818,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);
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index ebb2022551f78..043441bac4dea 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -108,6 +108,14 @@ class ModuleBitcodeWriter : public BitcodeWriterBase {
/// True if a module hash record should be written.
bool GenerateHash;
+ /// If non-null, when GenerateHash is true, the resulting hash is written
+ /// into ModHash. When GenerateHash is false, that specified value
+ /// is used as the hash instead of computing from the generated bitcode.
+ /// Can be used to produce the same module hash for a minimized bitcode
+ /// used just for the thin link as in the regular full bitcode that will
+ /// be used in the backend.
+ ModuleHash *ModHash;
+
/// The start bit of the identification block.
uint64_t BitcodeStartBit;
@@ -124,10 +132,12 @@ public:
/// writing to the provided \p Buffer.
ModuleBitcodeWriter(const Module *M, SmallVectorImpl<char> &Buffer,
BitstreamWriter &Stream, bool ShouldPreserveUseListOrder,
- const ModuleSummaryIndex *Index, bool GenerateHash)
+ const ModuleSummaryIndex *Index, bool GenerateHash,
+ ModuleHash *ModHash = nullptr)
: BitcodeWriterBase(Stream), Buffer(Buffer), M(*M),
VE(*M, ShouldPreserveUseListOrder), Index(Index),
- GenerateHash(GenerateHash), BitcodeStartBit(Stream.GetCurrentBitNo()) {
+ GenerateHash(GenerateHash), ModHash(ModHash),
+ BitcodeStartBit(Stream.GetCurrentBitNo()) {
// Assign ValueIds to any callee values in the index that came from
// indirect call profiles and were recorded as a GUID not a Value*
// (which would have been assigned an ID by the ValueEnumerator).
@@ -466,7 +476,6 @@ public:
void write();
private:
- void writeIndex();
void writeModStrings();
void writeCombinedValueSymbolTable();
void writeCombinedGlobalValueSummary();
@@ -709,22 +718,22 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
}
void ModuleBitcodeWriter::writeAttributeGroupTable() {
- const std::vector<AttributeSet> &AttrGrps = VE.getAttributeGroups();
+ const std::vector<AttributeList> &AttrGrps = VE.getAttributeGroups();
if (AttrGrps.empty()) return;
Stream.EnterSubblock(bitc::PARAMATTR_GROUP_BLOCK_ID, 3);
SmallVector<uint64_t, 64> Record;
for (unsigned i = 0, e = AttrGrps.size(); i != e; ++i) {
- AttributeSet AS = AttrGrps[i];
+ AttributeList AS = AttrGrps[i];
for (unsigned i = 0, e = AS.getNumSlots(); i != e; ++i) {
- AttributeSet A = AS.getSlotAttributes(i);
+ AttributeList A = AS.getSlotAttributes(i);
Record.push_back(VE.getAttributeGroupID(A));
Record.push_back(AS.getSlotIndex(i));
- for (AttributeSet::iterator I = AS.begin(0), E = AS.end(0);
- I != E; ++I) {
+ for (AttributeList::iterator I = AS.begin(0), E = AS.end(0); I != E;
+ ++I) {
Attribute Attr = *I;
if (Attr.isEnumAttribute()) {
Record.push_back(0);
@@ -756,14 +765,14 @@ void ModuleBitcodeWriter::writeAttributeGroupTable() {
}
void ModuleBitcodeWriter::writeAttributeTable() {
- const std::vector<AttributeSet> &Attrs = VE.getAttributes();
+ const std::vector<AttributeList> &Attrs = VE.getAttributes();
if (Attrs.empty()) return;
Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3);
SmallVector<uint64_t, 64> Record;
for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
- const AttributeSet &A = Attrs[i];
+ const AttributeList &A = Attrs[i];
for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i)
Record.push_back(VE.getAttributeGroupID(A.getSlotAttributes(i)));
@@ -1326,6 +1335,8 @@ static uint64_t getOptimizationFlags(const Value *V) {
Flags |= FastMathFlags::NoSignedZeros;
if (FPMO->hasAllowReciprocal())
Flags |= FastMathFlags::AllowReciprocal;
+ if (FPMO->hasAllowContract())
+ Flags |= FastMathFlags::AllowContract;
}
return Flags;
@@ -1473,6 +1484,13 @@ void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N,
Record.push_back(N->getFlags());
Record.push_back(VE.getMetadataOrNullID(N->getExtraData()));
+ // DWARF address space is encoded as N->getDWARFAddressSpace() + 1. 0 means
+ // that there is no DWARF address space associated with DIDerivedType.
+ if (const auto &DWARFAddressSpace = N->getDWARFAddressSpace())
+ Record.push_back(*DWARFAddressSpace + 1);
+ else
+ Record.push_back(0);
+
Stream.EmitRecord(bitc::METADATA_DERIVED_TYPE, Record, Abbrev);
Record.clear();
}
@@ -1549,6 +1567,7 @@ void ModuleBitcodeWriter::writeDICompileUnit(const DICompileUnit *N,
Record.push_back(N->getDWOId());
Record.push_back(VE.getMetadataOrNullID(N->getMacros().get()));
Record.push_back(N->getSplitDebugInlining());
+ Record.push_back(N->getDebugInfoForProfiling());
Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev);
Record.clear();
@@ -2559,7 +2578,7 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
pushValue(SI.getCondition(), InstID, Vals);
Vals.push_back(VE.getValueID(SI.getDefaultDest()));
- for (SwitchInst::ConstCaseIt Case : SI.cases()) {
+ for (auto Case : SI.cases()) {
Vals.push_back(VE.getValueID(Case.getCaseValue()));
Vals.push_back(VE.getValueID(Case.getCaseSuccessor()));
}
@@ -2905,13 +2924,6 @@ void ModuleBitcodeWriter::writeValueSymbolTable(
NameVals.push_back(VE.getValueID(Name.getValue()));
Function *F = dyn_cast<Function>(Name.getValue());
- if (!F) {
- // If value is an alias, need to get the aliased base object to
- // see if it is a function.
- auto *GA = dyn_cast<GlobalAlias>(Name.getValue());
- if (GA && GA->getBaseObject())
- F = dyn_cast<Function>(GA->getBaseObject());
- }
// VST_CODE_ENTRY: [valueid, namechar x N]
// VST_CODE_FNENTRY: [valueid, funcoffset, namechar x N]
@@ -3367,6 +3379,49 @@ void IndexBitcodeWriter::writeModStrings() {
Stream.ExitBlock();
}
+/// Write the function type metadata related records that need to appear before
+/// a function summary entry (whether per-module or combined).
+static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream,
+ FunctionSummary *FS) {
+ if (!FS->type_tests().empty())
+ Stream.EmitRecord(bitc::FS_TYPE_TESTS, FS->type_tests());
+
+ SmallVector<uint64_t, 64> Record;
+
+ auto WriteVFuncIdVec = [&](uint64_t Ty,
+ ArrayRef<FunctionSummary::VFuncId> VFs) {
+ if (VFs.empty())
+ return;
+ Record.clear();
+ for (auto &VF : VFs) {
+ Record.push_back(VF.GUID);
+ Record.push_back(VF.Offset);
+ }
+ Stream.EmitRecord(Ty, Record);
+ };
+
+ WriteVFuncIdVec(bitc::FS_TYPE_TEST_ASSUME_VCALLS,
+ FS->type_test_assume_vcalls());
+ WriteVFuncIdVec(bitc::FS_TYPE_CHECKED_LOAD_VCALLS,
+ FS->type_checked_load_vcalls());
+
+ auto WriteConstVCallVec = [&](uint64_t Ty,
+ ArrayRef<FunctionSummary::ConstVCall> VCs) {
+ for (auto &VC : VCs) {
+ Record.clear();
+ Record.push_back(VC.VFunc.GUID);
+ Record.push_back(VC.VFunc.Offset);
+ Record.insert(Record.end(), VC.Args.begin(), VC.Args.end());
+ Stream.EmitRecord(Ty, Record);
+ }
+ };
+
+ WriteConstVCallVec(bitc::FS_TYPE_TEST_ASSUME_CONST_VCALL,
+ FS->type_test_assume_const_vcalls());
+ WriteConstVCallVec(bitc::FS_TYPE_CHECKED_LOAD_CONST_VCALL,
+ FS->type_checked_load_const_vcalls());
+}
+
// Helper to emit a single function summary record.
void ModuleBitcodeWriter::writePerModuleFunctionSummaryRecord(
SmallVector<uint64_t, 64> &NameVals, GlobalValueSummary *Summary,
@@ -3375,8 +3430,7 @@ void ModuleBitcodeWriter::writePerModuleFunctionSummaryRecord(
NameVals.push_back(ValueID);
FunctionSummary *FS = cast<FunctionSummary>(Summary);
- if (!FS->type_tests().empty())
- Stream.EmitRecord(bitc::FS_TYPE_TESTS, FS->type_tests());
+ writeFunctionTypeMetadataRecords(Stream, FS);
NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
NameVals.push_back(FS->instCount());
@@ -3636,8 +3690,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
}
auto *FS = cast<FunctionSummary>(S);
- if (!FS->type_tests().empty())
- Stream.EmitRecord(bitc::FS_TYPE_TESTS, FS->type_tests());
+ writeFunctionTypeMetadataRecords(Stream, FS);
NameVals.push_back(ValueId);
NameVals.push_back(Index.getModuleId(FS->modulePath()));
@@ -3659,9 +3712,16 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
for (auto &EI : FS->calls()) {
// If this GUID doesn't have a value id, it doesn't have a function
// summary and we don't need to record any calls to it.
- if (!hasValueId(EI.first.getGUID()))
- continue;
- NameVals.push_back(getValueId(EI.first.getGUID()));
+ GlobalValue::GUID GUID = EI.first.getGUID();
+ if (!hasValueId(GUID)) {
+ // For SamplePGO, the indirect call targets for local functions will
+ // have its original name annotated in profile. We try to find the
+ // corresponding PGOFuncName as the GUID.
+ GUID = Index.getGUIDFromOriginalID(GUID);
+ if (GUID == 0 || !hasValueId(GUID))
+ continue;
+ }
+ NameVals.push_back(getValueId(GUID));
if (HasProfileData)
NameVals.push_back(static_cast<uint8_t>(EI.second.Hotness));
}
@@ -3697,7 +3757,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
/// Create the "IDENTIFICATION_BLOCK_ID" containing a single string with the
/// current llvm version, and a record for the epoch number.
-void writeIdentificationBlock(BitstreamWriter &Stream) {
+static void writeIdentificationBlock(BitstreamWriter &Stream) {
Stream.EnterSubblock(bitc::IDENTIFICATION_BLOCK_ID, 5);
// Write the "user readable" string identifying the bitcode producer
@@ -3722,17 +3782,24 @@ void writeIdentificationBlock(BitstreamWriter &Stream) {
void ModuleBitcodeWriter::writeModuleHash(size_t BlockStartPos) {
// Emit the module's hash.
// MODULE_CODE_HASH: [5*i32]
- SHA1 Hasher;
- Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&(Buffer)[BlockStartPos],
- Buffer.size() - BlockStartPos));
- StringRef Hash = Hasher.result();
- uint32_t Vals[5];
- for (int Pos = 0; Pos < 20; Pos += 4) {
- Vals[Pos / 4] = support::endian::read32be(Hash.data() + Pos);
- }
+ if (GenerateHash) {
+ SHA1 Hasher;
+ uint32_t Vals[5];
+ Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&(Buffer)[BlockStartPos],
+ Buffer.size() - BlockStartPos));
+ StringRef Hash = Hasher.result();
+ for (int Pos = 0; Pos < 20; Pos += 4) {
+ Vals[Pos / 4] = support::endian::read32be(Hash.data() + Pos);
+ }
- // Emit the finished record.
- Stream.EmitRecord(bitc::MODULE_CODE_HASH, Vals);
+ // Emit the finished record.
+ Stream.EmitRecord(bitc::MODULE_CODE_HASH, Vals);
+
+ if (ModHash)
+ // Save the written hash value.
+ std::copy(std::begin(Vals), std::end(Vals), std::begin(*ModHash));
+ } else if (ModHash)
+ Stream.EmitRecord(bitc::MODULE_CODE_HASH, ArrayRef<uint32_t>(*ModHash));
}
void ModuleBitcodeWriter::write() {
@@ -3793,9 +3860,7 @@ void ModuleBitcodeWriter::write() {
writeValueSymbolTable(M.getValueSymbolTable(),
/* IsModuleLevel */ true, &FunctionToBitcodeIndex);
- if (GenerateHash) {
- writeModuleHash(BlockStartPos);
- }
+ writeModuleHash(BlockStartPos);
Stream.ExitBlock();
}
@@ -3886,9 +3951,10 @@ BitcodeWriter::~BitcodeWriter() = default;
void BitcodeWriter::writeModule(const Module *M,
bool ShouldPreserveUseListOrder,
const ModuleSummaryIndex *Index,
- bool GenerateHash) {
- ModuleBitcodeWriter ModuleWriter(
- M, Buffer, *Stream, ShouldPreserveUseListOrder, Index, GenerateHash);
+ bool GenerateHash, ModuleHash *ModHash) {
+ ModuleBitcodeWriter ModuleWriter(M, Buffer, *Stream,
+ ShouldPreserveUseListOrder, Index,
+ GenerateHash, ModHash);
ModuleWriter.write();
}
@@ -3897,7 +3963,7 @@ void BitcodeWriter::writeModule(const Module *M,
void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,
bool ShouldPreserveUseListOrder,
const ModuleSummaryIndex *Index,
- bool GenerateHash) {
+ bool GenerateHash, ModuleHash *ModHash) {
SmallVector<char, 0> Buffer;
Buffer.reserve(256*1024);
@@ -3908,7 +3974,8 @@ void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,
Buffer.insert(Buffer.begin(), BWH_HeaderSize, 0);
BitcodeWriter Writer(Buffer);
- Writer.writeModule(M, ShouldPreserveUseListOrder, Index, GenerateHash);
+ Writer.writeModule(M, ShouldPreserveUseListOrder, Index, GenerateHash,
+ ModHash);
if (TT.isOSDarwin() || TT.isOSBinFormatMachO())
emitDarwinBCHeaderAndTrailer(Buffer, TT);
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp
index 5d5bfab58b81e..3800d9abd429a 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -432,12 +432,14 @@ unsigned ValueEnumerator::getValueID(const Value *V) const {
return I->second-1;
}
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void ValueEnumerator::dump() const {
print(dbgs(), ValueMap, "Default");
dbgs() << '\n';
print(dbgs(), MetadataMap, "MetaData");
dbgs() << '\n';
}
+#endif
void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
const char *Name) const {
@@ -452,7 +454,8 @@ void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
OS << "Value: " << V->getName();
else
OS << "Value: [null]\n";
- V->dump();
+ V->print(errs());
+ errs() << '\n';
OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):";
for (const Use &U : V->uses()) {
@@ -549,7 +552,7 @@ void ValueEnumerator::EnumerateFunctionLocalMetadata(
void ValueEnumerator::dropFunctionFromMetadata(
MetadataMapType::value_type &FirstMD) {
SmallVector<const MDNode *, 64> Worklist;
- auto push = [this, &Worklist](MetadataMapType::value_type &MD) {
+ auto push = [&Worklist](MetadataMapType::value_type &MD) {
auto &Entry = MD.second;
// Nothing to do if this metadata isn't tagged.
@@ -884,7 +887,7 @@ void ValueEnumerator::EnumerateOperandType(const Value *V) {
}
}
-void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
+void ValueEnumerator::EnumerateAttributes(AttributeList PAL) {
if (PAL.isEmpty()) return; // null is always 0.
// Do a lookup.
@@ -897,7 +900,7 @@ void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
// Do lookups for all attribute groups.
for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) {
- AttributeSet AS = PAL.getSlotAttributes(i);
+ AttributeList AS = PAL.getSlotAttributes(i);
unsigned &Entry = AttributeGroupMap[AS];
if (Entry == 0) {
AttributeGroups.push_back(AS);
diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h
index a8d6cf965a4b4..8a82aab298363 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.h
+++ b/lib/Bitcode/Writer/ValueEnumerator.h
@@ -36,7 +36,7 @@ class LocalAsMetadata;
class MDNode;
class MDOperand;
class NamedMDNode;
-class AttributeSet;
+class AttributeList;
class ValueSymbolTable;
class MDSymbolTable;
class raw_ostream;
@@ -102,13 +102,13 @@ private:
bool ShouldPreserveUseListOrder;
- typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType;
+ typedef DenseMap<AttributeList, unsigned> AttributeGroupMapType;
AttributeGroupMapType AttributeGroupMap;
- std::vector<AttributeSet> AttributeGroups;
+ std::vector<AttributeList> AttributeGroups;
- typedef DenseMap<AttributeSet, unsigned> AttributeMapType;
+ typedef DenseMap<AttributeList, unsigned> AttributeMapType;
AttributeMapType AttributeMap;
- std::vector<AttributeSet> Attribute;
+ std::vector<AttributeList> Attribute;
/// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by
/// the "getGlobalBasicBlockID" method.
@@ -166,14 +166,14 @@ public:
unsigned getInstructionID(const Instruction *I) const;
void setInstructionID(const Instruction *I);
- unsigned getAttributeID(AttributeSet PAL) const {
+ unsigned getAttributeID(AttributeList PAL) const {
if (PAL.isEmpty()) return 0; // Null maps to zero.
AttributeMapType::const_iterator I = AttributeMap.find(PAL);
assert(I != AttributeMap.end() && "Attribute not in ValueEnumerator!");
return I->second;
}
- unsigned getAttributeGroupID(AttributeSet PAL) const {
+ unsigned getAttributeGroupID(AttributeList PAL) const {
if (PAL.isEmpty()) return 0; // Null maps to zero.
AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(PAL);
assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!");
@@ -206,10 +206,8 @@ public:
const std::vector<const BasicBlock*> &getBasicBlocks() const {
return BasicBlocks;
}
- const std::vector<AttributeSet> &getAttributes() const {
- return Attribute;
- }
- const std::vector<AttributeSet> &getAttributeGroups() const {
+ const std::vector<AttributeList> &getAttributes() const { return Attribute; }
+ const std::vector<AttributeList> &getAttributeGroups() const {
return AttributeGroups;
}
@@ -283,7 +281,7 @@ private:
void EnumerateValue(const Value *V);
void EnumerateType(Type *T);
void EnumerateOperandType(const Value *V);
- void EnumerateAttributes(AttributeSet PAL);
+ void EnumerateAttributes(AttributeList PAL);
void EnumerateValueSymbolTable(const ValueSymbolTable &ST);
void EnumerateNamedMetadata(const Module &M);