[OpaquePtr] Remove existing support for forward compatibility

It assumes that PointerType will keep having an optional pointee type,
but we'd like to remove the pointee type in PointerType at some point.

I feel like the current implementation could be simplified anyway,
although perhaps I'm underestimating the amount of work needed
throughout BitcodeReader.

We will still need a side table to keep track of pointee types. This
will be reimplemented at some point.

This is essentially a revert of a4771e9d (which doesn't look like it was
reviewed anyway).

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D103135
This commit is contained in:
Arthur Eubanks
2021-05-25 20:04:00 -07:00
parent cc17bfe489
commit 8c5a44901c
3 changed files with 135 additions and 252 deletions

View File

@@ -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;
}
Type *getTypeByID(unsigned ID);
/// 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));
}
/// 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;
}
@@ -717,7 +684,7 @@ private:
/// Upgrades old-style typeless byval or sret attributes by adding the
/// corresponding argument's pointee type.
void propagateByValSRetTypes(CallBase *CB, ArrayRef<Type *> ArgsFullTys);
void propagateByValSRetTypes(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
@@ -1194,7 +1161,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;
@@ -2369,13 +2336,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;
@@ -2416,7 +2381,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())
@@ -2451,8 +2416,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())
@@ -2689,7 +2653,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");
@@ -2700,7 +2664,7 @@ Error BitcodeReader::parseConstants() {
return error("Invalid gep with no operands");
Type *ImplicitPointeeType =
getPointerElementFlatType(Elt0FullTy->getScalarType());
cast<PointerType>(Elt0FullTy->getScalarType())->getElementType();
if (!PointeeType)
PointeeType = ImplicitPointeeType;
else if (PointeeType != ImplicitPointeeType)
@@ -2784,7 +2748,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;
}
@@ -2795,7 +2759,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;
}
@@ -2835,8 +2799,8 @@ 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.,
@@ -2861,8 +2825,8 @@ 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;
}
@@ -2888,8 +2852,8 @@ 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), CanThrow);
break;
}
@@ -2950,9 +2914,7 @@ Error BitcodeReader::parseConstants() {
}
}
assert(V->getType() == flattenPointerTypes(CurFullTy) &&
"Incorrect fully structured type provided for Constant");
ValueList.assignValue(V, NextCstNo, CurFullTy);
ValueList.assignValue(V, NextCstNo);
++NextCstNo;
}
}
@@ -3230,8 +3192,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;
@@ -3243,7 +3204,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];
@@ -3289,10 +3250,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])
@@ -3335,12 +3293,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");
@@ -3356,9 +3313,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];
@@ -3377,8 +3334,8 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
Func->removeParamAttr(i, Kind);
Type *PTy = cast<FunctionType>(FullFTy)->getParamType(i);
Type *PtrEltTy = getPointerElementFlatType(PTy);
Type *PTy = cast<FunctionType>(FTy)->getParamType(i);
Type *PtrEltTy = cast<PointerType>(PTy)->getElementType();
Attribute NewAttr;
switch (Kind) {
case Attribute::ByVal:
@@ -3455,10 +3412,7 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
if (Record.size() > 18)
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.
@@ -3487,8 +3441,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");
@@ -3497,7 +3450,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++];
@@ -3514,8 +3467,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()) {
@@ -3545,10 +3496,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();
}
@@ -3856,7 +3804,7 @@ Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) {
}
void BitcodeReader::propagateByValSRetTypes(CallBase *CB,
ArrayRef<Type *> ArgsFullTys) {
ArrayRef<Type *> ArgsTys) {
for (unsigned i = 0; i != CB->arg_size(); ++i) {
for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet,
Attribute::InAlloca}) {
@@ -3865,7 +3813,7 @@ void BitcodeReader::propagateByValSRetTypes(CallBase *CB,
CB->removeParamAttr(i, Kind);
Type *PtrEltTy = getPointerElementFlatType(ArgsFullTys[i]);
Type *PtrEltTy = cast<PointerType>(ArgsTys[i])->getElementType();
Attribute NewAttr;
switch (Kind) {
case Attribute::ByVal:
@@ -3901,11 +3849,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
// Add all the function arguments to the value table.
unsigned ArgNo = 0;
FunctionType *FullFTy = FunctionTypes[F];
FunctionType *FTy = FunctionTypes[F];
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;
@@ -3978,7 +3926,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();
@@ -4124,8 +4071,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");
@@ -4155,25 +4101,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 (!cast<PointerType>(FullBaseTy->getScalarType())
->isOpaqueOrPointeeTypeMatches(Ty))
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()) {
@@ -4184,7 +4129,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
}
I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx);
FullTy = GetElementPtrInst::getGEPReturnType(FullTy, I, GEPIdx);
InstructionList.push_back(I);
if (InBounds)
@@ -4196,8 +4140,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)
@@ -4205,24 +4150,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);
@@ -4234,7 +4179,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))
@@ -4280,7 +4225,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");
@@ -4295,7 +4240,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");
@@ -4325,13 +4270,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;
}
@@ -4339,7 +4283,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");
@@ -4355,7 +4299,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");
@@ -4365,9 +4309,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;
}
@@ -4675,40 +4616,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 (cast<PointerType>(Callee->getType())->getElementType() != 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");
}
@@ -4720,23 +4657,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);
propagateByValSRetTypes(cast<CallBase>(I), ArgsTys);
break;
}
@@ -4762,29 +4697,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)
@@ -4817,7 +4748,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(
@@ -4833,8 +4763,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");
@@ -4886,8 +4815,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) {
@@ -4936,13 +4864,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);
@@ -4968,14 +4895,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");
@@ -4984,10 +4910,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;
@@ -5008,7 +4934,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");
@@ -5017,10 +4943,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;
@@ -5047,12 +4973,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");
@@ -5075,13 +5001,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");
@@ -5111,7 +5037,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()))
@@ -5119,11 +5045,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)
@@ -5155,7 +5080,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
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
@@ -5163,7 +5087,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]);
}
@@ -5177,14 +5100,14 @@ 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()))
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;
@@ -5225,7 +5148,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
I = new AtomicCmpXchgInst(Ptr, Cmp, Val, *Alignment, SuccessOrdering,
FailureOrdering, SSID);
FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)});
cast<AtomicCmpXchgInst>(I)->setVolatile(IsVol);
cast<AtomicCmpXchgInst>(I)->setWeak(IsWeak);
@@ -5240,7 +5162,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
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()))
@@ -5249,13 +5171,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Value *Val = nullptr;
if (BitCode == bitc::FUNC_CODE_INST_ATOMICRMW_OLD) {
if (popValue(Record, OpNum, NextValueNo,
getPointerElementFlatType(FullTy), Val))
cast<PointerType>(Ptr->getType())->getPointerElementType(),
Val))
return error("Invalid record");
FullTy = getPointerElementFlatType(FullTy);
} else {
if (getValueTypePair(Record, OpNum, NextValueNo, Val))
return error("Invalid record");
FullTy = Val->getType();
}
if (!(NumRecords == (OpNum + 4) || NumRecords == (OpNum + 5)))
@@ -5323,36 +5244,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 (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)
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())
@@ -5360,7 +5277,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");
}
@@ -5372,16 +5289,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(
@@ -5395,7 +5310,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);
propagateByValSRetTypes(cast<CallBase>(I), ArgsTys);
if (FMF.any()) {
if (!isa<FPMathOperator>(I))
return error("Fast-math-flags specified for call without "
@@ -5409,8 +5324,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);
@@ -5443,7 +5357,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");
@@ -5473,23 +5387,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: