forked from OSchip/llvm-project
[Bitcode] Fully support opaque pointer auto upgrade
This completes the propagation of type IDs through bitcode reading, and switches remaining uses of getPointerElementType() to use contained type IDs. The main new thing here is that sometimes we need to create a type ID for a type that was not explicitly encoded in bitcode (or we don't know its ID at the current point). For such types we create a "virtual" type ID, which is cached based on the type and the contained type IDs. Luckily, we generally only need zero or one contained type IDs, and in the one case where we need two, we can get away with not including it in the cache key. With this change, we pass the entirety of llvm-test-suite at O3 with opaque pointers. Differential Revision: https://reviews.llvm.org/D120471
This commit is contained in:
parent
04661a4d8e
commit
e3a9f68e2c
llvm
|
@ -39,6 +39,7 @@
|
||||||
#include "llvm/IR/DerivedTypes.h"
|
#include "llvm/IR/DerivedTypes.h"
|
||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
#include "llvm/IR/GVMaterializer.h"
|
#include "llvm/IR/GVMaterializer.h"
|
||||||
|
#include "llvm/IR/GetElementPtrTypeIterator.h"
|
||||||
#include "llvm/IR/GlobalAlias.h"
|
#include "llvm/IR/GlobalAlias.h"
|
||||||
#include "llvm/IR/GlobalIFunc.h"
|
#include "llvm/IR/GlobalIFunc.h"
|
||||||
#include "llvm/IR/GlobalObject.h"
|
#include "llvm/IR/GlobalObject.h"
|
||||||
|
@ -488,6 +489,13 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
|
||||||
/// types of a Type*. This is used during upgrades of typed pointer IR in
|
/// types of a Type*. This is used during upgrades of typed pointer IR in
|
||||||
/// opaque pointer mode.
|
/// opaque pointer mode.
|
||||||
DenseMap<unsigned, SmallVector<unsigned, 1>> ContainedTypeIDs;
|
DenseMap<unsigned, SmallVector<unsigned, 1>> ContainedTypeIDs;
|
||||||
|
/// In some cases, we need to create a type ID for a type that was not
|
||||||
|
/// explicitly encoded in the bitcode, or we don't know about at the current
|
||||||
|
/// point. For example, a global may explicitly encode the value type ID, but
|
||||||
|
/// not have a type ID for the pointer to value type, for which we create a
|
||||||
|
/// virtual type ID instead. This map stores the new type ID that was created
|
||||||
|
/// for the given pair of Type and contained type ID.
|
||||||
|
DenseMap<std::pair<Type *, unsigned>, unsigned> VirtualTypeIDs;
|
||||||
DenseMap<Function *, unsigned> FunctionTypeIDs;
|
DenseMap<Function *, unsigned> FunctionTypeIDs;
|
||||||
BitcodeReaderValueList ValueList;
|
BitcodeReaderValueList ValueList;
|
||||||
Optional<MetadataLoader> MDLoader;
|
Optional<MetadataLoader> MDLoader;
|
||||||
|
@ -595,12 +603,11 @@ private:
|
||||||
StructType *createIdentifiedStructType(LLVMContext &Context);
|
StructType *createIdentifiedStructType(LLVMContext &Context);
|
||||||
|
|
||||||
static constexpr unsigned InvalidTypeID = ~0u;
|
static constexpr unsigned InvalidTypeID = ~0u;
|
||||||
/// Placeholder for value type IDs we don't yet determine.
|
|
||||||
static constexpr unsigned TODOTypeID = InvalidTypeID - 1;
|
|
||||||
|
|
||||||
Type *getTypeByID(unsigned ID);
|
Type *getTypeByID(unsigned ID);
|
||||||
Type *getPtrElementTypeByID(unsigned ID);
|
Type *getPtrElementTypeByID(unsigned ID);
|
||||||
unsigned getContainedTypeID(unsigned ID, unsigned Idx = 0);
|
unsigned getContainedTypeID(unsigned ID, unsigned Idx = 0);
|
||||||
|
unsigned getVirtualTypeID(Type *Ty, ArrayRef<unsigned> ContainedTypeIDs = {});
|
||||||
|
|
||||||
Value *getFnValueByID(unsigned ID, Type *Ty, unsigned TyID) {
|
Value *getFnValueByID(unsigned ID, Type *Ty, unsigned TyID) {
|
||||||
if (Ty && Ty->isMetadataTy())
|
if (Ty && Ty->isMetadataTy())
|
||||||
|
@ -638,6 +645,8 @@ private:
|
||||||
// have.
|
// have.
|
||||||
TypeID = ValueList.getTypeID(ValNo);
|
TypeID = ValueList.getTypeID(ValNo);
|
||||||
ResVal = getFnValueByID(ValNo, nullptr, TypeID);
|
ResVal = getFnValueByID(ValNo, nullptr, TypeID);
|
||||||
|
assert((!ResVal || ResVal->getType() == getTypeByID(TypeID)) &&
|
||||||
|
"Incorrect type ID stored for value");
|
||||||
return ResVal == nullptr;
|
return ResVal == nullptr;
|
||||||
}
|
}
|
||||||
if (Slot == Record.size())
|
if (Slot == Record.size())
|
||||||
|
@ -693,7 +702,7 @@ private:
|
||||||
/// Upgrades old-style typeless byval/sret/inalloca attributes by adding the
|
/// Upgrades old-style typeless byval/sret/inalloca attributes by adding the
|
||||||
/// corresponding argument's pointee type. Also upgrades intrinsics that now
|
/// corresponding argument's pointee type. Also upgrades intrinsics that now
|
||||||
/// require an elementtype attribute.
|
/// require an elementtype attribute.
|
||||||
void propagateAttributeTypes(CallBase *CB, ArrayRef<Type *> ArgsTys);
|
void propagateAttributeTypes(CallBase *CB, ArrayRef<unsigned> ArgsTys);
|
||||||
|
|
||||||
/// Converts alignment exponent (i.e. power of two (or zero)) to the
|
/// Converts alignment exponent (i.e. power of two (or zero)) to the
|
||||||
/// corresponding alignment to use. If alignment is too large, returns
|
/// corresponding alignment to use. If alignment is too large, returns
|
||||||
|
@ -1188,9 +1197,6 @@ Type *BitcodeReader::getTypeByID(unsigned ID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned BitcodeReader::getContainedTypeID(unsigned ID, unsigned Idx) {
|
unsigned BitcodeReader::getContainedTypeID(unsigned ID, unsigned Idx) {
|
||||||
if (ID == TODOTypeID)
|
|
||||||
return TODOTypeID;
|
|
||||||
|
|
||||||
auto It = ContainedTypeIDs.find(ID);
|
auto It = ContainedTypeIDs.find(ID);
|
||||||
if (It == ContainedTypeIDs.end())
|
if (It == ContainedTypeIDs.end())
|
||||||
return InvalidTypeID;
|
return InvalidTypeID;
|
||||||
|
@ -1218,6 +1224,41 @@ Type *BitcodeReader::getPtrElementTypeByID(unsigned ID) {
|
||||||
return ElemTy;
|
return ElemTy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned BitcodeReader::getVirtualTypeID(Type *Ty,
|
||||||
|
ArrayRef<unsigned> ChildTypeIDs) {
|
||||||
|
unsigned ChildTypeID = ChildTypeIDs.empty() ? InvalidTypeID : ChildTypeIDs[0];
|
||||||
|
auto CacheKey = std::make_pair(Ty, ChildTypeID);
|
||||||
|
auto It = VirtualTypeIDs.find(CacheKey);
|
||||||
|
if (It != VirtualTypeIDs.end()) {
|
||||||
|
// The cmpxchg return value is the only place we need more than one
|
||||||
|
// contained type ID, however the second one will always be the same (i1),
|
||||||
|
// so we don't need to include it in the cache key. This asserts that the
|
||||||
|
// contained types are indeed as expected and there are no collisions.
|
||||||
|
assert((ChildTypeIDs.empty() ||
|
||||||
|
ContainedTypeIDs[It->second] == ChildTypeIDs) &&
|
||||||
|
"Incorrect cached contained type IDs");
|
||||||
|
return It->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (!Ty->isOpaquePointerTy()) {
|
||||||
|
assert(Ty->getNumContainedTypes() == ChildTypeIDs.size() &&
|
||||||
|
"Wrong number of contained types");
|
||||||
|
for (auto Pair : zip(Ty->subtypes(), ChildTypeIDs)) {
|
||||||
|
assert(std::get<0>(Pair) == getTypeByID(std::get<1>(Pair)) &&
|
||||||
|
"Incorrect contained type ID");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned TypeID = TypeList.size();
|
||||||
|
TypeList.push_back(Ty);
|
||||||
|
if (!ChildTypeIDs.empty())
|
||||||
|
append_range(ContainedTypeIDs[TypeID], ChildTypeIDs);
|
||||||
|
VirtualTypeIDs.insert({CacheKey, TypeID});
|
||||||
|
return TypeID;
|
||||||
|
}
|
||||||
|
|
||||||
StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context,
|
StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context,
|
||||||
StringRef Name) {
|
StringRef Name) {
|
||||||
auto *Ret = StructType::create(Context, Name);
|
auto *Ret = StructType::create(Context, Name);
|
||||||
|
@ -2406,8 +2447,9 @@ Error BitcodeReader::parseConstants() {
|
||||||
SmallVector<uint64_t, 64> Record;
|
SmallVector<uint64_t, 64> Record;
|
||||||
|
|
||||||
// Read all the records for this value table.
|
// Read all the records for this value table.
|
||||||
unsigned CurTyID = TODOTypeID;
|
|
||||||
Type *CurTy = Type::getInt32Ty(Context);
|
Type *CurTy = Type::getInt32Ty(Context);
|
||||||
|
unsigned Int32TyID = getVirtualTypeID(CurTy);
|
||||||
|
unsigned CurTyID = Int32TyID;
|
||||||
Type *CurElemTy = nullptr;
|
Type *CurElemTy = nullptr;
|
||||||
unsigned NextCstNo = ValueList.size();
|
unsigned NextCstNo = ValueList.size();
|
||||||
|
|
||||||
|
@ -2460,18 +2502,22 @@ Error BitcodeReader::parseConstants() {
|
||||||
Constant *Op1 = ValueList.getConstantFwdRef(Op1Idx, OpTy, OpTyID);
|
Constant *Op1 = ValueList.getConstantFwdRef(Op1Idx, OpTy, OpTyID);
|
||||||
Type *ShufTy =
|
Type *ShufTy =
|
||||||
VectorType::get(Type::getInt32Ty(Context), RTy->getElementCount());
|
VectorType::get(Type::getInt32Ty(Context), RTy->getElementCount());
|
||||||
Constant *Op2 = ValueList.getConstantFwdRef(Op2Idx, ShufTy, TODOTypeID);
|
Constant *Op2 = ValueList.getConstantFwdRef(
|
||||||
|
Op2Idx, ShufTy, getVirtualTypeID(ShufTy, Int32TyID));
|
||||||
if (!ShuffleVectorInst::isValidOperands(Op0, Op1, Op2))
|
if (!ShuffleVectorInst::isValidOperands(Op0, Op1, Op2))
|
||||||
return error("Invalid shufflevector operands");
|
return error("Invalid shufflevector operands");
|
||||||
SmallVector<int, 16> Mask;
|
SmallVector<int, 16> Mask;
|
||||||
ShuffleVectorInst::getShuffleMask(Op2, Mask);
|
ShuffleVectorInst::getShuffleMask(Op2, Mask);
|
||||||
Value *V = ConstantExpr::getShuffleVector(Op0, Op1, Mask);
|
Value *V = ConstantExpr::getShuffleVector(Op0, Op1, Mask);
|
||||||
ValueList.assignValue(CstNo, V, TODOTypeID);
|
ValueList.assignValue(
|
||||||
|
CstNo, V,
|
||||||
|
getVirtualTypeID(V->getType(), getContainedTypeID(OpTyID)));
|
||||||
}
|
}
|
||||||
for (auto &DelayedSelector : DelayedSelectors) {
|
for (auto &DelayedSelector : DelayedSelectors) {
|
||||||
Type *OpTy = DelayedSelector.OpTy;
|
Type *OpTy = DelayedSelector.OpTy;
|
||||||
unsigned OpTyID = DelayedSelector.OpTyID;
|
unsigned OpTyID = DelayedSelector.OpTyID;
|
||||||
Type *SelectorTy = Type::getInt1Ty(Context);
|
Type *SelectorTy = Type::getInt1Ty(Context);
|
||||||
|
unsigned SelectorTyID = getVirtualTypeID(SelectorTy);
|
||||||
uint64_t Op0Idx = DelayedSelector.Op0Idx;
|
uint64_t Op0Idx = DelayedSelector.Op0Idx;
|
||||||
uint64_t Op1Idx = DelayedSelector.Op1Idx;
|
uint64_t Op1Idx = DelayedSelector.Op1Idx;
|
||||||
uint64_t Op2Idx = DelayedSelector.Op2Idx;
|
uint64_t Op2Idx = DelayedSelector.Op2Idx;
|
||||||
|
@ -2483,13 +2529,15 @@ Error BitcodeReader::parseConstants() {
|
||||||
if (VectorType *VTy = dyn_cast<VectorType>(OpTy)) {
|
if (VectorType *VTy = dyn_cast<VectorType>(OpTy)) {
|
||||||
Value *V = ValueList[Op0Idx];
|
Value *V = ValueList[Op0Idx];
|
||||||
assert(V);
|
assert(V);
|
||||||
if (SelectorTy != V->getType())
|
if (SelectorTy != V->getType()) {
|
||||||
SelectorTy = VectorType::get(SelectorTy, VTy->getElementCount());
|
SelectorTy = VectorType::get(SelectorTy, VTy->getElementCount());
|
||||||
|
SelectorTyID = getVirtualTypeID(SelectorTy, SelectorTyID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Constant *Op0 =
|
Constant *Op0 =
|
||||||
ValueList.getConstantFwdRef(Op0Idx, SelectorTy, TODOTypeID);
|
ValueList.getConstantFwdRef(Op0Idx, SelectorTy, SelectorTyID);
|
||||||
Value *V = ConstantExpr::getSelect(Op0, Op1, Op2);
|
Value *V = ConstantExpr::getSelect(Op0, Op1, Op2);
|
||||||
ValueList.assignValue(CstNo, V, TODOTypeID);
|
ValueList.assignValue(CstNo, V, OpTyID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NextCstNo != ValueList.size())
|
if (NextCstNo != ValueList.size())
|
||||||
|
@ -2834,7 +2882,7 @@ Error BitcodeReader::parseConstants() {
|
||||||
} else {
|
} else {
|
||||||
// Deprecated, but still needed to read old bitcode files.
|
// Deprecated, but still needed to read old bitcode files.
|
||||||
Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context),
|
Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context),
|
||||||
TODOTypeID);
|
Int32TyID);
|
||||||
}
|
}
|
||||||
if (!Op1)
|
if (!Op1)
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
|
@ -2860,7 +2908,7 @@ Error BitcodeReader::parseConstants() {
|
||||||
} else {
|
} else {
|
||||||
// Deprecated, but still needed to read old bitcode files.
|
// Deprecated, but still needed to read old bitcode files.
|
||||||
Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context),
|
Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context),
|
||||||
TODOTypeID);
|
Int32TyID);
|
||||||
}
|
}
|
||||||
if (!Op2)
|
if (!Op2)
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
|
@ -3095,6 +3143,7 @@ Error BitcodeReader::parseConstants() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(V->getType() == getTypeByID(CurTyID) && "Incorrect result type ID");
|
||||||
ValueList.assignValue(NextCstNo, V, CurTyID);
|
ValueList.assignValue(NextCstNo, V, CurTyID);
|
||||||
++NextCstNo;
|
++NextCstNo;
|
||||||
}
|
}
|
||||||
|
@ -3387,7 +3436,8 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
|
||||||
if (!Ty->isPointerTy())
|
if (!Ty->isPointerTy())
|
||||||
return error("Invalid type for value");
|
return error("Invalid type for value");
|
||||||
AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
|
AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
|
||||||
Ty = getPtrElementTypeByID(Record[0]);
|
TyID = getContainedTypeID(TyID);
|
||||||
|
Ty = getTypeByID(TyID);
|
||||||
if (!Ty)
|
if (!Ty)
|
||||||
return error("Missing element type for old-style global");
|
return error("Missing element type for old-style global");
|
||||||
}
|
}
|
||||||
|
@ -3435,7 +3485,7 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
|
||||||
else
|
else
|
||||||
upgradeDLLImportExportLinkage(NewGV, RawLinkage);
|
upgradeDLLImportExportLinkage(NewGV, RawLinkage);
|
||||||
|
|
||||||
ValueList.push_back(NewGV, TyID);
|
ValueList.push_back(NewGV, getVirtualTypeID(NewGV->getType(), TyID));
|
||||||
|
|
||||||
// Remember which value to use for the global initializer.
|
// Remember which value to use for the global initializer.
|
||||||
if (unsigned InitID = Record[2])
|
if (unsigned InitID = Record[2])
|
||||||
|
@ -3613,7 +3663,7 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
|
||||||
Func->setPartition(StringRef(Strtab.data() + Record[17], Record[18]));
|
Func->setPartition(StringRef(Strtab.data() + Record[17], Record[18]));
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueList.push_back(Func, TODOTypeID);
|
ValueList.push_back(Func, getVirtualTypeID(Func->getType(), FTyID));
|
||||||
|
|
||||||
if (OperandInfo.PersonalityFn || OperandInfo.Prefix || OperandInfo.Prologue)
|
if (OperandInfo.PersonalityFn || OperandInfo.Prefix || OperandInfo.Prologue)
|
||||||
FunctionOperands.push_back(OperandInfo);
|
FunctionOperands.push_back(OperandInfo);
|
||||||
|
@ -3656,7 +3706,8 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
|
||||||
if (!PTy)
|
if (!PTy)
|
||||||
return error("Invalid type for value");
|
return error("Invalid type for value");
|
||||||
AddrSpace = PTy->getAddressSpace();
|
AddrSpace = PTy->getAddressSpace();
|
||||||
Ty = getPtrElementTypeByID(TypeID);
|
TypeID = getContainedTypeID(TypeID);
|
||||||
|
Ty = getTypeByID(TypeID);
|
||||||
if (!Ty)
|
if (!Ty)
|
||||||
return error("Missing element type for old-style indirect symbol");
|
return error("Missing element type for old-style indirect symbol");
|
||||||
} else {
|
} else {
|
||||||
|
@ -3703,7 +3754,7 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
|
||||||
OpNum += 2;
|
OpNum += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueList.push_back(NewGA, TypeID);
|
ValueList.push_back(NewGA, getVirtualTypeID(NewGA->getType(), TypeID));
|
||||||
IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
|
IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
|
||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
@ -4019,7 +4070,7 @@ Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcodeReader::propagateAttributeTypes(CallBase *CB,
|
void BitcodeReader::propagateAttributeTypes(CallBase *CB,
|
||||||
ArrayRef<Type *> ArgsTys) {
|
ArrayRef<unsigned> ArgTyIDs) {
|
||||||
for (unsigned i = 0; i != CB->arg_size(); ++i) {
|
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}) {
|
Attribute::InAlloca}) {
|
||||||
|
@ -4029,7 +4080,7 @@ void BitcodeReader::propagateAttributeTypes(CallBase *CB,
|
||||||
|
|
||||||
CB->removeParamAttr(i, Kind);
|
CB->removeParamAttr(i, Kind);
|
||||||
|
|
||||||
Type *PtrEltTy = ArgsTys[i]->getPointerElementType();
|
Type *PtrEltTy = getPtrElementTypeByID(ArgTyIDs[i]);
|
||||||
Attribute NewAttr;
|
Attribute NewAttr;
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
case Attribute::ByVal:
|
case Attribute::ByVal:
|
||||||
|
@ -4057,7 +4108,7 @@ void BitcodeReader::propagateAttributeTypes(CallBase *CB,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (CI.isIndirect && !CB->getParamElementType(ArgNo)) {
|
if (CI.isIndirect && !CB->getParamElementType(ArgNo)) {
|
||||||
Type *ElemTy = ArgsTys[ArgNo]->getPointerElementType();
|
Type *ElemTy = getPtrElementTypeByID(ArgTyIDs[ArgNo]);
|
||||||
CB->addParamAttr(
|
CB->addParamAttr(
|
||||||
ArgNo, Attribute::get(Context, Attribute::ElementType, ElemTy));
|
ArgNo, Attribute::get(Context, Attribute::ElementType, ElemTy));
|
||||||
}
|
}
|
||||||
|
@ -4070,7 +4121,7 @@ void BitcodeReader::propagateAttributeTypes(CallBase *CB,
|
||||||
case Intrinsic::preserve_array_access_index:
|
case Intrinsic::preserve_array_access_index:
|
||||||
case Intrinsic::preserve_struct_access_index:
|
case Intrinsic::preserve_struct_access_index:
|
||||||
if (!CB->getParamElementType(0)) {
|
if (!CB->getParamElementType(0)) {
|
||||||
Type *ElTy = ArgsTys[0]->getPointerElementType();
|
Type *ElTy = getPtrElementTypeByID(ArgTyIDs[0]);
|
||||||
Attribute NewAttr = Attribute::get(Context, Attribute::ElementType, ElTy);
|
Attribute NewAttr = Attribute::get(Context, Attribute::ElementType, ElTy);
|
||||||
CB->addParamAttr(0, NewAttr);
|
CB->addParamAttr(0, NewAttr);
|
||||||
}
|
}
|
||||||
|
@ -4351,14 +4402,17 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
case bitc::FUNC_CODE_INST_GEP: { // GEP: type, [n x operands]
|
case bitc::FUNC_CODE_INST_GEP: { // GEP: type, [n x operands]
|
||||||
unsigned OpNum = 0;
|
unsigned OpNum = 0;
|
||||||
|
|
||||||
|
unsigned TyID;
|
||||||
Type *Ty;
|
Type *Ty;
|
||||||
bool InBounds;
|
bool InBounds;
|
||||||
|
|
||||||
if (BitCode == bitc::FUNC_CODE_INST_GEP) {
|
if (BitCode == bitc::FUNC_CODE_INST_GEP) {
|
||||||
InBounds = Record[OpNum++];
|
InBounds = Record[OpNum++];
|
||||||
Ty = getTypeByID(Record[OpNum++]);
|
TyID = Record[OpNum++];
|
||||||
|
Ty = getTypeByID(TyID);
|
||||||
} else {
|
} else {
|
||||||
InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
|
InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
|
||||||
|
TyID = InvalidTypeID;
|
||||||
Ty = nullptr;
|
Ty = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4368,7 +4422,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
|
|
||||||
if (!Ty) {
|
if (!Ty) {
|
||||||
Ty = BasePtr->getType()->getScalarType()->getPointerElementType();
|
TyID = getContainedTypeID(BasePtrTypeID);
|
||||||
|
if (BasePtr->getType()->isVectorTy())
|
||||||
|
TyID = getContainedTypeID(TyID);
|
||||||
|
Ty = getTypeByID(TyID);
|
||||||
} else if (!cast<PointerType>(BasePtr->getType()->getScalarType())
|
} else if (!cast<PointerType>(BasePtr->getType()->getScalarType())
|
||||||
->isOpaqueOrPointeeTypeMatches(Ty)) {
|
->isOpaqueOrPointeeTypeMatches(Ty)) {
|
||||||
return error(
|
return error(
|
||||||
|
@ -4385,7 +4442,27 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
}
|
}
|
||||||
|
|
||||||
I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx);
|
I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx);
|
||||||
ResTypeID = TODOTypeID;
|
|
||||||
|
ResTypeID = TyID;
|
||||||
|
auto GTI = std::next(gep_type_begin(I));
|
||||||
|
for (Value *Idx : drop_begin(cast<GEPOperator>(I)->indices())) {
|
||||||
|
unsigned SubType = 0;
|
||||||
|
if (GTI.isStruct()) {
|
||||||
|
ConstantInt *IdxC =
|
||||||
|
Idx->getType()->isVectorTy()
|
||||||
|
? cast<ConstantInt>(cast<Constant>(Idx)->getSplatValue())
|
||||||
|
: cast<ConstantInt>(Idx);
|
||||||
|
SubType = IdxC->getZExtValue();
|
||||||
|
}
|
||||||
|
ResTypeID = getContainedTypeID(ResTypeID, SubType);
|
||||||
|
++GTI;
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point ResTypeID is the result element type. We need a pointer
|
||||||
|
// or vector of pointer to it.
|
||||||
|
ResTypeID = getVirtualTypeID(I->getType()->getScalarType(), ResTypeID);
|
||||||
|
if (I->getType()->isVectorTy())
|
||||||
|
ResTypeID = getVirtualTypeID(I->getType(), ResTypeID);
|
||||||
|
|
||||||
InstructionList.push_back(I);
|
InstructionList.push_back(I);
|
||||||
if (InBounds)
|
if (InBounds)
|
||||||
|
@ -4491,11 +4568,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
unsigned OpNum = 0;
|
unsigned OpNum = 0;
|
||||||
Value *TrueVal, *FalseVal, *Cond;
|
Value *TrueVal, *FalseVal, *Cond;
|
||||||
unsigned TypeID;
|
unsigned TypeID;
|
||||||
|
Type *CondType = Type::getInt1Ty(Context);
|
||||||
if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, TypeID) ||
|
if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, TypeID) ||
|
||||||
popValue(Record, OpNum, NextValueNo, TrueVal->getType(), TypeID,
|
popValue(Record, OpNum, NextValueNo, TrueVal->getType(), TypeID,
|
||||||
FalseVal) ||
|
FalseVal) ||
|
||||||
popValue(Record, OpNum, NextValueNo, Type::getInt1Ty(Context),
|
popValue(Record, OpNum, NextValueNo, CondType,
|
||||||
TODOTypeID, Cond))
|
getVirtualTypeID(CondType), Cond))
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
|
|
||||||
I = SelectInst::Create(Cond, TrueVal, FalseVal);
|
I = SelectInst::Create(Cond, TrueVal, FalseVal);
|
||||||
|
@ -4589,7 +4667,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
return error("Invalid type for value");
|
return error("Invalid type for value");
|
||||||
|
|
||||||
I = new ShuffleVectorInst(Vec1, Vec2, Mask);
|
I = new ShuffleVectorInst(Vec1, Vec2, Mask);
|
||||||
ResTypeID = TODOTypeID;
|
ResTypeID =
|
||||||
|
getVirtualTypeID(I->getType(), getContainedTypeID(Vec1TypeID));
|
||||||
InstructionList.push_back(I);
|
InstructionList.push_back(I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4625,7 +4704,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
I = new FCmpInst((FCmpInst::Predicate)PredVal, LHS, RHS);
|
I = new FCmpInst((FCmpInst::Predicate)PredVal, LHS, RHS);
|
||||||
else
|
else
|
||||||
I = new ICmpInst((ICmpInst::Predicate)PredVal, LHS, RHS);
|
I = new ICmpInst((ICmpInst::Predicate)PredVal, LHS, RHS);
|
||||||
ResTypeID = TODOTypeID;
|
|
||||||
|
ResTypeID = getVirtualTypeID(I->getType()->getScalarType());
|
||||||
|
if (LHS->getType()->isVectorTy())
|
||||||
|
ResTypeID = getVirtualTypeID(I->getType(), ResTypeID);
|
||||||
|
|
||||||
if (FMF.any())
|
if (FMF.any())
|
||||||
I->setFastMathFlags(FMF);
|
I->setFastMathFlags(FMF);
|
||||||
|
@ -4667,8 +4749,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BasicBlock *FalseDest = getBasicBlock(Record[1]);
|
BasicBlock *FalseDest = getBasicBlock(Record[1]);
|
||||||
Value *Cond = getValue(Record, 2, NextValueNo,
|
Type *CondType = Type::getInt1Ty(Context);
|
||||||
Type::getInt1Ty(Context), TODOTypeID);
|
Value *Cond = getValue(Record, 2, NextValueNo, CondType,
|
||||||
|
getVirtualTypeID(CondType));
|
||||||
if (!FalseDest || !Cond)
|
if (!FalseDest || !Cond)
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
I = BranchInst::Create(TrueDest, FalseDest, Cond);
|
I = BranchInst::Create(TrueDest, FalseDest, Cond);
|
||||||
|
@ -4680,8 +4763,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
if (Record.size() != 1 && Record.size() != 2)
|
if (Record.size() != 1 && Record.size() != 2)
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
unsigned Idx = 0;
|
unsigned Idx = 0;
|
||||||
Value *CleanupPad = getValue(
|
Type *TokenTy = Type::getTokenTy(Context);
|
||||||
Record, Idx++, NextValueNo, Type::getTokenTy(Context), TODOTypeID);
|
Value *CleanupPad = getValue(Record, Idx++, NextValueNo, TokenTy,
|
||||||
|
getVirtualTypeID(TokenTy));
|
||||||
if (!CleanupPad)
|
if (!CleanupPad)
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
BasicBlock *UnwindDest = nullptr;
|
BasicBlock *UnwindDest = nullptr;
|
||||||
|
@ -4699,8 +4783,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
if (Record.size() != 2)
|
if (Record.size() != 2)
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
unsigned Idx = 0;
|
unsigned Idx = 0;
|
||||||
Value *CatchPad = getValue(
|
Type *TokenTy = Type::getTokenTy(Context);
|
||||||
Record, Idx++, NextValueNo, Type::getTokenTy(Context), TODOTypeID);
|
Value *CatchPad = getValue(Record, Idx++, NextValueNo, TokenTy,
|
||||||
|
getVirtualTypeID(TokenTy));
|
||||||
if (!CatchPad)
|
if (!CatchPad)
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
BasicBlock *BB = getBasicBlock(Record[Idx++]);
|
BasicBlock *BB = getBasicBlock(Record[Idx++]);
|
||||||
|
@ -4718,8 +4803,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
|
|
||||||
unsigned Idx = 0;
|
unsigned Idx = 0;
|
||||||
|
|
||||||
Value *ParentPad = getValue(
|
Type *TokenTy = Type::getTokenTy(Context);
|
||||||
Record, Idx++, NextValueNo, Type::getTokenTy(Context), TODOTypeID);
|
Value *ParentPad = getValue(Record, Idx++, NextValueNo, TokenTy,
|
||||||
|
getVirtualTypeID(TokenTy));
|
||||||
|
|
||||||
unsigned NumHandlers = Record[Idx++];
|
unsigned NumHandlers = Record[Idx++];
|
||||||
|
|
||||||
|
@ -4746,7 +4832,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
for (BasicBlock *Handler : Handlers)
|
for (BasicBlock *Handler : Handlers)
|
||||||
CatchSwitch->addHandler(Handler);
|
CatchSwitch->addHandler(Handler);
|
||||||
I = CatchSwitch;
|
I = CatchSwitch;
|
||||||
ResTypeID = TODOTypeID;
|
ResTypeID = getVirtualTypeID(I->getType());
|
||||||
InstructionList.push_back(I);
|
InstructionList.push_back(I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4758,8 +4844,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
|
|
||||||
unsigned Idx = 0;
|
unsigned Idx = 0;
|
||||||
|
|
||||||
Value *ParentPad = getValue(
|
Type *TokenTy = Type::getTokenTy(Context);
|
||||||
Record, Idx++, NextValueNo, Type::getTokenTy(Context), TODOTypeID);
|
Value *ParentPad = getValue(Record, Idx++, NextValueNo, TokenTy,
|
||||||
|
getVirtualTypeID(TokenTy));
|
||||||
|
|
||||||
unsigned NumArgOperands = Record[Idx++];
|
unsigned NumArgOperands = Record[Idx++];
|
||||||
|
|
||||||
|
@ -4779,7 +4866,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
I = CleanupPadInst::Create(ParentPad, Args);
|
I = CleanupPadInst::Create(ParentPad, Args);
|
||||||
else
|
else
|
||||||
I = CatchPadInst::Create(ParentPad, Args);
|
I = CatchPadInst::Create(ParentPad, Args);
|
||||||
ResTypeID = TODOTypeID;
|
ResTypeID = getVirtualTypeID(I->getType());
|
||||||
InstructionList.push_back(I);
|
InstructionList.push_back(I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4904,9 +4991,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
BasicBlock *NormalBB = getBasicBlock(Record[OpNum++]);
|
BasicBlock *NormalBB = getBasicBlock(Record[OpNum++]);
|
||||||
BasicBlock *UnwindBB = getBasicBlock(Record[OpNum++]);
|
BasicBlock *UnwindBB = getBasicBlock(Record[OpNum++]);
|
||||||
|
|
||||||
|
unsigned FTyID = InvalidTypeID;
|
||||||
FunctionType *FTy = nullptr;
|
FunctionType *FTy = nullptr;
|
||||||
if ((CCInfo >> 13) & 1) {
|
if ((CCInfo >> 13) & 1) {
|
||||||
FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]));
|
FTyID = Record[OpNum++];
|
||||||
|
FTy = dyn_cast<FunctionType>(getTypeByID(FTyID));
|
||||||
if (!FTy)
|
if (!FTy)
|
||||||
return error("Explicit invoke type is not a function type");
|
return error("Explicit invoke type is not a function type");
|
||||||
}
|
}
|
||||||
|
@ -4920,8 +5009,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
if (!CalleeTy)
|
if (!CalleeTy)
|
||||||
return error("Callee is not a pointer");
|
return error("Callee is not a pointer");
|
||||||
if (!FTy) {
|
if (!FTy) {
|
||||||
FTy =
|
FTyID = getContainedTypeID(CalleeTypeID);
|
||||||
dyn_cast<FunctionType>(Callee->getType()->getPointerElementType());
|
FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID));
|
||||||
if (!FTy)
|
if (!FTy)
|
||||||
return error("Callee is not of pointer to function type");
|
return error("Callee is not of pointer to function type");
|
||||||
} else if (!CalleeTy->isOpaqueOrPointeeTypeMatches(FTy))
|
} else if (!CalleeTy->isOpaqueOrPointeeTypeMatches(FTy))
|
||||||
|
@ -4931,11 +5020,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
return error("Insufficient operands to call");
|
return error("Insufficient operands to call");
|
||||||
|
|
||||||
SmallVector<Value*, 16> Ops;
|
SmallVector<Value*, 16> Ops;
|
||||||
SmallVector<Type *, 16> ArgsTys;
|
SmallVector<unsigned, 16> ArgTyIDs;
|
||||||
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
|
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
|
||||||
Ops.push_back(getValue(Record, OpNum, NextValueNo,
|
unsigned ArgTyID = getContainedTypeID(FTyID, i + 1);
|
||||||
FTy->getParamType(i), TODOTypeID));
|
Ops.push_back(getValue(Record, OpNum, NextValueNo, FTy->getParamType(i),
|
||||||
ArgsTys.push_back(FTy->getParamType(i));
|
ArgTyID));
|
||||||
|
ArgTyIDs.push_back(ArgTyID);
|
||||||
if (!Ops.back())
|
if (!Ops.back())
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
}
|
}
|
||||||
|
@ -4951,19 +5041,19 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
Ops.push_back(Op);
|
Ops.push_back(Op);
|
||||||
ArgsTys.push_back(Op->getType());
|
ArgTyIDs.push_back(OpTypeID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
I = InvokeInst::Create(FTy, Callee, NormalBB, UnwindBB, Ops,
|
I = InvokeInst::Create(FTy, Callee, NormalBB, UnwindBB, Ops,
|
||||||
OperandBundles);
|
OperandBundles);
|
||||||
ResTypeID = TODOTypeID;
|
ResTypeID = getContainedTypeID(FTyID);
|
||||||
OperandBundles.clear();
|
OperandBundles.clear();
|
||||||
InstructionList.push_back(I);
|
InstructionList.push_back(I);
|
||||||
cast<InvokeInst>(I)->setCallingConv(
|
cast<InvokeInst>(I)->setCallingConv(
|
||||||
static_cast<CallingConv::ID>(CallingConv::MaxID & CCInfo));
|
static_cast<CallingConv::ID>(CallingConv::MaxID & CCInfo));
|
||||||
cast<InvokeInst>(I)->setAttributes(PAL);
|
cast<InvokeInst>(I)->setAttributes(PAL);
|
||||||
propagateAttributeTypes(cast<CallBase>(I), ArgsTys);
|
propagateAttributeTypes(cast<CallBase>(I), ArgTyIDs);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4989,9 +5079,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
for (unsigned i = 0, e = NumIndirectDests; i != e; ++i)
|
for (unsigned i = 0, e = NumIndirectDests; i != e; ++i)
|
||||||
IndirectDests.push_back(getBasicBlock(Record[OpNum++]));
|
IndirectDests.push_back(getBasicBlock(Record[OpNum++]));
|
||||||
|
|
||||||
|
unsigned FTyID = InvalidTypeID;
|
||||||
FunctionType *FTy = nullptr;
|
FunctionType *FTy = nullptr;
|
||||||
if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) {
|
if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) {
|
||||||
FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]));
|
FTyID = Record[OpNum++];
|
||||||
|
FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID));
|
||||||
if (!FTy)
|
if (!FTy)
|
||||||
return error("Explicit call type is not a function type");
|
return error("Explicit call type is not a function type");
|
||||||
}
|
}
|
||||||
|
@ -5005,8 +5097,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
if (!OpTy)
|
if (!OpTy)
|
||||||
return error("Callee is not a pointer type");
|
return error("Callee is not a pointer type");
|
||||||
if (!FTy) {
|
if (!FTy) {
|
||||||
FTy =
|
FTyID = getContainedTypeID(CalleeTypeID);
|
||||||
dyn_cast<FunctionType>(Callee->getType()->getPointerElementType());
|
FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID));
|
||||||
if (!FTy)
|
if (!FTy)
|
||||||
return error("Callee is not of pointer to function type");
|
return error("Callee is not of pointer to function type");
|
||||||
} else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy))
|
} else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy))
|
||||||
|
@ -5016,19 +5108,20 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
return error("Insufficient operands to call");
|
return error("Insufficient operands to call");
|
||||||
|
|
||||||
SmallVector<Value*, 16> Args;
|
SmallVector<Value*, 16> Args;
|
||||||
SmallVector<Type *, 16> ArgsTys;
|
SmallVector<unsigned, 16> ArgTyIDs;
|
||||||
// Read the fixed params.
|
// Read the fixed params.
|
||||||
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
|
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
|
||||||
Value *Arg;
|
Value *Arg;
|
||||||
|
unsigned ArgTyID = getContainedTypeID(FTyID, i + 1);
|
||||||
if (FTy->getParamType(i)->isLabelTy())
|
if (FTy->getParamType(i)->isLabelTy())
|
||||||
Arg = getBasicBlock(Record[OpNum]);
|
Arg = getBasicBlock(Record[OpNum]);
|
||||||
else
|
else
|
||||||
Arg = getValue(Record, OpNum, NextValueNo, FTy->getParamType(i),
|
Arg = getValue(Record, OpNum, NextValueNo, FTy->getParamType(i),
|
||||||
TODOTypeID);
|
ArgTyID);
|
||||||
if (!Arg)
|
if (!Arg)
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
Args.push_back(Arg);
|
Args.push_back(Arg);
|
||||||
ArgsTys.push_back(Arg->getType());
|
ArgTyIDs.push_back(ArgTyID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read type/value pairs for varargs params.
|
// Read type/value pairs for varargs params.
|
||||||
|
@ -5042,19 +5135,19 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
Args.push_back(Op);
|
Args.push_back(Op);
|
||||||
ArgsTys.push_back(Op->getType());
|
ArgTyIDs.push_back(OpTypeID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
I = CallBrInst::Create(FTy, Callee, DefaultDest, IndirectDests, Args,
|
I = CallBrInst::Create(FTy, Callee, DefaultDest, IndirectDests, Args,
|
||||||
OperandBundles);
|
OperandBundles);
|
||||||
ResTypeID = TODOTypeID;
|
ResTypeID = getContainedTypeID(FTyID);
|
||||||
OperandBundles.clear();
|
OperandBundles.clear();
|
||||||
InstructionList.push_back(I);
|
InstructionList.push_back(I);
|
||||||
cast<CallBrInst>(I)->setCallingConv(
|
cast<CallBrInst>(I)->setCallingConv(
|
||||||
static_cast<CallingConv::ID>((0x7ff & CCInfo) >> bitc::CALL_CCONV));
|
static_cast<CallingConv::ID>((0x7ff & CCInfo) >> bitc::CALL_CCONV));
|
||||||
cast<CallBrInst>(I)->setAttributes(PAL);
|
cast<CallBrInst>(I)->setAttributes(PAL);
|
||||||
propagateAttributeTypes(cast<CallBase>(I), ArgsTys);
|
propagateAttributeTypes(cast<CallBase>(I), ArgTyIDs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
|
case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
|
||||||
|
@ -5171,9 +5264,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
const uint64_t Rec = Record[3];
|
const uint64_t Rec = Record[3];
|
||||||
const bool InAlloca = Bitfield::get<APV::UsedWithInAlloca>(Rec);
|
const bool InAlloca = Bitfield::get<APV::UsedWithInAlloca>(Rec);
|
||||||
const bool SwiftError = Bitfield::get<APV::SwiftError>(Rec);
|
const bool SwiftError = Bitfield::get<APV::SwiftError>(Rec);
|
||||||
Type *Ty = getTypeByID(Record[0]);
|
unsigned TyID = Record[0];
|
||||||
|
Type *Ty = getTypeByID(TyID);
|
||||||
if (!Bitfield::get<APV::ExplicitType>(Rec)) {
|
if (!Bitfield::get<APV::ExplicitType>(Rec)) {
|
||||||
Ty = getPtrElementTypeByID(Record[0]);
|
TyID = getContainedTypeID(TyID);
|
||||||
|
Ty = getTypeByID(TyID);
|
||||||
if (!Ty)
|
if (!Ty)
|
||||||
return error("Missing element type for old-style alloca");
|
return error("Missing element type for old-style alloca");
|
||||||
}
|
}
|
||||||
|
@ -5204,7 +5299,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
AI->setUsedWithInAlloca(InAlloca);
|
AI->setUsedWithInAlloca(InAlloca);
|
||||||
AI->setSwiftError(SwiftError);
|
AI->setSwiftError(SwiftError);
|
||||||
I = AI;
|
I = AI;
|
||||||
ResTypeID = TODOTypeID;
|
ResTypeID = getVirtualTypeID(AI->getType(), TyID);
|
||||||
InstructionList.push_back(I);
|
InstructionList.push_back(I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5225,7 +5320,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
Ty = getTypeByID(ResTypeID);
|
Ty = getTypeByID(ResTypeID);
|
||||||
} else {
|
} else {
|
||||||
ResTypeID = getContainedTypeID(OpTypeID);
|
ResTypeID = getContainedTypeID(OpTypeID);
|
||||||
Ty = Op->getType()->getPointerElementType();
|
Ty = getTypeByID(ResTypeID);
|
||||||
|
if (!Ty)
|
||||||
|
return error("Missing element type for old-style load");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType()))
|
if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType()))
|
||||||
|
@ -5261,7 +5358,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
Ty = getTypeByID(ResTypeID);
|
Ty = getTypeByID(ResTypeID);
|
||||||
} else {
|
} else {
|
||||||
ResTypeID = getContainedTypeID(OpTypeID);
|
ResTypeID = getContainedTypeID(OpTypeID);
|
||||||
Ty = Op->getType()->getPointerElementType();
|
Ty = getTypeByID(ResTypeID);
|
||||||
|
if (!Ty)
|
||||||
|
return error("Missing element type for old style atomic load");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType()))
|
if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType()))
|
||||||
|
@ -5290,13 +5389,20 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
unsigned OpNum = 0;
|
unsigned OpNum = 0;
|
||||||
Value *Val, *Ptr;
|
Value *Val, *Ptr;
|
||||||
unsigned PtrTypeID, ValTypeID;
|
unsigned PtrTypeID, ValTypeID;
|
||||||
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID) ||
|
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID))
|
||||||
(BitCode == bitc::FUNC_CODE_INST_STORE
|
return error("Invalid record");
|
||||||
? getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID)
|
|
||||||
: popValue(Record, OpNum, NextValueNo,
|
if (BitCode == bitc::FUNC_CODE_INST_STORE) {
|
||||||
Ptr->getType()->getPointerElementType(),
|
if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID))
|
||||||
getContainedTypeID(PtrTypeID), Val)) ||
|
return error("Invalid record");
|
||||||
OpNum + 2 != Record.size())
|
} else {
|
||||||
|
ValTypeID = getContainedTypeID(PtrTypeID);
|
||||||
|
if (popValue(Record, OpNum, NextValueNo, getTypeByID(ValTypeID),
|
||||||
|
ValTypeID, Val))
|
||||||
|
return error("Invalid record");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OpNum + 2 != Record.size())
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
|
|
||||||
if (Error Err = typeCheckLoadStoreInst(Val->getType(), Ptr->getType()))
|
if (Error Err = typeCheckLoadStoreInst(Val->getType(), Ptr->getType()))
|
||||||
|
@ -5320,13 +5426,19 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
Value *Val, *Ptr;
|
Value *Val, *Ptr;
|
||||||
unsigned PtrTypeID, ValTypeID;
|
unsigned PtrTypeID, ValTypeID;
|
||||||
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID) ||
|
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID) ||
|
||||||
!isa<PointerType>(Ptr->getType()) ||
|
!isa<PointerType>(Ptr->getType()))
|
||||||
(BitCode == bitc::FUNC_CODE_INST_STOREATOMIC
|
return error("Invalid record");
|
||||||
? getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID)
|
if (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC) {
|
||||||
: popValue(Record, OpNum, NextValueNo,
|
if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID))
|
||||||
Ptr->getType()->getPointerElementType(),
|
return error("Invalid record");
|
||||||
getContainedTypeID(PtrTypeID), Val)) ||
|
} else {
|
||||||
OpNum + 4 != Record.size())
|
ValTypeID = getContainedTypeID(PtrTypeID);
|
||||||
|
if (popValue(Record, OpNum, NextValueNo, getTypeByID(ValTypeID),
|
||||||
|
ValTypeID, Val))
|
||||||
|
return error("Invalid record");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OpNum + 4 != Record.size())
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
|
|
||||||
if (Error Err = typeCheckLoadStoreInst(Val->getType(), Ptr->getType()))
|
if (Error Err = typeCheckLoadStoreInst(Val->getType(), Ptr->getType()))
|
||||||
|
@ -5364,8 +5476,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
|
|
||||||
Value *Cmp = nullptr;
|
Value *Cmp = nullptr;
|
||||||
unsigned CmpTypeID = getContainedTypeID(PtrTypeID);
|
unsigned CmpTypeID = getContainedTypeID(PtrTypeID);
|
||||||
if (popValue(Record, OpNum, NextValueNo,
|
if (popValue(Record, OpNum, NextValueNo, getTypeByID(CmpTypeID),
|
||||||
cast<PointerType>(Ptr->getType())->getPointerElementType(),
|
|
||||||
CmpTypeID, Cmp))
|
CmpTypeID, Cmp))
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
|
|
||||||
|
@ -5400,7 +5511,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
|
|
||||||
I = new AtomicCmpXchgInst(Ptr, Cmp, New, Alignment, SuccessOrdering,
|
I = new AtomicCmpXchgInst(Ptr, Cmp, New, Alignment, SuccessOrdering,
|
||||||
FailureOrdering, SSID);
|
FailureOrdering, SSID);
|
||||||
ResTypeID = TODOTypeID;
|
|
||||||
cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
|
cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
|
||||||
|
|
||||||
if (NumRecords < 8) {
|
if (NumRecords < 8) {
|
||||||
|
@ -5409,9 +5519,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
// expecting the first component of a modern cmpxchg.
|
// expecting the first component of a modern cmpxchg.
|
||||||
CurBB->getInstList().push_back(I);
|
CurBB->getInstList().push_back(I);
|
||||||
I = ExtractValueInst::Create(I, 0);
|
I = ExtractValueInst::Create(I, 0);
|
||||||
ResTypeID = TODOTypeID;
|
ResTypeID = CmpTypeID;
|
||||||
} else {
|
} else {
|
||||||
cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum + 4]);
|
cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum + 4]);
|
||||||
|
unsigned I1TypeID = getVirtualTypeID(Type::getInt1Ty(Context));
|
||||||
|
ResTypeID = getVirtualTypeID(I->getType(), {CmpTypeID, I1TypeID});
|
||||||
}
|
}
|
||||||
|
|
||||||
InstructionList.push_back(I);
|
InstructionList.push_back(I);
|
||||||
|
@ -5475,7 +5587,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
FailureOrdering, SSID);
|
FailureOrdering, SSID);
|
||||||
cast<AtomicCmpXchgInst>(I)->setVolatile(IsVol);
|
cast<AtomicCmpXchgInst>(I)->setVolatile(IsVol);
|
||||||
cast<AtomicCmpXchgInst>(I)->setWeak(IsWeak);
|
cast<AtomicCmpXchgInst>(I)->setWeak(IsWeak);
|
||||||
ResTypeID = TODOTypeID;
|
|
||||||
|
unsigned I1TypeID = getVirtualTypeID(Type::getInt1Ty(Context));
|
||||||
|
ResTypeID = getVirtualTypeID(I->getType(), {CmpTypeID, I1TypeID});
|
||||||
|
|
||||||
InstructionList.push_back(I);
|
InstructionList.push_back(I);
|
||||||
break;
|
break;
|
||||||
|
@ -5496,13 +5610,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
|
|
||||||
Value *Val = nullptr;
|
Value *Val = nullptr;
|
||||||
|
unsigned ValTypeID = InvalidTypeID;
|
||||||
if (BitCode == bitc::FUNC_CODE_INST_ATOMICRMW_OLD) {
|
if (BitCode == bitc::FUNC_CODE_INST_ATOMICRMW_OLD) {
|
||||||
|
ValTypeID = getContainedTypeID(PtrTypeID);
|
||||||
if (popValue(Record, OpNum, NextValueNo,
|
if (popValue(Record, OpNum, NextValueNo,
|
||||||
cast<PointerType>(Ptr->getType())->getPointerElementType(),
|
getTypeByID(ValTypeID), ValTypeID, Val))
|
||||||
getContainedTypeID(PtrTypeID), Val))
|
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
} else {
|
} else {
|
||||||
unsigned ValTypeID;
|
|
||||||
if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID))
|
if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID))
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
}
|
}
|
||||||
|
@ -5537,7 +5651,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
Align(TheModule->getDataLayout().getTypeStoreSize(Val->getType()));
|
Align(TheModule->getDataLayout().getTypeStoreSize(Val->getType()));
|
||||||
|
|
||||||
I = new AtomicRMWInst(Operation, Ptr, Val, *Alignment, Ordering, SSID);
|
I = new AtomicRMWInst(Operation, Ptr, Val, *Alignment, Ordering, SSID);
|
||||||
ResTypeID = TODOTypeID;
|
ResTypeID = ValTypeID;
|
||||||
cast<AtomicRMWInst>(I)->setVolatile(IsVol);
|
cast<AtomicRMWInst>(I)->setVolatile(IsVol);
|
||||||
|
|
||||||
InstructionList.push_back(I);
|
InstructionList.push_back(I);
|
||||||
|
@ -5572,9 +5686,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
return error("Fast math flags indicator set for call with no FMF");
|
return error("Fast math flags indicator set for call with no FMF");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned FTyID = InvalidTypeID;
|
||||||
FunctionType *FTy = nullptr;
|
FunctionType *FTy = nullptr;
|
||||||
if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) {
|
if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) {
|
||||||
FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]));
|
FTyID = Record[OpNum++];
|
||||||
|
FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID));
|
||||||
if (!FTy)
|
if (!FTy)
|
||||||
return error("Explicit call type is not a function type");
|
return error("Explicit call type is not a function type");
|
||||||
}
|
}
|
||||||
|
@ -5588,8 +5704,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
if (!OpTy)
|
if (!OpTy)
|
||||||
return error("Callee is not a pointer type");
|
return error("Callee is not a pointer type");
|
||||||
if (!FTy) {
|
if (!FTy) {
|
||||||
FTy =
|
FTyID = getContainedTypeID(CalleeTypeID);
|
||||||
dyn_cast<FunctionType>(Callee->getType()->getPointerElementType());
|
FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID));
|
||||||
if (!FTy)
|
if (!FTy)
|
||||||
return error("Callee is not of pointer to function type");
|
return error("Callee is not of pointer to function type");
|
||||||
} else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy))
|
} else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy))
|
||||||
|
@ -5599,15 +5715,16 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
return error("Insufficient operands to call");
|
return error("Insufficient operands to call");
|
||||||
|
|
||||||
SmallVector<Value*, 16> Args;
|
SmallVector<Value*, 16> Args;
|
||||||
SmallVector<Type *, 16> ArgsTys;
|
SmallVector<unsigned, 16> ArgTyIDs;
|
||||||
// Read the fixed params.
|
// Read the fixed params.
|
||||||
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
|
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
|
||||||
|
unsigned ArgTyID = getContainedTypeID(FTyID, i + 1);
|
||||||
if (FTy->getParamType(i)->isLabelTy())
|
if (FTy->getParamType(i)->isLabelTy())
|
||||||
Args.push_back(getBasicBlock(Record[OpNum]));
|
Args.push_back(getBasicBlock(Record[OpNum]));
|
||||||
else
|
else
|
||||||
Args.push_back(getValue(Record, OpNum, NextValueNo,
|
Args.push_back(getValue(Record, OpNum, NextValueNo,
|
||||||
FTy->getParamType(i), TODOTypeID));
|
FTy->getParamType(i), ArgTyID));
|
||||||
ArgsTys.push_back(FTy->getParamType(i));
|
ArgTyIDs.push_back(ArgTyID);
|
||||||
if (!Args.back())
|
if (!Args.back())
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
}
|
}
|
||||||
|
@ -5623,12 +5740,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
Args.push_back(Op);
|
Args.push_back(Op);
|
||||||
ArgsTys.push_back(Op->getType());
|
ArgTyIDs.push_back(OpTypeID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
I = CallInst::Create(FTy, Callee, Args, OperandBundles);
|
I = CallInst::Create(FTy, Callee, Args, OperandBundles);
|
||||||
ResTypeID = TODOTypeID;
|
ResTypeID = getContainedTypeID(FTyID);
|
||||||
OperandBundles.clear();
|
OperandBundles.clear();
|
||||||
InstructionList.push_back(I);
|
InstructionList.push_back(I);
|
||||||
cast<CallInst>(I)->setCallingConv(
|
cast<CallInst>(I)->setCallingConv(
|
||||||
|
@ -5642,7 +5759,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
TCK = CallInst::TCK_NoTail;
|
TCK = CallInst::TCK_NoTail;
|
||||||
cast<CallInst>(I)->setTailCallKind(TCK);
|
cast<CallInst>(I)->setTailCallKind(TCK);
|
||||||
cast<CallInst>(I)->setAttributes(PAL);
|
cast<CallInst>(I)->setAttributes(PAL);
|
||||||
propagateAttributeTypes(cast<CallBase>(I), ArgsTys);
|
propagateAttributeTypes(cast<CallBase>(I), ArgTyIDs);
|
||||||
if (FMF.any()) {
|
if (FMF.any()) {
|
||||||
if (!isa<FPMathOperator>(I))
|
if (!isa<FPMathOperator>(I))
|
||||||
return error("Fast-math-flags specified for call without "
|
return error("Fast-math-flags specified for call without "
|
||||||
|
@ -5725,7 +5842,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
||||||
|
|
||||||
// Non-void values get registered in the value table for future use.
|
// Non-void values get registered in the value table for future use.
|
||||||
if (!I->getType()->isVoidTy()) {
|
if (!I->getType()->isVoidTy()) {
|
||||||
assert(ResTypeID != InvalidTypeID && "Should have ID for non-void type");
|
assert(I->getType() == getTypeByID(ResTypeID) &&
|
||||||
|
"Incorrect result type ID");
|
||||||
ValueList.assignValue(NextValueNo++, I, ResTypeID);
|
ValueList.assignValue(NextValueNo++, I, ResTypeID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
; RUN: llvm-dis < %s.bc| FileCheck %s
|
; RUN: llvm-dis -opaque-pointers=0 < %s.bc| FileCheck %s
|
||||||
|
; RUN: llvm-dis -opaque-pointers=1 < %s.bc| FileCheck %s
|
||||||
; RUN: verify-uselistorder < %s.bc
|
; RUN: verify-uselistorder < %s.bc
|
||||||
|
|
||||||
; case-ranges.ll.bc was generated by passing this file to llvm-as from the 3.3
|
; case-ranges.ll.bc was generated by passing this file to llvm-as from the 3.3
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
; RUN: llvm-dis < %s.bc | FileCheck %s
|
; RUN: llvm-dis -opaque-pointers=0 < %s.bc | FileCheck %s
|
||||||
|
; RUN: llvm-dis -opaque-pointers=1 < %s.bc | FileCheck %s
|
||||||
|
|
||||||
; Check that function-local metadata is dropped correctly when it's not a
|
; Check that function-local metadata is dropped correctly when it's not a
|
||||||
; direct argument to a call instruction.
|
; direct argument to a call instruction.
|
||||||
|
|
Loading…
Reference in New Issue