aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2022-02-09 14:44:20 +0100
committerNikita Popov <npopov@redhat.com>2022-02-15 09:39:48 +0100
commit1c456a82205cd3a06c87ad498f0bbddf963d8645 (patch)
tree76cca6b336aa813ac4aa8e017e4ab59a58a4941e /llvm/lib/Bitcode/Reader/BitcodeReader.cpp
parent32389d0c2e2db54f9d3f78fae0e113060a9b4074 (diff)
downloadllvm-1c456a82205cd3a06c87ad498f0bbddf963d8645.zip
llvm-1c456a82205cd3a06c87ad498f0bbddf963d8645.tar.gz
llvm-1c456a82205cd3a06c87ad498f0bbddf963d8645.tar.bz2
[Bitcode] Improve support for opaque-pointer bitcode upgrade
This is step two of supporting autoupgrade of old bitcode to opaque pointers. Rather than tracking the element type ID of pointers in particular, track all type IDs that a type contains. This allows us to recover the element type in more complex situations, e.g. when we need to determine the pointer element type of a vector element or function type parameter. Differential Revision: https://reviews.llvm.org/D119339
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp73
1 files changed, 54 insertions, 19 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index fa57edbc..f460bfe 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -484,9 +484,10 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
std::vector<std::string> GCTable;
std::vector<Type *> TypeList;
- /// Stores pointer element type for a given type ID. This is used during
- /// upgrades of typed pointer IR in opaque pointer mode.
- std::vector<Type *> ElementTypeList;
+ /// Track type IDs of contained types. Order is the same as the contained
+ /// types of a Type*. This is used during upgrades of typed pointer IR in
+ /// opaque pointer mode.
+ DenseMap<unsigned, SmallVector<unsigned, 1>> ContainedTypeIDs;
DenseMap<Function *, FunctionType *> FunctionTypes;
BitcodeReaderValueList ValueList;
Optional<MetadataLoader> MDLoader;
@@ -593,8 +594,11 @@ private:
StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name);
StructType *createIdentifiedStructType(LLVMContext &Context);
+ static constexpr unsigned InvalidTypeID = ~0u;
+
Type *getTypeByID(unsigned ID);
Type *getPtrElementTypeByID(unsigned ID);
+ unsigned getContainedTypeID(unsigned ID, unsigned Idx);
Value *getFnValueByID(unsigned ID, Type *Ty) {
if (Ty && Ty->isMetadataTy())
@@ -1180,6 +1184,17 @@ Type *BitcodeReader::getTypeByID(unsigned ID) {
return TypeList[ID] = createIdentifiedStructType(Context);
}
+unsigned BitcodeReader::getContainedTypeID(unsigned ID, unsigned Idx) {
+ auto It = ContainedTypeIDs.find(ID);
+ if (It == ContainedTypeIDs.end())
+ return InvalidTypeID;
+
+ if (Idx >= It->second.size())
+ return InvalidTypeID;
+
+ return It->second[Idx];
+}
+
Type *BitcodeReader::getPtrElementTypeByID(unsigned ID) {
if (ID >= TypeList.size())
return nullptr;
@@ -1188,7 +1203,7 @@ Type *BitcodeReader::getPtrElementTypeByID(unsigned ID) {
if (!Ty->isPointerTy())
return nullptr;
- Type *ElemTy = ElementTypeList[ID];
+ Type *ElemTy = getTypeByID(getContainedTypeID(ID, 0));
if (!ElemTy)
return nullptr;
@@ -1733,7 +1748,7 @@ Error BitcodeReader::parseTypeTableBody() {
// Read a record.
Record.clear();
Type *ResultTy = nullptr;
- Type *ElemTy = nullptr;
+ SmallVector<unsigned> ContainedIDs;
Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record);
if (!MaybeRecord)
return MaybeRecord.takeError();
@@ -1746,7 +1761,6 @@ Error BitcodeReader::parseTypeTableBody() {
if (Record.empty())
return error("Invalid record");
TypeList.resize(Record[0]);
- ElementTypeList.resize(Record[0]);
continue;
case bitc::TYPE_CODE_VOID: // VOID
ResultTy = Type::getVoidTy(Context);
@@ -1809,7 +1823,7 @@ Error BitcodeReader::parseTypeTableBody() {
if (!ResultTy ||
!PointerType::isValidElementType(ResultTy))
return error("Invalid type");
- ElemTy = ResultTy;
+ ContainedIDs.push_back(Record[0]);
ResultTy = PointerType::get(ResultTy, AddressSpace);
break;
}
@@ -1840,6 +1854,7 @@ Error BitcodeReader::parseTypeTableBody() {
if (!ResultTy || ArgTys.size() < Record.size()-3)
return error("Invalid type");
+ ContainedIDs.append(Record.begin() + 2, Record.end());
ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
break;
}
@@ -1862,6 +1877,7 @@ Error BitcodeReader::parseTypeTableBody() {
if (!ResultTy || ArgTys.size() < Record.size()-2)
return error("Invalid type");
+ ContainedIDs.append(Record.begin() + 1, Record.end());
ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
break;
}
@@ -1877,6 +1893,7 @@ Error BitcodeReader::parseTypeTableBody() {
}
if (EltTys.size() != Record.size()-1)
return error("Invalid type");
+ ContainedIDs.append(Record.begin() + 1, Record.end());
ResultTy = StructType::get(Context, EltTys, Record[0]);
break;
}
@@ -1911,6 +1928,7 @@ Error BitcodeReader::parseTypeTableBody() {
if (EltTys.size() != Record.size()-1)
return error("Invalid record");
Res->setBody(EltTys, Record[0]);
+ ContainedIDs.append(Record.begin() + 1, Record.end());
ResultTy = Res;
break;
}
@@ -1938,6 +1956,7 @@ Error BitcodeReader::parseTypeTableBody() {
ResultTy = getTypeByID(Record[1]);
if (!ResultTy || !ArrayType::isValidElementType(ResultTy))
return error("Invalid type");
+ ContainedIDs.push_back(Record[1]);
ResultTy = ArrayType::get(ResultTy, Record[0]);
break;
case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] or
@@ -1950,6 +1969,7 @@ Error BitcodeReader::parseTypeTableBody() {
if (!ResultTy || !VectorType::isValidElementType(ResultTy))
return error("Invalid type");
bool Scalable = Record.size() > 2 ? Record[2] : false;
+ ContainedIDs.push_back(Record[1]);
ResultTy = VectorType::get(ResultTy, Record[0], Scalable);
break;
}
@@ -1961,7 +1981,8 @@ Error BitcodeReader::parseTypeTableBody() {
"Invalid TYPE table: Only named structs can be forward referenced");
assert(ResultTy && "Didn't read a type?");
TypeList[NumRecords] = ResultTy;
- ElementTypeList[NumRecords] = ElemTy;
+ if (!ContainedIDs.empty())
+ ContainedTypeIDs[NumRecords] = std::move(ContainedIDs);
++NumRecords;
}
}
@@ -2726,10 +2747,8 @@ Error BitcodeReader::parseConstants() {
InBounds = true;
SmallVector<Constant*, 16> Elts;
- Type *Elt0FullTy = nullptr;
+ unsigned BaseTypeID = Record[OpNum];
while (OpNum != Record.size()) {
- if (!Elt0FullTy)
- Elt0FullTy = getTypeByID(Record[OpNum]);
Type *ElTy = getTypeByID(Record[OpNum++]);
if (!ElTy)
return error("Invalid record");
@@ -2739,10 +2758,21 @@ Error BitcodeReader::parseConstants() {
if (Elts.size() < 1)
return error("Invalid gep with no operands");
- PointerType *OrigPtrTy = cast<PointerType>(Elt0FullTy->getScalarType());
- if (!PointeeType)
- PointeeType = OrigPtrTy->getPointerElementType();
- else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType))
+ Type *BaseType = getTypeByID(BaseTypeID);
+ if (isa<VectorType>(BaseType)) {
+ BaseTypeID = getContainedTypeID(BaseTypeID, 0);
+ BaseType = getTypeByID(BaseTypeID);
+ }
+
+ PointerType *OrigPtrTy = dyn_cast_or_null<PointerType>(BaseType);
+ if (!OrigPtrTy)
+ return error("GEP base operand must be pointer or vector of pointer");
+
+ if (!PointeeType) {
+ PointeeType = getPtrElementTypeByID(BaseTypeID);
+ if (!PointeeType)
+ return error("Missing element type for old-style constant GEP");
+ } else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType))
return error("Explicit gep operator type does not match pointee type "
"of pointer operand");
@@ -3414,11 +3444,13 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
if (Record.size() < 8)
return error("Invalid record");
- Type *FTy = getTypeByID(Record[0]);
+ unsigned FTyID = Record[0];
+ Type *FTy = getTypeByID(FTyID);
if (!FTy)
return error("Invalid record");
if (isa<PointerType>(FTy)) {
- FTy = getPtrElementTypeByID(Record[0]);
+ FTyID = getContainedTypeID(FTyID, 0);
+ FTy = getTypeByID(FTyID);
if (!FTy)
return error("Missing element type for old-style function");
}
@@ -3461,8 +3493,11 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
Func->removeParamAttr(i, Kind);
- Type *PTy = cast<FunctionType>(FTy)->getParamType(i);
- Type *PtrEltTy = PTy->getPointerElementType();
+ unsigned ParamTypeID = getContainedTypeID(FTyID, i + 1);
+ Type *PtrEltTy = getPtrElementTypeByID(ParamTypeID);
+ if (!PtrEltTy)
+ return error("Missing param element type for attribute upgrade");
+
Attribute NewAttr;
switch (Kind) {
case Attribute::ByVal: