summaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/Bitcode
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp2
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp639
-rw-r--r--llvm/lib/Bitcode/Reader/MetadataLoader.cpp20
-rw-r--r--llvm/lib/Bitcode/Reader/ValueList.cpp12
-rw-r--r--llvm/lib/Bitcode/Reader/ValueList.h20
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp69
-rw-r--r--llvm/lib/Bitcode/Writer/ValueEnumerator.cpp127
-rw-r--r--llvm/lib/Bitcode/Writer/ValueEnumerator.h4
8 files changed, 549 insertions, 344 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
index e91af121ea08..f577d3886e01 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
@@ -218,6 +218,7 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID,
STRINGIFY_CODE(CST_CODE, INLINEASM)
STRINGIFY_CODE(CST_CODE, CE_SHUFVEC_EX)
STRINGIFY_CODE(CST_CODE, CE_UNOP)
+ STRINGIFY_CODE(CST_CODE, DSO_LOCAL_EQUIVALENT)
case bitc::CST_CODE_BLOCKADDRESS:
return "CST_CODE_BLOCKADDRESS";
STRINGIFY_CODE(CST_CODE, DATA)
@@ -361,6 +362,7 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID,
STRINGIFY_CODE(METADATA, GLOBAL_VAR_EXPR)
STRINGIFY_CODE(METADATA, INDEX_OFFSET)
STRINGIFY_CODE(METADATA, INDEX)
+ STRINGIFY_CODE(METADATA, ARG_LIST)
}
case bitc::METADATA_KIND_BLOCK_ID:
switch (CodeID) {
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index f2800201e871..d5e366c21f7d 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -593,42 +593,12 @@ private:
StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name);
StructType *createIdentifiedStructType(LLVMContext &Context);
- /// Map all pointer types within \param Ty to the opaque pointer
- /// type in the same address space if opaque pointers are being
- /// used, otherwise nop. This converts a bitcode-reader internal
- /// type into one suitable for use in a Value.
- Type *flattenPointerTypes(Type *Ty) {
- return Ty;
- }
-
- /// Given a fully structured pointer type (i.e. not opaque), return
- /// the flattened form of its element, suitable for use in a Value.
- Type *getPointerElementFlatType(Type *Ty) {
- return flattenPointerTypes(cast<PointerType>(Ty)->getElementType());
- }
-
- /// Given a fully structured pointer type, get its element type in
- /// both fully structured form, and flattened form suitable for use
- /// in a Value.
- std::pair<Type *, Type *> getPointerElementTypes(Type *FullTy) {
- Type *ElTy = cast<PointerType>(FullTy)->getElementType();
- return std::make_pair(ElTy, flattenPointerTypes(ElTy));
- }
-
- /// Return the flattened type (suitable for use in a Value)
- /// specified by the given \param ID .
- Type *getTypeByID(unsigned ID) {
- return flattenPointerTypes(getFullyStructuredTypeByID(ID));
- }
+ Type *getTypeByID(unsigned ID);
- /// Return the fully structured (bitcode-reader internal) type
- /// corresponding to the given \param ID .
- Type *getFullyStructuredTypeByID(unsigned ID);
-
- Value *getFnValueByID(unsigned ID, Type *Ty, Type **FullTy = nullptr) {
+ Value *getFnValueByID(unsigned ID, Type *Ty) {
if (Ty && Ty->isMetadataTy())
return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID));
- return ValueList.getValueFwdRef(ID, Ty, FullTy);
+ return ValueList.getValueFwdRef(ID, Ty);
}
Metadata *getFnMetadataByID(unsigned ID) {
@@ -650,8 +620,7 @@ private:
/// Increment Slot past the number of slots used in the record. Return true on
/// failure.
bool getValueTypePair(const SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
- unsigned InstNum, Value *&ResVal,
- Type **FullTy = nullptr) {
+ unsigned InstNum, Value *&ResVal) {
if (Slot == Record.size()) return true;
unsigned ValNo = (unsigned)Record[Slot++];
// Adjust the ValNo, if it was encoded relative to the InstNum.
@@ -660,7 +629,7 @@ private:
if (ValNo < InstNum) {
// If this is not a forward reference, just return the value we already
// have.
- ResVal = getFnValueByID(ValNo, nullptr, FullTy);
+ ResVal = getFnValueByID(ValNo, nullptr);
return ResVal == nullptr;
}
if (Slot == Record.size())
@@ -668,8 +637,6 @@ private:
unsigned TypeNo = (unsigned)Record[Slot++];
ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo));
- if (FullTy)
- *FullTy = getFullyStructuredTypeByID(TypeNo);
return ResVal == nullptr;
}
@@ -715,9 +682,10 @@ private:
return getFnValueByID(ValNo, Ty);
}
- /// Upgrades old-style typeless byval or sret attributes by adding the
- /// corresponding argument's pointee type.
- void propagateByValSRetTypes(CallBase *CB, ArrayRef<Type *> ArgsFullTys);
+ /// Upgrades old-style typeless byval/sret/inalloca attributes by adding the
+ /// corresponding argument's pointee type. Also upgrades intrinsics that now
+ /// require an elementtype attribute.
+ void propagateAttributeTypes(CallBase *CB, ArrayRef<Type *> ArgsTys);
/// Converts alignment exponent (i.e. power of two (or zero)) to the
/// corresponding alignment to use. If alignment is too large, returns
@@ -968,13 +936,17 @@ static FunctionSummary::FFlags getDecodedFFlags(uint64_t RawFlags) {
return Flags;
}
-/// Decode the flags for GlobalValue in the summary.
+// Decode the flags for GlobalValue in the summary. The bits for each attribute:
+//
+// linkage: [0,4), notEligibleToImport: 4, live: 5, local: 6, canAutoHide: 7,
+// visibility: [8, 10).
static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags,
uint64_t Version) {
// Summary were not emitted before LLVM 3.9, we don't need to upgrade Linkage
// like getDecodedLinkage() above. Any future change to the linkage enum and
// to getDecodedLinkage() will need to be taken into account here as above.
auto Linkage = GlobalValue::LinkageTypes(RawFlags & 0xF); // 4 bits
+ auto Visibility = GlobalValue::VisibilityTypes((RawFlags >> 8) & 3); // 2 bits
RawFlags = RawFlags >> 4;
bool NotEligibleToImport = (RawFlags & 0x1) || Version < 3;
// The Live flag wasn't introduced until version 3. For dead stripping
@@ -984,7 +956,8 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags,
bool Local = (RawFlags & 0x4);
bool AutoHide = (RawFlags & 0x8);
- return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, Live, Local, AutoHide);
+ return GlobalValueSummary::GVFlags(Linkage, Visibility, NotEligibleToImport,
+ Live, Local, AutoHide);
}
// Decode the flags for GlobalVariable in the summary
@@ -1155,7 +1128,7 @@ static Comdat::SelectionKind getDecodedComdatSelectionKind(unsigned Val) {
case bitc::COMDAT_SELECTION_KIND_LARGEST:
return Comdat::Largest;
case bitc::COMDAT_SELECTION_KIND_NO_DUPLICATES:
- return Comdat::NoDuplicates;
+ return Comdat::NoDeduplicate;
case bitc::COMDAT_SELECTION_KIND_SAME_SIZE:
return Comdat::SameSize;
}
@@ -1189,7 +1162,7 @@ static void upgradeDLLImportExportLinkage(GlobalValue *GV, unsigned Val) {
}
}
-Type *BitcodeReader::getFullyStructuredTypeByID(unsigned ID) {
+Type *BitcodeReader::getTypeByID(unsigned ID) {
// The type table size is always specified correctly.
if (ID >= TypeList.size())
return nullptr;
@@ -1307,6 +1280,8 @@ static void addRawAttributeValue(AttrBuilder &B, uint64_t Val) {
B.addAlignmentAttr(1ULL << ((A >> 16) - 1));
else if (I == Attribute::StackAlignment)
B.addStackAlignmentAttr(1ULL << ((A >> 26)-1));
+ else if (Attribute::isTypeAttrKind(I))
+ B.addTypeAttr(I, nullptr); // Type will be auto-upgraded.
else
B.addAttribute(I);
}
@@ -1413,6 +1388,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::Cold;
case bitc::ATTR_KIND_CONVERGENT:
return Attribute::Convergent;
+ case bitc::ATTR_KIND_ELEMENTTYPE:
+ return Attribute::ElementType;
case bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY:
return Attribute::InaccessibleMemOnly;
case bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY:
@@ -1467,8 +1444,12 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::NoSync;
case bitc::ATTR_KIND_NOCF_CHECK:
return Attribute::NoCfCheck;
+ case bitc::ATTR_KIND_NO_PROFILE:
+ return Attribute::NoProfile;
case bitc::ATTR_KIND_NO_UNWIND:
return Attribute::NoUnwind;
+ case bitc::ATTR_KIND_NO_SANITIZE_COVERAGE:
+ return Attribute::NoSanitizeCoverage;
case bitc::ATTR_KIND_NULL_POINTER_IS_VALID:
return Attribute::NullPointerIsValid;
case bitc::ATTR_KIND_OPT_FOR_FUZZING:
@@ -1519,8 +1500,12 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::SwiftError;
case bitc::ATTR_KIND_SWIFT_SELF:
return Attribute::SwiftSelf;
+ case bitc::ATTR_KIND_SWIFT_ASYNC:
+ return Attribute::SwiftAsync;
case bitc::ATTR_KIND_UW_TABLE:
return Attribute::UWTable;
+ case bitc::ATTR_KIND_VSCALE_RANGE:
+ return Attribute::VScaleRange;
case bitc::ATTR_KIND_WILLRETURN:
return Attribute::WillReturn;
case bitc::ATTR_KIND_WRITEONLY:
@@ -1617,12 +1602,18 @@ Error BitcodeReader::parseAttributeGroupBlock() {
B.addByValAttr(nullptr);
else if (Kind == Attribute::StructRet)
B.addStructRetAttr(nullptr);
-
- B.addAttribute(Kind);
+ else if (Kind == Attribute::InAlloca)
+ B.addInAllocaAttr(nullptr);
+ else if (Attribute::isEnumAttrKind(Kind))
+ B.addAttribute(Kind);
+ else
+ return error("Not an enum attribute");
} else if (Record[i] == 1) { // Integer attribute
Attribute::AttrKind Kind;
if (Error Err = parseAttrKind(Record[++i], &Kind))
return Err;
+ if (!Attribute::isIntAttrKind(Kind))
+ return error("Not an int attribute");
if (Kind == Attribute::Alignment)
B.addAlignmentAttr(Record[++i]);
else if (Kind == Attribute::StackAlignment)
@@ -1633,6 +1624,8 @@ Error BitcodeReader::parseAttributeGroupBlock() {
B.addDereferenceableOrNullAttr(Record[++i]);
else if (Kind == Attribute::AllocSize)
B.addAllocSizeAttrFromRawRepr(Record[++i]);
+ else if (Kind == Attribute::VScaleRange)
+ B.addVScaleRangeAttrFromRawRepr(Record[++i]);
} else if (Record[i] == 3 || Record[i] == 4) { // String attribute
bool HasValue = (Record[i++] == 4);
SmallString<64> KindStr;
@@ -1658,15 +1651,10 @@ Error BitcodeReader::parseAttributeGroupBlock() {
Attribute::AttrKind Kind;
if (Error Err = parseAttrKind(Record[++i], &Kind))
return Err;
- if (Kind == Attribute::ByVal) {
- B.addByValAttr(HasType ? getTypeByID(Record[++i]) : nullptr);
- } else if (Kind == Attribute::StructRet) {
- B.addStructRetAttr(HasType ? getTypeByID(Record[++i]) : nullptr);
- } else if (Kind == Attribute::ByRef) {
- B.addByRefAttr(getTypeByID(Record[++i]));
- } else if (Kind == Attribute::Preallocated) {
- B.addPreallocatedAttr(getTypeByID(Record[++i]));
- }
+ if (!Attribute::isTypeAttrKind(Kind))
+ return error("Not a type attribute");
+
+ B.addTypeAttr(Kind, HasType ? getTypeByID(Record[++i]) : nullptr);
}
}
@@ -1794,6 +1782,13 @@ Error BitcodeReader::parseTypeTableBody() {
ResultTy = PointerType::get(ResultTy, AddressSpace);
break;
}
+ case bitc::TYPE_CODE_OPAQUE_POINTER: { // OPAQUE_POINTER: [addrspace]
+ if (Record.size() != 1)
+ return error("Invalid record");
+ unsigned AddressSpace = Record[0];
+ ResultTy = PointerType::get(Context, AddressSpace);
+ break;
+ }
case bitc::TYPE_CODE_FUNCTION_OLD: {
// Deprecated, but still needed to read old bitcode files.
// FUNCTION: [vararg, attrid, retty, paramty x N]
@@ -2345,13 +2340,11 @@ Error BitcodeReader::parseConstants() {
// Read all the records for this value table.
Type *CurTy = Type::getInt32Ty(Context);
- Type *CurFullTy = Type::getInt32Ty(Context);
unsigned NextCstNo = ValueList.size();
struct DelayedShufTy {
VectorType *OpTy;
VectorType *RTy;
- Type *CurFullTy;
uint64_t Op0Idx;
uint64_t Op1Idx;
uint64_t Op2Idx;
@@ -2392,7 +2385,7 @@ Error BitcodeReader::parseConstants() {
SmallVector<int, 16> Mask;
ShuffleVectorInst::getShuffleMask(Op2, Mask);
Value *V = ConstantExpr::getShuffleVector(Op0, Op1, Mask);
- ValueList.assignValue(V, CstNo, DelayedShuffle.CurFullTy);
+ ValueList.assignValue(V, CstNo);
}
if (NextCstNo != ValueList.size())
@@ -2427,8 +2420,7 @@ Error BitcodeReader::parseConstants() {
return error("Invalid record");
if (TypeList[Record[0]] == VoidType)
return error("Invalid constant type");
- CurFullTy = TypeList[Record[0]];
- CurTy = flattenPointerTypes(CurFullTy);
+ CurTy = TypeList[Record[0]];
continue; // Skip the ValueList manipulation.
case bitc::CST_CODE_NULL: // NULL
if (CurTy->isVoidTy() || CurTy->isFunctionTy() || CurTy->isLabelTy())
@@ -2665,7 +2657,7 @@ Error BitcodeReader::parseConstants() {
Type *Elt0FullTy = nullptr;
while (OpNum != Record.size()) {
if (!Elt0FullTy)
- Elt0FullTy = getFullyStructuredTypeByID(Record[OpNum]);
+ Elt0FullTy = getTypeByID(Record[OpNum]);
Type *ElTy = getTypeByID(Record[OpNum++]);
if (!ElTy)
return error("Invalid record");
@@ -2675,11 +2667,10 @@ Error BitcodeReader::parseConstants() {
if (Elts.size() < 1)
return error("Invalid gep with no operands");
- Type *ImplicitPointeeType =
- getPointerElementFlatType(Elt0FullTy->getScalarType());
+ PointerType *OrigPtrTy = cast<PointerType>(Elt0FullTy->getScalarType());
if (!PointeeType)
- PointeeType = ImplicitPointeeType;
- else if (PointeeType != ImplicitPointeeType)
+ PointeeType = OrigPtrTy->getElementType();
+ else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType))
return error("Explicit gep operator type does not match pointee type "
"of pointer operand");
@@ -2760,7 +2751,7 @@ Error BitcodeReader::parseConstants() {
if (Record.size() < 3 || !OpTy)
return error("Invalid record");
DelayedShuffles.push_back(
- {OpTy, OpTy, CurFullTy, Record[0], Record[1], Record[2], NextCstNo});
+ {OpTy, OpTy, Record[0], Record[1], Record[2], NextCstNo});
++NextCstNo;
continue;
}
@@ -2771,7 +2762,7 @@ Error BitcodeReader::parseConstants() {
if (Record.size() < 4 || !RTy || !OpTy)
return error("Invalid record");
DelayedShuffles.push_back(
- {OpTy, RTy, CurFullTy, Record[1], Record[2], Record[3], NextCstNo});
+ {OpTy, RTy, Record[1], Record[2], Record[3], NextCstNo});
++NextCstNo;
continue;
}
@@ -2811,13 +2802,13 @@ Error BitcodeReader::parseConstants() {
ConstrStr += (char)Record[3+AsmStrSize+i];
UpgradeInlineAsmString(&AsmStr);
V = InlineAsm::get(
- cast<FunctionType>(getPointerElementFlatType(CurFullTy)), AsmStr,
- ConstrStr, HasSideEffects, IsAlignStack);
+ cast<FunctionType>(cast<PointerType>(CurTy)->getElementType()),
+ AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
break;
}
// This version adds support for the asm dialect keywords (e.g.,
// inteldialect).
- case bitc::CST_CODE_INLINEASM: {
+ case bitc::CST_CODE_INLINEASM_OLD2: {
if (Record.size() < 2)
return error("Invalid record");
std::string AsmStr, ConstrStr;
@@ -2837,11 +2828,38 @@ Error BitcodeReader::parseConstants() {
ConstrStr += (char)Record[3+AsmStrSize+i];
UpgradeInlineAsmString(&AsmStr);
V = InlineAsm::get(
- cast<FunctionType>(getPointerElementFlatType(CurFullTy)), AsmStr,
- ConstrStr, HasSideEffects, IsAlignStack,
+ cast<FunctionType>(cast<PointerType>(CurTy)->getElementType()),
+ AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
InlineAsm::AsmDialect(AsmDialect));
break;
}
+ // This version adds support for the unwind keyword.
+ case bitc::CST_CODE_INLINEASM: {
+ if (Record.size() < 2)
+ return error("Invalid record");
+ std::string AsmStr, ConstrStr;
+ bool HasSideEffects = Record[0] & 1;
+ bool IsAlignStack = (Record[0] >> 1) & 1;
+ unsigned AsmDialect = (Record[0] >> 2) & 1;
+ bool CanThrow = (Record[0] >> 3) & 1;
+ unsigned AsmStrSize = Record[1];
+ if (2 + AsmStrSize >= Record.size())
+ return error("Invalid record");
+ unsigned ConstStrSize = Record[2 + AsmStrSize];
+ if (3 + AsmStrSize + ConstStrSize > Record.size())
+ return error("Invalid record");
+
+ for (unsigned i = 0; i != AsmStrSize; ++i)
+ AsmStr += (char)Record[2 + i];
+ for (unsigned i = 0; i != ConstStrSize; ++i)
+ ConstrStr += (char)Record[3 + AsmStrSize + i];
+ UpgradeInlineAsmString(&AsmStr);
+ V = InlineAsm::get(
+ cast<FunctionType>(cast<PointerType>(CurTy)->getElementType()),
+ AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
+ InlineAsm::AsmDialect(AsmDialect), CanThrow);
+ break;
+ }
case bitc::CST_CODE_BLOCKADDRESS:{
if (Record.size() < 3)
return error("Invalid record");
@@ -2883,11 +2901,23 @@ Error BitcodeReader::parseConstants() {
V = BlockAddress::get(Fn, BB);
break;
}
+ case bitc::CST_CODE_DSO_LOCAL_EQUIVALENT: {
+ if (Record.size() < 2)
+ return error("Invalid record");
+ Type *GVTy = getTypeByID(Record[0]);
+ if (!GVTy)
+ return error("Invalid record");
+ GlobalValue *GV = dyn_cast_or_null<GlobalValue>(
+ ValueList.getConstantFwdRef(Record[1], GVTy));
+ if (!GV)
+ return error("Invalid record");
+
+ V = DSOLocalEquivalent::get(GV);
+ break;
+ }
}
- assert(V->getType() == flattenPointerTypes(CurFullTy) &&
- "Incorrect fully structured type provided for Constant");
- ValueList.assignValue(V, NextCstNo, CurFullTy);
+ ValueList.assignValue(V, NextCstNo);
++NextCstNo;
}
}
@@ -3165,8 +3195,7 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
if (Record.size() < 6)
return error("Invalid record");
- Type *FullTy = getFullyStructuredTypeByID(Record[0]);
- Type *Ty = flattenPointerTypes(FullTy);
+ Type *Ty = getTypeByID(Record[0]);
if (!Ty)
return error("Invalid record");
bool isConstant = Record[1] & 1;
@@ -3178,7 +3207,7 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
if (!Ty->isPointerTy())
return error("Invalid type for value");
AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
- std::tie(FullTy, Ty) = getPointerElementTypes(FullTy);
+ Ty = cast<PointerType>(Ty)->getElementType();
}
uint64_t RawLinkage = Record[3];
@@ -3224,10 +3253,7 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
else
upgradeDLLImportExportLinkage(NewGV, RawLinkage);
- FullTy = PointerType::get(FullTy, AddressSpace);
- assert(NewGV->getType() == flattenPointerTypes(FullTy) &&
- "Incorrect fully specified type for GlobalVariable");
- ValueList.push_back(NewGV, FullTy);
+ ValueList.push_back(NewGV);
// Remember which value to use for the global initializer.
if (unsigned InitID = Record[2])
@@ -3270,12 +3296,11 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
if (Record.size() < 8)
return error("Invalid record");
- Type *FullFTy = getFullyStructuredTypeByID(Record[0]);
- Type *FTy = flattenPointerTypes(FullFTy);
+ Type *FTy = getTypeByID(Record[0]);
if (!FTy)
return error("Invalid record");
- if (isa<PointerType>(FTy))
- std::tie(FullFTy, FTy) = getPointerElementTypes(FullFTy);
+ if (auto *PTy = dyn_cast<PointerType>(FTy))
+ FTy = PTy->getElementType();
if (!isa<FunctionType>(FTy))
return error("Invalid type for value");
@@ -3291,9 +3316,9 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
Function::Create(cast<FunctionType>(FTy), GlobalValue::ExternalLinkage,
AddrSpace, Name, TheModule);
- assert(Func->getFunctionType() == flattenPointerTypes(FullFTy) &&
+ assert(Func->getFunctionType() == FTy &&
"Incorrect fully specified type provided for function");
- FunctionTypes[Func] = cast<FunctionType>(FullFTy);
+ FunctionTypes[Func] = cast<FunctionType>(FTy);
Func->setCallingConv(CC);
bool isProto = Record[2];
@@ -3305,18 +3330,33 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
// argument's pointee type. There should be no opaque pointers where the byval
// type is implicit.
for (unsigned i = 0; i != Func->arg_size(); ++i) {
- for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet}) {
+ for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet,
+ Attribute::InAlloca}) {
if (!Func->hasParamAttribute(i, Kind))
continue;
+ if (Func->getParamAttribute(i, Kind).getValueAsType())
+ continue;
+
Func->removeParamAttr(i, Kind);
- Type *PTy = cast<FunctionType>(FullFTy)->getParamType(i);
- Type *PtrEltTy = getPointerElementFlatType(PTy);
- Attribute NewAttr =
- Kind == Attribute::ByVal
- ? Attribute::getWithByValType(Context, PtrEltTy)
- : Attribute::getWithStructRetType(Context, PtrEltTy);
+ Type *PTy = cast<FunctionType>(FTy)->getParamType(i);
+ Type *PtrEltTy = cast<PointerType>(PTy)->getElementType();
+ Attribute NewAttr;
+ switch (Kind) {
+ case Attribute::ByVal:
+ NewAttr = Attribute::getWithByValType(Context, PtrEltTy);
+ break;
+ case Attribute::StructRet:
+ NewAttr = Attribute::getWithStructRetType(Context, PtrEltTy);
+ break;
+ case Attribute::InAlloca:
+ NewAttr = Attribute::getWithInAllocaType(Context, PtrEltTy);
+ break;
+ default:
+ llvm_unreachable("not an upgraded type attribute");
+ }
+
Func->addParamAttr(i, NewAttr);
}
}
@@ -3374,14 +3414,14 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
// Record[16] is the address space number.
- // Check whether we have enough values to read a partition name.
- if (Record.size() > 18)
+ // Check whether we have enough values to read a partition name. Also make
+ // sure Strtab has enough values.
+ if (Record.size() > 18 && Strtab.data() &&
+ Record[17] + Record[18] <= Strtab.size()) {
Func->setPartition(StringRef(Strtab.data() + Record[17], Record[18]));
+ }
- Type *FullTy = PointerType::get(FullFTy, AddrSpace);
- assert(Func->getType() == flattenPointerTypes(FullTy) &&
- "Incorrect fully specified type provided for Function");
- ValueList.push_back(Func, FullTy);
+ 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.
@@ -3410,8 +3450,7 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
if (Record.size() < (3 + (unsigned)NewRecord))
return error("Invalid record");
unsigned OpNum = 0;
- Type *FullTy = getFullyStructuredTypeByID(Record[OpNum++]);
- Type *Ty = flattenPointerTypes(FullTy);
+ Type *Ty = getTypeByID(Record[OpNum++]);
if (!Ty)
return error("Invalid record");
@@ -3420,7 +3459,7 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
auto *PTy = dyn_cast<PointerType>(Ty);
if (!PTy)
return error("Invalid type for value");
- std::tie(FullTy, Ty) = getPointerElementTypes(FullTy);
+ Ty = PTy->getElementType();
AddrSpace = PTy->getAddressSpace();
} else {
AddrSpace = Record[OpNum++];
@@ -3437,8 +3476,6 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
NewGA = GlobalIFunc::create(Ty, AddrSpace, getDecodedLinkage(Linkage), Name,
nullptr, TheModule);
- assert(NewGA->getValueType() == flattenPointerTypes(FullTy) &&
- "Incorrect fully structured type provided for GlobalIndirectSymbol");
// Local linkage must have default visibility.
// auto-upgrade `hidden` and `protected` for old bitcode.
if (OpNum != Record.size()) {
@@ -3468,10 +3505,7 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
OpNum += 2;
}
- FullTy = PointerType::get(FullTy, AddrSpace);
- assert(NewGA->getType() == flattenPointerTypes(FullTy) &&
- "Incorrect fully structured type provided for GlobalIndirectSymbol");
- ValueList.push_back(NewGA, FullTy);
+ ValueList.push_back(NewGA);
IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
return Error::success();
}
@@ -3769,33 +3803,57 @@ Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata,
Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) {
if (!isa<PointerType>(PtrType))
return error("Load/Store operand is not a pointer type");
- Type *ElemType = cast<PointerType>(PtrType)->getElementType();
- if (ValType && ValType != ElemType)
+ if (!cast<PointerType>(PtrType)->isOpaqueOrPointeeTypeMatches(ValType))
return error("Explicit load/store type does not match pointee "
"type of pointer operand");
- if (!PointerType::isLoadableOrStorableType(ElemType))
+ if (!PointerType::isLoadableOrStorableType(ValType))
return error("Cannot load/store from pointer");
return Error::success();
}
-void BitcodeReader::propagateByValSRetTypes(CallBase *CB,
- ArrayRef<Type *> ArgsFullTys) {
+void BitcodeReader::propagateAttributeTypes(CallBase *CB,
+ ArrayRef<Type *> ArgsTys) {
for (unsigned i = 0; i != CB->arg_size(); ++i) {
- for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet}) {
+ for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet,
+ Attribute::InAlloca}) {
if (!CB->paramHasAttr(i, Kind))
continue;
CB->removeParamAttr(i, Kind);
- Type *PtrEltTy = getPointerElementFlatType(ArgsFullTys[i]);
- Attribute NewAttr =
- Kind == Attribute::ByVal
- ? Attribute::getWithByValType(Context, PtrEltTy)
- : Attribute::getWithStructRetType(Context, PtrEltTy);
+ Type *PtrEltTy = cast<PointerType>(ArgsTys[i])->getElementType();
+ Attribute NewAttr;
+ switch (Kind) {
+ case Attribute::ByVal:
+ NewAttr = Attribute::getWithByValType(Context, PtrEltTy);
+ break;
+ case Attribute::StructRet:
+ NewAttr = Attribute::getWithStructRetType(Context, PtrEltTy);
+ break;
+ case Attribute::InAlloca:
+ NewAttr = Attribute::getWithInAllocaType(Context, PtrEltTy);
+ break;
+ default:
+ llvm_unreachable("not an upgraded type attribute");
+ }
+
CB->addParamAttr(i, NewAttr);
}
}
+
+ switch (CB->getIntrinsicID()) {
+ case Intrinsic::preserve_array_access_index:
+ case Intrinsic::preserve_struct_access_index:
+ if (!CB->getAttributes().getParamElementType(0)) {
+ Type *ElTy = cast<PointerType>(ArgsTys[0])->getElementType();
+ Attribute NewAttr = Attribute::get(Context, Attribute::ElementType, ElTy);
+ CB->addParamAttr(0, NewAttr);
+ }
+ break;
+ default:
+ break;
+ }
}
/// Lazily parse the specified function body block.
@@ -3812,12 +3870,14 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned ModuleMDLoaderSize = MDLoader->size();
// Add all the function arguments to the value table.
+#ifndef NDEBUG
unsigned ArgNo = 0;
- FunctionType *FullFTy = FunctionTypes[F];
+ FunctionType *FTy = FunctionTypes[F];
+#endif
for (Argument &I : F->args()) {
- assert(I.getType() == flattenPointerTypes(FullFTy->getParamType(ArgNo)) &&
+ assert(I.getType() == FTy->getParamType(ArgNo++) &&
"Incorrect fully specified type for Function Argument");
- ValueList.push_back(&I, FullFTy->getParamType(ArgNo++));
+ ValueList.push_back(&I);
}
unsigned NextValueNo = ValueList.size();
BasicBlock *CurBB = nullptr;
@@ -3890,7 +3950,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
// Read a record.
Record.clear();
Instruction *I = nullptr;
- Type *FullTy = nullptr;
Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record);
if (!MaybeBitCode)
return MaybeBitCode.takeError();
@@ -4036,8 +4095,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
OpNum+2 != Record.size())
return error("Invalid record");
- FullTy = getFullyStructuredTypeByID(Record[OpNum]);
- Type *ResTy = flattenPointerTypes(FullTy);
+ Type *ResTy = getTypeByID(Record[OpNum]);
int Opc = getDecodedCastOpcode(Record[OpNum + 1]);
if (Opc == -1 || !ResTy)
return error("Invalid record");
@@ -4067,24 +4125,24 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (BitCode == bitc::FUNC_CODE_INST_GEP) {
InBounds = Record[OpNum++];
- FullTy = getFullyStructuredTypeByID(Record[OpNum++]);
- Ty = flattenPointerTypes(FullTy);
+ Ty = getTypeByID(Record[OpNum++]);
} else {
InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
Ty = nullptr;
}
Value *BasePtr;
- Type *FullBaseTy = nullptr;
- if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr, &FullBaseTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr))
return error("Invalid record");
if (!Ty) {
- std::tie(FullTy, Ty) =
- getPointerElementTypes(FullBaseTy->getScalarType());
- } else if (Ty != getPointerElementFlatType(FullBaseTy->getScalarType()))
+ Ty = cast<PointerType>(BasePtr->getType()->getScalarType())
+ ->getElementType();
+ } else if (!cast<PointerType>(BasePtr->getType()->getScalarType())
+ ->isOpaqueOrPointeeTypeMatches(Ty)) {
return error(
"Explicit gep type does not match pointee type of pointer operand");
+ }
SmallVector<Value*, 16> GEPIdx;
while (OpNum != Record.size()) {
@@ -4095,7 +4153,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
}
I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx);
- FullTy = GetElementPtrInst::getGEPReturnType(FullTy, I, GEPIdx);
InstructionList.push_back(I);
if (InBounds)
@@ -4107,8 +4164,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
// EXTRACTVAL: [opty, opval, n x indices]
unsigned OpNum = 0;
Value *Agg;
- if (getValueTypePair(Record, OpNum, NextValueNo, Agg, &FullTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
return error("Invalid record");
+ Type *Ty = Agg->getType();
unsigned RecSize = Record.size();
if (OpNum == RecSize)
@@ -4116,24 +4174,24 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
SmallVector<unsigned, 4> EXTRACTVALIdx;
for (; OpNum != RecSize; ++OpNum) {
- bool IsArray = FullTy->isArrayTy();
- bool IsStruct = FullTy->isStructTy();
+ bool IsArray = Ty->isArrayTy();
+ bool IsStruct = Ty->isStructTy();
uint64_t Index = Record[OpNum];
if (!IsStruct && !IsArray)
return error("EXTRACTVAL: Invalid type");
if ((unsigned)Index != Index)
return error("Invalid value");
- if (IsStruct && Index >= FullTy->getStructNumElements())
+ if (IsStruct && Index >= Ty->getStructNumElements())
return error("EXTRACTVAL: Invalid struct index");
- if (IsArray && Index >= FullTy->getArrayNumElements())
+ if (IsArray && Index >= Ty->getArrayNumElements())
return error("EXTRACTVAL: Invalid array index");
EXTRACTVALIdx.push_back((unsigned)Index);
if (IsStruct)
- FullTy = FullTy->getStructElementType(Index);
+ Ty = Ty->getStructElementType(Index);
else
- FullTy = FullTy->getArrayElementType();
+ Ty = Ty->getArrayElementType();
}
I = ExtractValueInst::Create(Agg, EXTRACTVALIdx);
@@ -4145,7 +4203,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
// INSERTVAL: [opty, opval, opty, opval, n x indices]
unsigned OpNum = 0;
Value *Agg;
- if (getValueTypePair(Record, OpNum, NextValueNo, Agg, &FullTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
return error("Invalid record");
Value *Val;
if (getValueTypePair(Record, OpNum, NextValueNo, Val))
@@ -4191,7 +4249,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
// handles select i1 ... in old bitcode
unsigned OpNum = 0;
Value *TrueVal, *FalseVal, *Cond;
- if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, &FullTy) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) ||
popValue(Record, OpNum, NextValueNo, Type::getInt1Ty(Context), Cond))
return error("Invalid record");
@@ -4206,7 +4264,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
// handles select i1 or select [N x i1]
unsigned OpNum = 0;
Value *TrueVal, *FalseVal, *Cond;
- if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, &FullTy) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) ||
getValueTypePair(Record, OpNum, NextValueNo, Cond))
return error("Invalid record");
@@ -4236,13 +4294,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
case bitc::FUNC_CODE_INST_EXTRACTELT: { // EXTRACTELT: [opty, opval, opval]
unsigned OpNum = 0;
Value *Vec, *Idx;
- if (getValueTypePair(Record, OpNum, NextValueNo, Vec, &FullTy) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
getValueTypePair(Record, OpNum, NextValueNo, Idx))
return error("Invalid record");
if (!Vec->getType()->isVectorTy())
return error("Invalid type for value");
I = ExtractElementInst::Create(Vec, Idx);
- FullTy = cast<VectorType>(FullTy)->getElementType();
InstructionList.push_back(I);
break;
}
@@ -4250,7 +4307,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
case bitc::FUNC_CODE_INST_INSERTELT: { // INSERTELT: [ty, opval,opval,opval]
unsigned OpNum = 0;
Value *Vec, *Elt, *Idx;
- if (getValueTypePair(Record, OpNum, NextValueNo, Vec, &FullTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Vec))
return error("Invalid record");
if (!Vec->getType()->isVectorTy())
return error("Invalid type for value");
@@ -4266,7 +4323,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
case bitc::FUNC_CODE_INST_SHUFFLEVEC: {// SHUFFLEVEC: [opval,ty,opval,opval]
unsigned OpNum = 0;
Value *Vec1, *Vec2, *Mask;
- if (getValueTypePair(Record, OpNum, NextValueNo, Vec1, &FullTy) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) ||
popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec2))
return error("Invalid record");
@@ -4276,9 +4333,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
return error("Invalid type for value");
I = new ShuffleVectorInst(Vec1, Vec2, Mask);
- FullTy =
- VectorType::get(cast<VectorType>(FullTy)->getElementType(),
- cast<VectorType>(Mask->getType())->getElementCount());
InstructionList.push_back(I);
break;
}
@@ -4586,40 +4640,36 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
BasicBlock *UnwindBB = getBasicBlock(Record[OpNum++]);
FunctionType *FTy = nullptr;
- FunctionType *FullFTy = nullptr;
if ((CCInfo >> 13) & 1) {
- FullFTy =
- dyn_cast<FunctionType>(getFullyStructuredTypeByID(Record[OpNum++]));
- if (!FullFTy)
+ FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]));
+ if (!FTy)
return error("Explicit invoke type is not a function type");
- FTy = cast<FunctionType>(flattenPointerTypes(FullFTy));
}
Value *Callee;
- if (getValueTypePair(Record, OpNum, NextValueNo, Callee, &FullTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
return error("Invalid record");
PointerType *CalleeTy = dyn_cast<PointerType>(Callee->getType());
if (!CalleeTy)
return error("Callee is not a pointer");
if (!FTy) {
- FullFTy =
- dyn_cast<FunctionType>(cast<PointerType>(FullTy)->getElementType());
- if (!FullFTy)
+ FTy = dyn_cast<FunctionType>(
+ cast<PointerType>(Callee->getType())->getElementType());
+ if (!FTy)
return error("Callee is not of pointer to function type");
- FTy = cast<FunctionType>(flattenPointerTypes(FullFTy));
- } else if (getPointerElementFlatType(FullTy) != FTy)
+ } else if (!CalleeTy->isOpaqueOrPointeeTypeMatches(FTy))
return error("Explicit invoke type does not match pointee type of "
"callee operand");
if (Record.size() < FTy->getNumParams() + OpNum)
return error("Insufficient operands to call");
SmallVector<Value*, 16> Ops;
- SmallVector<Type *, 16> ArgsFullTys;
+ SmallVector<Type *, 16> ArgsTys;
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
Ops.push_back(getValue(Record, OpNum, NextValueNo,
FTy->getParamType(i)));
- ArgsFullTys.push_back(FullFTy->getParamType(i));
+ ArgsTys.push_back(FTy->getParamType(i));
if (!Ops.back())
return error("Invalid record");
}
@@ -4631,23 +4681,21 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
// Read type/value pairs for varargs params.
while (OpNum != Record.size()) {
Value *Op;
- Type *FullTy;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op))
return error("Invalid record");
Ops.push_back(Op);
- ArgsFullTys.push_back(FullTy);
+ ArgsTys.push_back(Op->getType());
}
}
I = InvokeInst::Create(FTy, Callee, NormalBB, UnwindBB, Ops,
OperandBundles);
- FullTy = FullFTy->getReturnType();
OperandBundles.clear();
InstructionList.push_back(I);
cast<InvokeInst>(I)->setCallingConv(
static_cast<CallingConv::ID>(CallingConv::MaxID & CCInfo));
cast<InvokeInst>(I)->setAttributes(PAL);
- propagateByValSRetTypes(cast<CallBase>(I), ArgsFullTys);
+ propagateAttributeTypes(cast<CallBase>(I), ArgsTys);
break;
}
@@ -4673,29 +4721,25 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
IndirectDests.push_back(getBasicBlock(Record[OpNum++]));
FunctionType *FTy = nullptr;
- FunctionType *FullFTy = nullptr;
if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) {
- FullFTy =
- dyn_cast<FunctionType>(getFullyStructuredTypeByID(Record[OpNum++]));
- if (!FullFTy)
+ FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]));
+ if (!FTy)
return error("Explicit call type is not a function type");
- FTy = cast<FunctionType>(flattenPointerTypes(FullFTy));
}
Value *Callee;
- if (getValueTypePair(Record, OpNum, NextValueNo, Callee, &FullTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
return error("Invalid record");
PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
if (!OpTy)
return error("Callee is not a pointer type");
if (!FTy) {
- FullFTy =
- dyn_cast<FunctionType>(cast<PointerType>(FullTy)->getElementType());
- if (!FullFTy)
+ FTy = dyn_cast<FunctionType>(
+ cast<PointerType>(Callee->getType())->getElementType());
+ if (!FTy)
return error("Callee is not of pointer to function type");
- FTy = cast<FunctionType>(flattenPointerTypes(FullFTy));
- } else if (getPointerElementFlatType(FullTy) != FTy)
+ } else if (cast<PointerType>(Callee->getType())->getElementType() != FTy)
return error("Explicit call type does not match pointee type of "
"callee operand");
if (Record.size() < FTy->getNumParams() + OpNum)
@@ -4728,7 +4772,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
I = CallBrInst::Create(FTy, Callee, DefaultDest, IndirectDests, Args,
OperandBundles);
- FullTy = FullFTy->getReturnType();
OperandBundles.clear();
InstructionList.push_back(I);
cast<CallBrInst>(I)->setCallingConv(
@@ -4744,8 +4787,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (Record.empty())
return error("Invalid record");
// The first record specifies the type.
- FullTy = getFullyStructuredTypeByID(Record[0]);
- Type *Ty = flattenPointerTypes(FullTy);
+ Type *Ty = getTypeByID(Record[0]);
if (!Ty)
return error("Invalid record");
@@ -4797,8 +4839,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (Record.size() < 4)
return error("Invalid record");
}
- FullTy = getFullyStructuredTypeByID(Record[Idx++]);
- Type *Ty = flattenPointerTypes(FullTy);
+ Type *Ty = getTypeByID(Record[Idx++]);
if (!Ty)
return error("Invalid record");
if (BitCode == bitc::FUNC_CODE_INST_LANDINGPAD_OLD) {
@@ -4847,13 +4888,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
const uint64_t Rec = Record[3];
const bool InAlloca = Bitfield::get<APV::UsedWithInAlloca>(Rec);
const bool SwiftError = Bitfield::get<APV::SwiftError>(Rec);
- FullTy = getFullyStructuredTypeByID(Record[0]);
- Type *Ty = flattenPointerTypes(FullTy);
+ Type *Ty = getTypeByID(Record[0]);
if (!Bitfield::get<APV::ExplicitType>(Rec)) {
auto *PTy = dyn_cast_or_null<PointerType>(Ty);
if (!PTy)
return error("Old-style alloca with a non-pointer type");
- std::tie(FullTy, Ty) = getPointerElementTypes(FullTy);
+ Ty = PTy->getElementType();
}
Type *OpTy = getTypeByID(Record[1]);
Value *Size = getFnValueByID(Record[2], OpTy);
@@ -4879,14 +4919,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
AI->setUsedWithInAlloca(InAlloca);
AI->setSwiftError(SwiftError);
I = AI;
- FullTy = PointerType::get(FullTy, AS);
InstructionList.push_back(I);
break;
}
case bitc::FUNC_CODE_INST_LOAD: { // LOAD: [opty, op, align, vol]
unsigned OpNum = 0;
Value *Op;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
(OpNum + 2 != Record.size() && OpNum + 3 != Record.size()))
return error("Invalid record");
@@ -4895,10 +4934,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Type *Ty = nullptr;
if (OpNum + 3 == Record.size()) {
- FullTy = getFullyStructuredTypeByID(Record[OpNum++]);
- Ty = flattenPointerTypes(FullTy);
- } else
- std::tie(FullTy, Ty) = getPointerElementTypes(FullTy);
+ Ty = getTypeByID(Record[OpNum++]);
+ } else {
+ Ty = cast<PointerType>(Op->getType())->getElementType();
+ }
if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType()))
return Err;
@@ -4919,7 +4958,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
// LOADATOMIC: [opty, op, align, vol, ordering, ssid]
unsigned OpNum = 0;
Value *Op;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
(OpNum + 4 != Record.size() && OpNum + 5 != Record.size()))
return error("Invalid record");
@@ -4928,10 +4967,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Type *Ty = nullptr;
if (OpNum + 5 == Record.size()) {
- FullTy = getFullyStructuredTypeByID(Record[OpNum++]);
- Ty = flattenPointerTypes(FullTy);
- } else
- std::tie(FullTy, Ty) = getPointerElementTypes(FullTy);
+ Ty = getTypeByID(Record[OpNum++]);
+ } else {
+ Ty = cast<PointerType>(Op->getType())->getElementType();
+ }
if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType()))
return Err;
@@ -4958,12 +4997,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
case bitc::FUNC_CODE_INST_STORE_OLD: { // STORE2:[ptrty, ptr, val, align, vol]
unsigned OpNum = 0;
Value *Val, *Ptr;
- Type *FullTy;
- if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
(BitCode == bitc::FUNC_CODE_INST_STORE
? getValueTypePair(Record, OpNum, NextValueNo, Val)
: popValue(Record, OpNum, NextValueNo,
- getPointerElementFlatType(FullTy), Val)) ||
+ cast<PointerType>(Ptr->getType())->getElementType(),
+ Val)) ||
OpNum + 2 != Record.size())
return error("Invalid record");
@@ -4986,13 +5025,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
// STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, ssid]
unsigned OpNum = 0;
Value *Val, *Ptr;
- Type *FullTy;
- if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
!isa<PointerType>(Ptr->getType()) ||
(BitCode == bitc::FUNC_CODE_INST_STOREATOMIC
? getValueTypePair(Record, OpNum, NextValueNo, Val)
: popValue(Record, OpNum, NextValueNo,
- getPointerElementFlatType(FullTy), Val)) ||
+ cast<PointerType>(Ptr->getType())->getElementType(),
+ Val)) ||
OpNum + 4 != Record.size())
return error("Invalid record");
@@ -5022,7 +5061,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
const size_t NumRecords = Record.size();
unsigned OpNum = 0;
Value *Ptr = nullptr;
- if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr))
return error("Invalid record");
if (!isa<PointerType>(Ptr->getType()))
@@ -5030,11 +5069,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Value *Cmp = nullptr;
if (popValue(Record, OpNum, NextValueNo,
- getPointerElementFlatType(FullTy), Cmp))
+ cast<PointerType>(Ptr->getType())->getPointerElementType(),
+ Cmp))
return error("Invalid record");
- FullTy = cast<PointerType>(FullTy)->getElementType();
-
Value *New = nullptr;
if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) ||
NumRecords < OpNum + 3 || NumRecords > OpNum + 5)
@@ -5056,13 +5094,16 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
? AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrdering)
: getDecodedOrdering(Record[OpNum + 3]);
+ if (FailureOrdering == AtomicOrdering::NotAtomic ||
+ FailureOrdering == AtomicOrdering::Unordered)
+ return error("Invalid record");
+
const Align Alignment(
TheModule->getDataLayout().getTypeStoreSize(Cmp->getType()));
I = new AtomicCmpXchgInst(Ptr, Cmp, New, Alignment, SuccessOrdering,
FailureOrdering, SSID);
cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
- FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)});
if (NumRecords < 8) {
// Before weak cmpxchgs existed, the instruction simply returned the
@@ -5070,7 +5111,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
// expecting the first component of a modern cmpxchg.
CurBB->getInstList().push_back(I);
I = ExtractValueInst::Create(I, 0);
- FullTy = cast<StructType>(FullTy)->getElementType(0);
} else {
cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum + 4]);
}
@@ -5080,30 +5120,33 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
}
case bitc::FUNC_CODE_INST_CMPXCHG: {
// CMPXCHG: [ptrty, ptr, cmp, val, vol, success_ordering, synchscope,
- // failure_ordering, weak]
+ // failure_ordering, weak, align?]
const size_t NumRecords = Record.size();
unsigned OpNum = 0;
Value *Ptr = nullptr;
- if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr))
return error("Invalid record");
if (!isa<PointerType>(Ptr->getType()))
return error("Cmpxchg operand is not a pointer type");
Value *Cmp = nullptr;
- if (getValueTypePair(Record, OpNum, NextValueNo, Cmp, &FullTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Cmp))
return error("Invalid record");
Value *Val = nullptr;
- if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), Val) ||
- NumRecords < OpNum + 3 || NumRecords > OpNum + 5)
+ if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), Val))
+ return error("Invalid record");
+
+ if (NumRecords < OpNum + 3 || NumRecords > OpNum + 6)
return error("Invalid record");
+ const bool IsVol = Record[OpNum];
+
const AtomicOrdering SuccessOrdering =
getDecodedOrdering(Record[OpNum + 1]);
- if (SuccessOrdering == AtomicOrdering::NotAtomic ||
- SuccessOrdering == AtomicOrdering::Unordered)
- return error("Invalid record");
+ if (!AtomicCmpXchgInst::isValidSuccessOrdering(SuccessOrdering))
+ return error("Invalid cmpxchg success ordering");
const SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 2]);
@@ -5112,43 +5155,86 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
const AtomicOrdering FailureOrdering =
getDecodedOrdering(Record[OpNum + 3]);
+ if (!AtomicCmpXchgInst::isValidFailureOrdering(FailureOrdering))
+ return error("Invalid cmpxchg failure ordering");
- const Align Alignment(
- TheModule->getDataLayout().getTypeStoreSize(Cmp->getType()));
+ const bool IsWeak = Record[OpNum + 4];
+
+ MaybeAlign Alignment;
- I = new AtomicCmpXchgInst(Ptr, Cmp, Val, Alignment, SuccessOrdering,
+ if (NumRecords == (OpNum + 6)) {
+ if (Error Err = parseAlignmentValue(Record[OpNum + 5], Alignment))
+ return Err;
+ }
+ if (!Alignment)
+ Alignment =
+ Align(TheModule->getDataLayout().getTypeStoreSize(Cmp->getType()));
+
+ I = new AtomicCmpXchgInst(Ptr, Cmp, Val, *Alignment, SuccessOrdering,
FailureOrdering, SSID);
- FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)});
- cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
- cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum + 4]);
+ cast<AtomicCmpXchgInst>(I)->setVolatile(IsVol);
+ cast<AtomicCmpXchgInst>(I)->setWeak(IsWeak);
InstructionList.push_back(I);
break;
}
+ case bitc::FUNC_CODE_INST_ATOMICRMW_OLD:
case bitc::FUNC_CODE_INST_ATOMICRMW: {
- // ATOMICRMW:[ptrty, ptr, val, op, vol, ordering, ssid]
+ // ATOMICRMW_OLD: [ptrty, ptr, val, op, vol, ordering, ssid, align?]
+ // ATOMICRMW: [ptrty, ptr, valty, val, op, vol, ordering, ssid, align?]
+ const size_t NumRecords = Record.size();
unsigned OpNum = 0;
- Value *Ptr, *Val;
- if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy) ||
- !isa<PointerType>(Ptr->getType()) ||
- popValue(Record, OpNum, NextValueNo,
- getPointerElementFlatType(FullTy), Val) ||
- OpNum + 4 != Record.size())
+
+ Value *Ptr = nullptr;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr))
return error("Invalid record");
- AtomicRMWInst::BinOp Operation = getDecodedRMWOperation(Record[OpNum]);
+
+ if (!isa<PointerType>(Ptr->getType()))
+ return error("Invalid record");
+
+ Value *Val = nullptr;
+ if (BitCode == bitc::FUNC_CODE_INST_ATOMICRMW_OLD) {
+ if (popValue(Record, OpNum, NextValueNo,
+ cast<PointerType>(Ptr->getType())->getPointerElementType(),
+ Val))
+ return error("Invalid record");
+ } else {
+ if (getValueTypePair(Record, OpNum, NextValueNo, Val))
+ return error("Invalid record");
+ }
+
+ if (!(NumRecords == (OpNum + 4) || NumRecords == (OpNum + 5)))
+ return error("Invalid record");
+
+ const AtomicRMWInst::BinOp Operation =
+ getDecodedRMWOperation(Record[OpNum]);
if (Operation < AtomicRMWInst::FIRST_BINOP ||
Operation > AtomicRMWInst::LAST_BINOP)
return error("Invalid record");
- AtomicOrdering Ordering = getDecodedOrdering(Record[OpNum + 2]);
+
+ const bool IsVol = Record[OpNum + 1];
+
+ const AtomicOrdering Ordering = getDecodedOrdering(Record[OpNum + 2]);
if (Ordering == AtomicOrdering::NotAtomic ||
Ordering == AtomicOrdering::Unordered)
return error("Invalid record");
- SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 3]);
- Align Alignment(
- TheModule->getDataLayout().getTypeStoreSize(Val->getType()));
- I = new AtomicRMWInst(Operation, Ptr, Val, Alignment, Ordering, SSID);
- FullTy = getPointerElementFlatType(FullTy);
- cast<AtomicRMWInst>(I)->setVolatile(Record[OpNum+1]);
+
+ const SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 3]);
+
+ MaybeAlign Alignment;
+
+ if (NumRecords == (OpNum + 5)) {
+ if (Error Err = parseAlignmentValue(Record[OpNum + 4], Alignment))
+ return Err;
+ }
+
+ if (!Alignment)
+ Alignment =
+ Align(TheModule->getDataLayout().getTypeStoreSize(Val->getType()));
+
+ I = new AtomicRMWInst(Operation, Ptr, Val, *Alignment, Ordering, SSID);
+ cast<AtomicRMWInst>(I)->setVolatile(IsVol);
+
InstructionList.push_back(I);
break;
}
@@ -5182,36 +5268,32 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
}
FunctionType *FTy = nullptr;
- FunctionType *FullFTy = nullptr;
if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) {
- FullFTy =
- dyn_cast<FunctionType>(getFullyStructuredTypeByID(Record[OpNum++]));
- if (!FullFTy)
+ FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]));
+ if (!FTy)
return error("Explicit call type is not a function type");
- FTy = cast<FunctionType>(flattenPointerTypes(FullFTy));
}
Value *Callee;
- if (getValueTypePair(Record, OpNum, NextValueNo, Callee, &FullTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
return error("Invalid record");
PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
if (!OpTy)
return error("Callee is not a pointer type");
if (!FTy) {
- FullFTy =
- dyn_cast<FunctionType>(cast<PointerType>(FullTy)->getElementType());
- if (!FullFTy)
+ FTy = dyn_cast<FunctionType>(
+ cast<PointerType>(Callee->getType())->getElementType());
+ if (!FTy)
return error("Callee is not of pointer to function type");
- FTy = cast<FunctionType>(flattenPointerTypes(FullFTy));
- } else if (getPointerElementFlatType(FullTy) != FTy)
+ } else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy))
return error("Explicit call type does not match pointee type of "
"callee operand");
if (Record.size() < FTy->getNumParams() + OpNum)
return error("Insufficient operands to call");
SmallVector<Value*, 16> Args;
- SmallVector<Type*, 16> ArgsFullTys;
+ SmallVector<Type *, 16> ArgsTys;
// Read the fixed params.
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
if (FTy->getParamType(i)->isLabelTy())
@@ -5219,7 +5301,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
else
Args.push_back(getValue(Record, OpNum, NextValueNo,
FTy->getParamType(i)));
- ArgsFullTys.push_back(FullFTy->getParamType(i));
+ ArgsTys.push_back(FTy->getParamType(i));
if (!Args.back())
return error("Invalid record");
}
@@ -5231,16 +5313,14 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
} else {
while (OpNum != Record.size()) {
Value *Op;
- Type *FullTy;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op))
return error("Invalid record");
Args.push_back(Op);
- ArgsFullTys.push_back(FullTy);
+ ArgsTys.push_back(Op->getType());
}
}
I = CallInst::Create(FTy, Callee, Args, OperandBundles);
- FullTy = FullFTy->getReturnType();
OperandBundles.clear();
InstructionList.push_back(I);
cast<CallInst>(I)->setCallingConv(
@@ -5254,7 +5334,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
TCK = CallInst::TCK_NoTail;
cast<CallInst>(I)->setTailCallKind(TCK);
cast<CallInst>(I)->setAttributes(PAL);
- propagateByValSRetTypes(cast<CallBase>(I), ArgsFullTys);
+ propagateAttributeTypes(cast<CallBase>(I), ArgsTys);
if (FMF.any()) {
if (!isa<FPMathOperator>(I))
return error("Fast-math-flags specified for call without "
@@ -5268,8 +5348,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
return error("Invalid record");
Type *OpTy = getTypeByID(Record[0]);
Value *Op = getValue(Record, 1, NextValueNo, OpTy);
- FullTy = getFullyStructuredTypeByID(Record[2]);
- Type *ResTy = flattenPointerTypes(FullTy);
+ Type *ResTy = getTypeByID(Record[2]);
if (!OpTy || !Op || !ResTy)
return error("Invalid record");
I = new VAArgInst(Op, ResTy);
@@ -5302,7 +5381,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
case bitc::FUNC_CODE_INST_FREEZE: { // FREEZE: [opty,opval]
unsigned OpNum = 0;
Value *Op = nullptr;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op))
return error("Invalid record");
if (OpNum != Record.size())
return error("Invalid record");
@@ -5332,23 +5411,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
}
// Non-void values get registered in the value table for future use.
- if (!I->getType()->isVoidTy()) {
- if (!FullTy) {
- FullTy = I->getType();
- assert(
- !FullTy->isPointerTy() && !isa<StructType>(FullTy) &&
- !isa<ArrayType>(FullTy) &&
- (!isa<VectorType>(FullTy) ||
- cast<VectorType>(FullTy)->getElementType()->isFloatingPointTy() ||
- cast<VectorType>(FullTy)->getElementType()->isIntegerTy()) &&
- "Structured types must be assigned with corresponding non-opaque "
- "pointer type");
- }
-
- assert(I->getType() == flattenPointerTypes(FullTy) &&
- "Incorrect fully structured type provided for Instruction");
- ValueList.assignValue(I, NextValueNo++, FullTy);
- }
+ if (!I->getType()->isVoidTy())
+ ValueList.assignValue(I, NextValueNo++);
}
OutOfRecordLoop:
@@ -5472,8 +5536,8 @@ Error BitcodeReader::materialize(GlobalValue *GV) {
}
}
- // "Upgrade" older incorrect branch weights by dropping them.
for (auto &I : instructions(F)) {
+ // "Upgrade" older incorrect branch weights by dropping them.
if (auto *MD = I.getMetadata(LLVMContext::MD_prof)) {
if (MD->getOperand(0) != nullptr && isa<MDString>(MD->getOperand(0))) {
MDString *MDS = cast<MDString>(MD->getOperand(0));
@@ -5500,6 +5564,17 @@ Error BitcodeReader::materialize(GlobalValue *GV) {
I.setMetadata(LLVMContext::MD_prof, nullptr);
}
}
+
+ // Remove incompatible attributes on function calls.
+ if (auto *CI = dyn_cast<CallBase>(&I)) {
+ CI->removeAttributes(AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(
+ CI->getFunctionType()->getReturnType()));
+
+ for (unsigned ArgNo = 0; ArgNo < CI->arg_size(); ++ArgNo)
+ CI->removeParamAttrs(ArgNo, AttributeFuncs::typeIncompatible(
+ CI->getArgOperand(ArgNo)->getType()));
+ }
}
// Look for functions that rely on old function attribute behavior.
@@ -6801,7 +6876,7 @@ static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream,
case bitc::FS_FLAGS: { // [flags]
uint64_t Flags = Record[0];
// Scan flags.
- assert(Flags <= 0x3f && "Unexpected bits in flag");
+ assert(Flags <= 0x7f && "Unexpected bits in flag");
return Flags & 0x8;
}
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 8cdda62870ff..8493eb7a28b2 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -550,8 +550,7 @@ class MetadataLoader::MetadataLoaderImpl {
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));
+ DDI->setExpression(DIExpression::get(Context, Ops));
}
}
@@ -2076,6 +2075,23 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
return Err;
break;
}
+ case bitc::METADATA_ARG_LIST: {
+ SmallVector<ValueAsMetadata *, 4> Elts;
+ Elts.reserve(Record.size());
+ for (uint64_t Elt : Record) {
+ Metadata *MD = getMD(Elt);
+ if (isa<MDNode>(MD) && cast<MDNode>(MD)->isTemporary())
+ return error(
+ "Invalid record: DIArgList should not contain forward refs");
+ if (!isa<ValueAsMetadata>(MD))
+ return error("Invalid record");
+ Elts.push_back(cast<ValueAsMetadata>(MD));
+ }
+
+ MetadataList.assignValue(DIArgList::get(Context, Elts), NextMetadataNo);
+ NextMetadataNo++;
+ break;
+ }
}
return Error::success();
#undef GET_OR_DISTINCT
diff --git a/llvm/lib/Bitcode/Reader/ValueList.cpp b/llvm/lib/Bitcode/Reader/ValueList.cpp
index ddfa28c6b1e4..86ed664070f6 100644
--- a/llvm/lib/Bitcode/Reader/ValueList.cpp
+++ b/llvm/lib/Bitcode/Reader/ValueList.cpp
@@ -62,18 +62,15 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)
} // end namespace llvm
-void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx, Type *FullTy) {
+void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) {
if (Idx == size()) {
- push_back(V, FullTy);
+ push_back(V);
return;
}
if (Idx >= size())
resize(Idx + 1);
- assert(FullTypes[Idx] == nullptr || FullTypes[Idx] == FullTy);
- FullTypes[Idx] = FullTy;
-
WeakTrackingVH &OldV = ValuePtrs[Idx];
if (!OldV) {
OldV = V;
@@ -113,8 +110,7 @@ Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, Type *Ty) {
return C;
}
-Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty,
- Type **FullTy) {
+Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) {
// Bail out for a clearly invalid value.
if (Idx >= RefsUpperBound)
return nullptr;
@@ -126,8 +122,6 @@ Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty,
// If the types don't match, it's invalid.
if (Ty && Ty != V->getType())
return nullptr;
- if (FullTy)
- *FullTy = FullTypes[Idx];
return V;
}
diff --git a/llvm/lib/Bitcode/Reader/ValueList.h b/llvm/lib/Bitcode/Reader/ValueList.h
index 49900498c294..a39617018f42 100644
--- a/llvm/lib/Bitcode/Reader/ValueList.h
+++ b/llvm/lib/Bitcode/Reader/ValueList.h
@@ -28,13 +28,6 @@ class Value;
class BitcodeReaderValueList {
std::vector<WeakTrackingVH> ValuePtrs;
- /// Struct containing fully-specified copies of the type of each
- /// value. When pointers are opaque, this will be contain non-opaque
- /// variants so that restructuring instructions can determine their
- /// type correctly even if being loaded from old bitcode where some
- /// types are implicit.
- std::vector<Type *> FullTypes;
-
/// As we resolve forward-referenced constants, we add information about them
/// to this vector. This allows us to resolve them in bulk instead of
/// resolving each reference at a time. See the code in
@@ -64,17 +57,12 @@ public:
unsigned size() const { return ValuePtrs.size(); }
void resize(unsigned N) {
ValuePtrs.resize(N);
- FullTypes.resize(N);
- }
- void push_back(Value *V, Type *Ty) {
- ValuePtrs.emplace_back(V);
- FullTypes.emplace_back(Ty);
}
+ void push_back(Value *V) { ValuePtrs.emplace_back(V); }
void clear() {
assert(ResolveConstants.empty() && "Constants not resolved?");
ValuePtrs.clear();
- FullTypes.clear();
}
Value *operator[](unsigned i) const {
@@ -85,20 +73,18 @@ public:
Value *back() const { return ValuePtrs.back(); }
void pop_back() {
ValuePtrs.pop_back();
- FullTypes.pop_back();
}
bool empty() const { return ValuePtrs.empty(); }
void shrinkTo(unsigned N) {
assert(N <= size() && "Invalid shrinkTo request!");
ValuePtrs.resize(N);
- FullTypes.resize(N);
}
Constant *getConstantFwdRef(unsigned Idx, Type *Ty);
- Value *getValueFwdRef(unsigned Idx, Type *Ty, Type **FullTy = nullptr);
+ Value *getValueFwdRef(unsigned Idx, Type *Ty);
- void assignValue(Value *V, unsigned Idx, Type *FullTy);
+ void assignValue(Value *V, unsigned Idx);
/// Once all constants are read, this method bulk resolves any forward
/// references.
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 37ecb9992e44..0a202c376981 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -335,6 +335,8 @@ private:
unsigned Abbrev);
void writeDIMacroFile(const DIMacroFile *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev);
+ void writeDIArgList(const DIArgList *N, SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev);
void writeDIModule(const DIModule *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev);
void writeDITemplateTypeParameter(const DITemplateTypeParameter *N,
@@ -628,6 +630,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_COLD;
case Attribute::Hot:
return bitc::ATTR_KIND_HOT;
+ case Attribute::ElementType:
+ return bitc::ATTR_KIND_ELEMENTTYPE;
case Attribute::InaccessibleMemOnly:
return bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY;
case Attribute::InaccessibleMemOrArgMemOnly:
@@ -684,6 +688,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_NO_PROFILE;
case Attribute::NoUnwind:
return bitc::ATTR_KIND_NO_UNWIND;
+ case Attribute::NoSanitizeCoverage:
+ return bitc::ATTR_KIND_NO_SANITIZE_COVERAGE;
case Attribute::NullPointerIsValid:
return bitc::ATTR_KIND_NULL_POINTER_IS_VALID;
case Attribute::OptForFuzzing:
@@ -734,8 +740,12 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_SWIFT_ERROR;
case Attribute::SwiftSelf:
return bitc::ATTR_KIND_SWIFT_SELF;
+ case Attribute::SwiftAsync:
+ return bitc::ATTR_KIND_SWIFT_ASYNC;
case Attribute::UWTable:
return bitc::ATTR_KIND_UW_TABLE;
+ case Attribute::VScaleRange:
+ return bitc::ATTR_KIND_VSCALE_RANGE;
case Attribute::WillReturn:
return bitc::ATTR_KIND_WILLRETURN;
case Attribute::WriteOnly:
@@ -854,6 +864,12 @@ void ModuleBitcodeWriter::writeTypeTable() {
Abbv->Add(BitCodeAbbrevOp(0)); // Addrspace = 0
unsigned PtrAbbrev = Stream.EmitAbbrev(std::move(Abbv));
+ // Abbrev for TYPE_CODE_OPAQUE_POINTER.
+ Abbv = std::make_shared<BitCodeAbbrev>();
+ Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_OPAQUE_POINTER));
+ Abbv->Add(BitCodeAbbrevOp(0)); // Addrspace = 0
+ unsigned OpaquePtrAbbrev = Stream.EmitAbbrev(std::move(Abbv));
+
// Abbrev for TYPE_CODE_FUNCTION.
Abbv = std::make_shared<BitCodeAbbrev>();
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_FUNCTION));
@@ -924,12 +940,21 @@ void ModuleBitcodeWriter::writeTypeTable() {
break;
case Type::PointerTyID: {
PointerType *PTy = cast<PointerType>(T);
- // POINTER: [pointee type, address space]
- Code = bitc::TYPE_CODE_POINTER;
- TypeVals.push_back(VE.getTypeID(PTy->getElementType()));
unsigned AddressSpace = PTy->getAddressSpace();
- TypeVals.push_back(AddressSpace);
- if (AddressSpace == 0) AbbrevToUse = PtrAbbrev;
+ if (PTy->isOpaque()) {
+ // OPAQUE_POINTER: [address space]
+ Code = bitc::TYPE_CODE_OPAQUE_POINTER;
+ TypeVals.push_back(AddressSpace);
+ if (AddressSpace == 0)
+ AbbrevToUse = OpaquePtrAbbrev;
+ } else {
+ // POINTER: [pointee type, address space]
+ Code = bitc::TYPE_CODE_POINTER;
+ TypeVals.push_back(VE.getTypeID(PTy->getElementType()));
+ TypeVals.push_back(AddressSpace);
+ if (AddressSpace == 0)
+ AbbrevToUse = PtrAbbrev;
+ }
break;
}
case Type::FunctionTyID: {
@@ -1044,7 +1069,8 @@ static uint64_t getEncodedFFlags(FunctionSummary::FFlags Flags) {
return RawFlags;
}
-// Decode the flags for GlobalValue in the summary
+// Decode the flags for GlobalValue in the summary. See getDecodedGVSummaryFlags
+// in BitcodeReader.cpp.
static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
uint64_t RawFlags = 0;
@@ -1058,6 +1084,8 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
// account here as well.
RawFlags = (RawFlags << 4) | Flags.Linkage; // 4 bits
+ RawFlags |= (Flags.Visibility << 8); // 2 bits
+
return RawFlags;
}
@@ -1104,7 +1132,7 @@ static unsigned getEncodedComdatSelectionKind(const Comdat &C) {
return bitc::COMDAT_SELECTION_KIND_EXACT_MATCH;
case Comdat::Largest:
return bitc::COMDAT_SELECTION_KIND_LARGEST;
- case Comdat::NoDuplicates:
+ case Comdat::NoDeduplicate:
return bitc::COMDAT_SELECTION_KIND_NO_DUPLICATES;
case Comdat::SameSize:
return bitc::COMDAT_SELECTION_KIND_SAME_SIZE;
@@ -1864,6 +1892,17 @@ void ModuleBitcodeWriter::writeDIMacroFile(const DIMacroFile *N,
Record.clear();
}
+void ModuleBitcodeWriter::writeDIArgList(const DIArgList *N,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.reserve(N->getArgs().size());
+ for (ValueAsMetadata *MD : N->getArgs())
+ Record.push_back(VE.getMetadataID(MD));
+
+ Stream.EmitRecord(bitc::METADATA_ARG_LIST, Record, Abbrev);
+ Record.clear();
+}
+
void ModuleBitcodeWriter::writeDIModule(const DIModule *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
@@ -2411,9 +2450,9 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
}
if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
- Record.push_back(unsigned(IA->hasSideEffects()) |
- unsigned(IA->isAlignStack()) << 1 |
- unsigned(IA->getDialect()&1) << 2);
+ Record.push_back(
+ unsigned(IA->hasSideEffects()) | unsigned(IA->isAlignStack()) << 1 |
+ unsigned(IA->getDialect() & 1) << 2 | unsigned(IA->canThrow()) << 3);
// Add the asm string.
const std::string &AsmStr = IA->getAsmString();
@@ -2606,6 +2645,10 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
Record.push_back(VE.getTypeID(BA->getFunction()->getType()));
Record.push_back(VE.getValueID(BA->getFunction()));
Record.push_back(VE.getGlobalBasicBlockID(BA->getBasicBlock()));
+ } else if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(C)) {
+ Code = bitc::CST_CODE_DSO_LOCAL_EQUIVALENT;
+ Record.push_back(VE.getTypeID(Equiv->getGlobalValue()->getType()));
+ Record.push_back(VE.getValueID(Equiv->getGlobalValue()));
} else {
#ifndef NDEBUG
C->dump();
@@ -3057,17 +3100,19 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
Vals.push_back(
getEncodedOrdering(cast<AtomicCmpXchgInst>(I).getFailureOrdering()));
Vals.push_back(cast<AtomicCmpXchgInst>(I).isWeak());
+ Vals.push_back(getEncodedAlign(cast<AtomicCmpXchgInst>(I).getAlign()));
break;
case Instruction::AtomicRMW:
Code = bitc::FUNC_CODE_INST_ATOMICRMW;
pushValueAndType(I.getOperand(0), InstID, Vals); // ptrty + ptr
- pushValue(I.getOperand(1), InstID, Vals); // val.
+ pushValueAndType(I.getOperand(1), InstID, Vals); // valty + val
Vals.push_back(
getEncodedRMWOperation(cast<AtomicRMWInst>(I).getOperation()));
Vals.push_back(cast<AtomicRMWInst>(I).isVolatile());
Vals.push_back(getEncodedOrdering(cast<AtomicRMWInst>(I).getOrdering()));
Vals.push_back(
getEncodedSyncScopeID(cast<AtomicRMWInst>(I).getSyncScopeID()));
+ Vals.push_back(getEncodedAlign(cast<AtomicRMWInst>(I).getAlign()));
break;
case Instruction::Fence:
Code = bitc::FUNC_CODE_INST_FENCE;
@@ -4846,7 +4891,7 @@ void llvm::EmbedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf,
const std::vector<uint8_t> &CmdArgs) {
// Save llvm.compiler.used and remove it.
SmallVector<Constant *, 2> UsedArray;
- SmallPtrSet<GlobalValue *, 4> UsedGlobals;
+ SmallVector<GlobalValue *, 4> UsedGlobals;
Type *UsedElementType = Type::getInt8Ty(M.getContext())->getPointerTo(0);
GlobalVariable *Used = collectUsedGlobalVariables(M, UsedGlobals, true);
for (auto *GV : UsedGlobals) {
diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
index bbee8b324954..d86db61ee1f4 100644
--- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -28,6 +28,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
@@ -78,16 +79,6 @@ struct OrderMap {
} // end anonymous namespace
-/// Look for a value that might be wrapped as metadata, e.g. a value in a
-/// metadata operand. Returns nullptr for a non-wrapped input value if
-/// OnlyWrapped is true, or it returns the input value as-is if false.
-static const Value *skipMetadataWrapper(const Value *V, bool OnlyWrapped) {
- if (const auto *MAV = dyn_cast<MetadataAsValue>(V))
- if (const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata()))
- return VAM->getValue();
- return OnlyWrapped ? nullptr : V;
-}
-
static void orderValue(const Value *V, OrderMap &OM) {
if (OM.lookup(V).first)
return;
@@ -139,16 +130,25 @@ static OrderMap orderModule(const Module &M) {
// these before global values, as these will be read before setting the
// global values' initializers. The latter matters for constants which have
// uses towards other constants that are used as initializers.
+ auto orderConstantValue = [&OM](const Value *V) {
+ if ((isa<Constant>(V) && !isa<GlobalValue>(V)) || isa<InlineAsm>(V))
+ orderValue(V, OM);
+ };
for (const Function &F : M) {
if (F.isDeclaration())
continue;
for (const BasicBlock &BB : F)
for (const Instruction &I : BB)
for (const Value *V : I.operands()) {
- if (const Value *Op = skipMetadataWrapper(V, true)) {
- if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) ||
- isa<InlineAsm>(*Op))
- orderValue(Op, OM);
+ if (const auto *MAV = dyn_cast<MetadataAsValue>(V)) {
+ if (const auto *VAM =
+ dyn_cast<ValueAsMetadata>(MAV->getMetadata())) {
+ orderConstantValue(VAM->getValue());
+ } else if (const auto *AL =
+ dyn_cast<DIArgList>(MAV->getMetadata())) {
+ for (const auto *VAM : AL->getArgs())
+ orderConstantValue(VAM->getValue());
+ }
}
}
}
@@ -365,18 +365,23 @@ ValueEnumerator::ValueEnumerator(const Module &M,
UseListOrders = predictUseListOrder(M);
// Enumerate the global variables.
- for (const GlobalVariable &GV : M.globals())
+ for (const GlobalVariable &GV : M.globals()) {
EnumerateValue(&GV);
+ EnumerateType(GV.getValueType());
+ }
// Enumerate the functions.
for (const Function & F : M) {
EnumerateValue(&F);
+ EnumerateType(F.getValueType());
EnumerateAttributes(F.getAttributes());
}
// Enumerate the aliases.
- for (const GlobalAlias &GA : M.aliases())
+ for (const GlobalAlias &GA : M.aliases()) {
EnumerateValue(&GA);
+ EnumerateType(GA.getValueType());
+ }
// Enumerate the ifuncs.
for (const GlobalIFunc &GIF : M.ifuncs())
@@ -448,17 +453,31 @@ ValueEnumerator::ValueEnumerator(const Module &M,
continue;
}
- // Local metadata is enumerated during function-incorporation.
+ // Local metadata is enumerated during function-incorporation, but
+ // any ConstantAsMetadata arguments in a DIArgList should be examined
+ // now.
if (isa<LocalAsMetadata>(MD->getMetadata()))
continue;
+ if (auto *AL = dyn_cast<DIArgList>(MD->getMetadata())) {
+ for (auto *VAM : AL->getArgs())
+ if (isa<ConstantAsMetadata>(VAM))
+ EnumerateMetadata(&F, VAM);
+ continue;
+ }
EnumerateMetadata(&F, MD->getMetadata());
}
if (auto *SVI = dyn_cast<ShuffleVectorInst>(&I))
EnumerateType(SVI->getShuffleMaskForBitcode()->getType());
+ if (auto *GEP = dyn_cast<GetElementPtrInst>(&I))
+ EnumerateType(GEP->getSourceElementType());
+ if (auto *AI = dyn_cast<AllocaInst>(&I))
+ EnumerateType(AI->getAllocatedType());
EnumerateType(I.getType());
- if (const auto *Call = dyn_cast<CallBase>(&I))
+ if (const auto *Call = dyn_cast<CallBase>(&I)) {
EnumerateAttributes(Call->getAttributes());
+ EnumerateType(Call->getFunctionType());
+ }
// Enumerate metadata attached with this instruction.
MDs.clear();
@@ -619,6 +638,11 @@ void ValueEnumerator::EnumerateFunctionLocalMetadata(
EnumerateFunctionLocalMetadata(getMetadataFunctionID(&F), Local);
}
+void ValueEnumerator::EnumerateFunctionLocalListMetadata(
+ const Function &F, const DIArgList *ArgList) {
+ EnumerateFunctionLocalListMetadata(getMetadataFunctionID(&F), ArgList);
+}
+
void ValueEnumerator::dropFunctionFromMetadata(
MetadataMapType::value_type &FirstMD) {
SmallVector<const MDNode *, 64> Worklist;
@@ -729,7 +753,7 @@ const MDNode *ValueEnumerator::enumerateMetadataImpl(unsigned F, const Metadata
return nullptr;
}
-/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata
+/// EnumerateFunctionLocalMetadata - Incorporate function-local metadata
/// information reachable from the metadata.
void ValueEnumerator::EnumerateFunctionLocalMetadata(
unsigned F, const LocalAsMetadata *Local) {
@@ -749,6 +773,39 @@ void ValueEnumerator::EnumerateFunctionLocalMetadata(
EnumerateValue(Local->getValue());
}
+/// EnumerateFunctionLocalListMetadata - Incorporate function-local metadata
+/// information reachable from the metadata.
+void ValueEnumerator::EnumerateFunctionLocalListMetadata(
+ unsigned F, const DIArgList *ArgList) {
+ assert(F && "Expected a function");
+
+ // Check to see if it's already in!
+ MDIndex &Index = MetadataMap[ArgList];
+ if (Index.ID) {
+ assert(Index.F == F && "Expected the same function");
+ return;
+ }
+
+ for (ValueAsMetadata *VAM : ArgList->getArgs()) {
+ if (isa<LocalAsMetadata>(VAM)) {
+ assert(MetadataMap.count(VAM) &&
+ "LocalAsMetadata should be enumerated before DIArgList");
+ assert(MetadataMap[VAM].F == F &&
+ "Expected LocalAsMetadata in the same function");
+ } else {
+ assert(isa<ConstantAsMetadata>(VAM) &&
+ "Expected LocalAsMetadata or ConstantAsMetadata");
+ assert(ValueMap.count(VAM->getValue()) &&
+ "Constant should be enumerated beforeDIArgList");
+ EnumerateMetadata(F, VAM);
+ }
+ }
+
+ MDs.push_back(ArgList);
+ Index.F = F;
+ Index.ID = MDs.size();
+}
+
static unsigned getMetadataTypeOrder(const Metadata *MD) {
// Strings are emitted in bulk and must come first.
if (isa<MDString>(MD))
@@ -959,9 +1016,12 @@ void ValueEnumerator::EnumerateOperandType(const Value *V) {
EnumerateOperandType(Op);
}
- if (auto *CE = dyn_cast<ConstantExpr>(C))
+ if (auto *CE = dyn_cast<ConstantExpr>(C)) {
if (CE->getOpcode() == Instruction::ShuffleVector)
EnumerateOperandType(CE->getShuffleMaskForBitcode());
+ if (CE->getOpcode() == Instruction::GetElementPtr)
+ EnumerateType(cast<GEPOperator>(CE)->getSourceElementType());
+ }
}
void ValueEnumerator::EnumerateAttributes(AttributeList PAL) {
@@ -985,6 +1045,11 @@ void ValueEnumerator::EnumerateAttributes(AttributeList PAL) {
if (Entry == 0) {
AttributeGroups.push_back(Pair);
Entry = AttributeGroups.size();
+
+ for (Attribute Attr : AS) {
+ if (Attr.isTypeAttribute())
+ EnumerateType(Attr.getValueAsType());
+ }
}
}
}
@@ -1004,6 +1069,8 @@ void ValueEnumerator::incorporateFunction(const Function &F) {
EnumerateType(I.getParamByValType());
else if (I.hasAttribute(Attribute::StructRet))
EnumerateType(I.getParamStructRetType());
+ else if (I.hasAttribute(Attribute::ByRef))
+ EnumerateType(I.getParamByRefType());
}
FirstFuncConstantID = Values.size();
@@ -1031,14 +1098,26 @@ void ValueEnumerator::incorporateFunction(const Function &F) {
FirstInstID = Values.size();
SmallVector<LocalAsMetadata *, 8> FnLocalMDVector;
+ SmallVector<DIArgList *, 8> ArgListMDVector;
// Add all of the instructions.
for (const BasicBlock &BB : F) {
for (const Instruction &I : BB) {
for (const Use &OI : I.operands()) {
- if (auto *MD = dyn_cast<MetadataAsValue>(&OI))
- if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata()))
+ if (auto *MD = dyn_cast<MetadataAsValue>(&OI)) {
+ if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata())) {
// Enumerate metadata after the instructions they might refer to.
FnLocalMDVector.push_back(Local);
+ } else if (auto *ArgList = dyn_cast<DIArgList>(MD->getMetadata())) {
+ ArgListMDVector.push_back(ArgList);
+ for (ValueAsMetadata *VMD : ArgList->getArgs()) {
+ if (auto *Local = dyn_cast<LocalAsMetadata>(VMD)) {
+ // Enumerate metadata after the instructions they might refer
+ // to.
+ FnLocalMDVector.push_back(Local);
+ }
+ }
+ }
+ }
}
if (!I.getType()->isVoidTy())
@@ -1054,6 +1133,10 @@ void ValueEnumerator::incorporateFunction(const Function &F) {
"Missing value for metadata operand");
EnumerateFunctionLocalMetadata(F, FnLocalMDVector[i]);
}
+ // DIArgList entries must come after function-local metadata, as it is not
+ // possible to forward-reference them.
+ for (const DIArgList *ArgList : ArgListMDVector)
+ EnumerateFunctionLocalListMetadata(F, ArgList);
}
void ValueEnumerator::purgeFunction() {
diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/llvm/lib/Bitcode/Writer/ValueEnumerator.h
index 3c3bd0d9fdc7..6c3f6d4ff61e 100644
--- a/llvm/lib/Bitcode/Writer/ValueEnumerator.h
+++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.h
@@ -27,6 +27,7 @@ namespace llvm {
class BasicBlock;
class Comdat;
+class DIArgList;
class Function;
class Instruction;
class LocalAsMetadata;
@@ -286,6 +287,9 @@ private:
void EnumerateFunctionLocalMetadata(const Function &F,
const LocalAsMetadata *Local);
void EnumerateFunctionLocalMetadata(unsigned F, const LocalAsMetadata *Local);
+ void EnumerateFunctionLocalListMetadata(const Function &F,
+ const DIArgList *ArgList);
+ void EnumerateFunctionLocalListMetadata(unsigned F, const DIArgList *Arglist);
void EnumerateNamedMDNode(const NamedMDNode *NMD);
void EnumerateValue(const Value *V);
void EnumerateType(Type *T);