|
|
|
|
@@ -494,6 +494,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
|
|
|
|
|
std::vector<std::string> GCTable;
|
|
|
|
|
|
|
|
|
|
std::vector<Type*> TypeList;
|
|
|
|
|
DenseMap<Function *, FunctionType *> FunctionTypes;
|
|
|
|
|
BitcodeReaderValueList ValueList;
|
|
|
|
|
Optional<MetadataLoader> MDLoader;
|
|
|
|
|
std::vector<Comdat *> ComdatList;
|
|
|
|
|
@@ -592,12 +593,42 @@ private:
|
|
|
|
|
StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name);
|
|
|
|
|
StructType *createIdentifiedStructType(LLVMContext &Context);
|
|
|
|
|
|
|
|
|
|
Type *getTypeByID(unsigned ID);
|
|
|
|
|
/// 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Value *getFnValueByID(unsigned ID, Type *Ty) {
|
|
|
|
|
/// Given a fully structured pointer type (i.e. not opaque), return
|
|
|
|
|
/// the flattened form of its element, suitable for use in a Value.
|
|
|
|
|
Type *getPointerElementFlatType(Type *Ty) {
|
|
|
|
|
return flattenPointerTypes(cast<PointerType>(Ty)->getElementType());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Given a fully structured pointer type, get its element type in
|
|
|
|
|
/// both fully structured form, and flattened form suitable for use
|
|
|
|
|
/// in a Value.
|
|
|
|
|
std::pair<Type *, Type *> getPointerElementTypes(Type *FullTy) {
|
|
|
|
|
Type *ElTy = cast<PointerType>(FullTy)->getElementType();
|
|
|
|
|
return std::make_pair(ElTy, flattenPointerTypes(ElTy));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Return the flattened type (suitable for use in a Value)
|
|
|
|
|
/// specified by the given \param ID.
|
|
|
|
|
Type *getTypeByID(unsigned ID) {
|
|
|
|
|
return flattenPointerTypes(getFullyStructuredTypeByID(ID));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 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) {
|
|
|
|
|
if (Ty && Ty->isMetadataTy())
|
|
|
|
|
return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID));
|
|
|
|
|
return ValueList.getValueFwdRef(ID, Ty);
|
|
|
|
|
return ValueList.getValueFwdRef(ID, Ty, FullTy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Metadata *getFnMetadataByID(unsigned ID) {
|
|
|
|
|
@@ -619,7 +650,8 @@ private:
|
|
|
|
|
/// Increment Slot past the number of slots used in the record. Return true on
|
|
|
|
|
/// failure.
|
|
|
|
|
bool getValueTypePair(SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
|
|
|
|
|
unsigned InstNum, Value *&ResVal) {
|
|
|
|
|
unsigned InstNum, Value *&ResVal,
|
|
|
|
|
Type **FullTy = nullptr) {
|
|
|
|
|
if (Slot == Record.size()) return true;
|
|
|
|
|
unsigned ValNo = (unsigned)Record[Slot++];
|
|
|
|
|
// Adjust the ValNo, if it was encoded relative to the InstNum.
|
|
|
|
|
@@ -628,7 +660,7 @@ private:
|
|
|
|
|
if (ValNo < InstNum) {
|
|
|
|
|
// If this is not a forward reference, just return the value we already
|
|
|
|
|
// have.
|
|
|
|
|
ResVal = getFnValueByID(ValNo, nullptr);
|
|
|
|
|
ResVal = getFnValueByID(ValNo, nullptr, FullTy);
|
|
|
|
|
return ResVal == nullptr;
|
|
|
|
|
}
|
|
|
|
|
if (Slot == Record.size())
|
|
|
|
|
@@ -636,6 +668,8 @@ private:
|
|
|
|
|
|
|
|
|
|
unsigned TypeNo = (unsigned)Record[Slot++];
|
|
|
|
|
ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo));
|
|
|
|
|
if (FullTy)
|
|
|
|
|
*FullTy = getFullyStructuredTypeByID(TypeNo);
|
|
|
|
|
return ResVal == nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -683,7 +717,7 @@ private:
|
|
|
|
|
|
|
|
|
|
/// Upgrades old-style typeless byval attributes by adding the corresponding
|
|
|
|
|
/// argument's pointee type.
|
|
|
|
|
void propagateByValTypes(CallBase *CB);
|
|
|
|
|
void propagateByValTypes(CallBase *CB, ArrayRef<Type *> ArgsFullTys);
|
|
|
|
|
|
|
|
|
|
/// Converts alignment exponent (i.e. power of two (or zero)) to the
|
|
|
|
|
/// corresponding alignment to use. If alignment is too large, returns
|
|
|
|
|
@@ -1144,7 +1178,7 @@ static void upgradeDLLImportExportLinkage(GlobalValue *GV, unsigned Val) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Type *BitcodeReader::getTypeByID(unsigned ID) {
|
|
|
|
|
Type *BitcodeReader::getFullyStructuredTypeByID(unsigned ID) {
|
|
|
|
|
// The type table size is always specified correctly.
|
|
|
|
|
if (ID >= TypeList.size())
|
|
|
|
|
return nullptr;
|
|
|
|
|
@@ -2268,6 +2302,7 @@ 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();
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
@@ -2312,7 +2347,8 @@ Error BitcodeReader::parseConstants() {
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
if (TypeList[Record[0]] == VoidType)
|
|
|
|
|
return error("Invalid constant type");
|
|
|
|
|
CurTy = TypeList[Record[0]];
|
|
|
|
|
CurFullTy = TypeList[Record[0]];
|
|
|
|
|
CurTy = flattenPointerTypes(CurFullTy);
|
|
|
|
|
continue; // Skip the ValueList manipulation.
|
|
|
|
|
case bitc::CST_CODE_NULL: // NULL
|
|
|
|
|
V = Constant::getNullValue(CurTy);
|
|
|
|
|
@@ -2531,7 +2567,10 @@ Error BitcodeReader::parseConstants() {
|
|
|
|
|
InBounds = true;
|
|
|
|
|
|
|
|
|
|
SmallVector<Constant*, 16> Elts;
|
|
|
|
|
Type *Elt0FullTy = nullptr;
|
|
|
|
|
while (OpNum != Record.size()) {
|
|
|
|
|
if (!Elt0FullTy)
|
|
|
|
|
Elt0FullTy = getFullyStructuredTypeByID(Record[OpNum]);
|
|
|
|
|
Type *ElTy = getTypeByID(Record[OpNum++]);
|
|
|
|
|
if (!ElTy)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
@@ -2542,8 +2581,7 @@ Error BitcodeReader::parseConstants() {
|
|
|
|
|
return error("Invalid gep with no operands");
|
|
|
|
|
|
|
|
|
|
Type *ImplicitPointeeType =
|
|
|
|
|
cast<PointerType>(Elts[0]->getType()->getScalarType())
|
|
|
|
|
->getElementType();
|
|
|
|
|
getPointerElementFlatType(Elt0FullTy->getScalarType());
|
|
|
|
|
if (!PointeeType)
|
|
|
|
|
PointeeType = ImplicitPointeeType;
|
|
|
|
|
else if (PointeeType != ImplicitPointeeType)
|
|
|
|
|
@@ -2677,10 +2715,10 @@ Error BitcodeReader::parseConstants() {
|
|
|
|
|
AsmStr += (char)Record[2+i];
|
|
|
|
|
for (unsigned i = 0; i != ConstStrSize; ++i)
|
|
|
|
|
ConstrStr += (char)Record[3+AsmStrSize+i];
|
|
|
|
|
PointerType *PTy = cast<PointerType>(CurTy);
|
|
|
|
|
UpgradeInlineAsmString(&AsmStr);
|
|
|
|
|
V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()),
|
|
|
|
|
AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
|
|
|
|
|
V = InlineAsm::get(
|
|
|
|
|
cast<FunctionType>(getPointerElementFlatType(CurFullTy)), AsmStr,
|
|
|
|
|
ConstrStr, HasSideEffects, IsAlignStack);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// This version adds support for the asm dialect keywords (e.g.,
|
|
|
|
|
@@ -2703,11 +2741,11 @@ Error BitcodeReader::parseConstants() {
|
|
|
|
|
AsmStr += (char)Record[2+i];
|
|
|
|
|
for (unsigned i = 0; i != ConstStrSize; ++i)
|
|
|
|
|
ConstrStr += (char)Record[3+AsmStrSize+i];
|
|
|
|
|
PointerType *PTy = cast<PointerType>(CurTy);
|
|
|
|
|
UpgradeInlineAsmString(&AsmStr);
|
|
|
|
|
V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()),
|
|
|
|
|
AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
|
|
|
|
|
InlineAsm::AsmDialect(AsmDialect));
|
|
|
|
|
V = InlineAsm::get(
|
|
|
|
|
cast<FunctionType>(getPointerElementFlatType(CurFullTy)), AsmStr,
|
|
|
|
|
ConstrStr, HasSideEffects, IsAlignStack,
|
|
|
|
|
InlineAsm::AsmDialect(AsmDialect));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case bitc::CST_CODE_BLOCKADDRESS:{
|
|
|
|
|
@@ -2753,7 +2791,9 @@ Error BitcodeReader::parseConstants() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ValueList.assignValue(V, NextCstNo);
|
|
|
|
|
assert(V->getType() == flattenPointerTypes(CurFullTy) &&
|
|
|
|
|
"Incorrect fully structured type provided for Constant");
|
|
|
|
|
ValueList.assignValue(V, NextCstNo, CurFullTy);
|
|
|
|
|
++NextCstNo;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -3026,7 +3066,8 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
|
|
|
|
|
|
|
|
|
|
if (Record.size() < 6)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
Type *Ty = getTypeByID(Record[0]);
|
|
|
|
|
Type *FullTy = getFullyStructuredTypeByID(Record[0]);
|
|
|
|
|
Type *Ty = flattenPointerTypes(FullTy);
|
|
|
|
|
if (!Ty)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
bool isConstant = Record[1] & 1;
|
|
|
|
|
@@ -3038,7 +3079,7 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
|
|
|
|
|
if (!Ty->isPointerTy())
|
|
|
|
|
return error("Invalid type for value");
|
|
|
|
|
AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
|
|
|
|
|
Ty = cast<PointerType>(Ty)->getElementType();
|
|
|
|
|
std::tie(FullTy, Ty) = getPointerElementTypes(FullTy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t RawLinkage = Record[3];
|
|
|
|
|
@@ -3084,7 +3125,10 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
|
|
|
|
|
else
|
|
|
|
|
upgradeDLLImportExportLinkage(NewGV, RawLinkage);
|
|
|
|
|
|
|
|
|
|
ValueList.push_back(NewGV);
|
|
|
|
|
FullTy = PointerType::get(FullTy, AddressSpace);
|
|
|
|
|
assert(NewGV->getType() == flattenPointerTypes(FullTy) &&
|
|
|
|
|
"Incorrect fully specified type for GlobalVariable");
|
|
|
|
|
ValueList.push_back(NewGV, FullTy);
|
|
|
|
|
|
|
|
|
|
// Remember which value to use for the global initializer.
|
|
|
|
|
if (unsigned InitID = Record[2])
|
|
|
|
|
@@ -3127,13 +3171,14 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
|
|
|
|
|
|
|
|
|
|
if (Record.size() < 8)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
Type *Ty = getTypeByID(Record[0]);
|
|
|
|
|
if (!Ty)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
if (auto *PTy = dyn_cast<PointerType>(Ty))
|
|
|
|
|
Ty = PTy->getElementType();
|
|
|
|
|
auto *FTy = dyn_cast<FunctionType>(Ty);
|
|
|
|
|
Type *FullFTy = getFullyStructuredTypeByID(Record[0]);
|
|
|
|
|
Type *FTy = flattenPointerTypes(FullFTy);
|
|
|
|
|
if (!FTy)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
if (isa<PointerType>(FTy))
|
|
|
|
|
std::tie(FullFTy, FTy) = getPointerElementTypes(FullFTy);
|
|
|
|
|
|
|
|
|
|
if (!isa<FunctionType>(FTy))
|
|
|
|
|
return error("Invalid type for value");
|
|
|
|
|
auto CC = static_cast<CallingConv::ID>(Record[1]);
|
|
|
|
|
if (CC & ~CallingConv::MaxID)
|
|
|
|
|
@@ -3143,8 +3188,13 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
|
|
|
|
|
if (Record.size() > 16)
|
|
|
|
|
AddrSpace = Record[16];
|
|
|
|
|
|
|
|
|
|
Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage,
|
|
|
|
|
AddrSpace, Name, TheModule);
|
|
|
|
|
Function *Func =
|
|
|
|
|
Function::Create(cast<FunctionType>(FTy), GlobalValue::ExternalLinkage,
|
|
|
|
|
AddrSpace, Name, TheModule);
|
|
|
|
|
|
|
|
|
|
assert(Func->getFunctionType() == flattenPointerTypes(FullFTy) &&
|
|
|
|
|
"Incorrect fully specified type provided for function");
|
|
|
|
|
FunctionTypes[Func] = cast<FunctionType>(FullFTy);
|
|
|
|
|
|
|
|
|
|
Func->setCallingConv(CC);
|
|
|
|
|
bool isProto = Record[2];
|
|
|
|
|
@@ -3155,13 +3205,14 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
|
|
|
|
|
// Upgrade any old-style byval without a type by propagating the argument's
|
|
|
|
|
// pointee type. There should be no opaque pointers where the byval type is
|
|
|
|
|
// implicit.
|
|
|
|
|
for (auto &Arg : Func->args()) {
|
|
|
|
|
if (Arg.hasByValAttr() &&
|
|
|
|
|
!Arg.getAttribute(Attribute::ByVal).getValueAsType()) {
|
|
|
|
|
Arg.removeAttr(Attribute::ByVal);
|
|
|
|
|
Arg.addAttr(Attribute::getWithByValType(
|
|
|
|
|
Context, Arg.getType()->getPointerElementType()));
|
|
|
|
|
}
|
|
|
|
|
for (unsigned i = 0; i != Func->arg_size(); ++i) {
|
|
|
|
|
if (!Func->hasParamAttribute(i, Attribute::ByVal))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
Type *PTy = cast<FunctionType>(FullFTy)->getParamType(i);
|
|
|
|
|
Func->removeParamAttr(i, Attribute::ByVal);
|
|
|
|
|
Func->addParamAttr(i, Attribute::getWithByValType(
|
|
|
|
|
Context, getPointerElementFlatType(PTy)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned Alignment;
|
|
|
|
|
@@ -3221,7 +3272,10 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
|
|
|
|
|
if (Record.size() > 18)
|
|
|
|
|
Func->setPartition(StringRef(Strtab.data() + Record[17], Record[18]));
|
|
|
|
|
|
|
|
|
|
ValueList.push_back(Func);
|
|
|
|
|
Type *FullTy = PointerType::get(FullFTy, AddrSpace);
|
|
|
|
|
assert(Func->getType() == flattenPointerTypes(FullTy) &&
|
|
|
|
|
"Incorrect fully specified type provided for Function");
|
|
|
|
|
ValueList.push_back(Func, FullTy);
|
|
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
|
@@ -3250,7 +3304,8 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
|
|
|
|
|
if (Record.size() < (3 + (unsigned)NewRecord))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
unsigned OpNum = 0;
|
|
|
|
|
Type *Ty = getTypeByID(Record[OpNum++]);
|
|
|
|
|
Type *FullTy = getFullyStructuredTypeByID(Record[OpNum++]);
|
|
|
|
|
Type *Ty = flattenPointerTypes(FullTy);
|
|
|
|
|
if (!Ty)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
@@ -3259,7 +3314,7 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
|
|
|
|
|
auto *PTy = dyn_cast<PointerType>(Ty);
|
|
|
|
|
if (!PTy)
|
|
|
|
|
return error("Invalid type for value");
|
|
|
|
|
Ty = PTy->getElementType();
|
|
|
|
|
std::tie(FullTy, Ty) = getPointerElementTypes(FullTy);
|
|
|
|
|
AddrSpace = PTy->getAddressSpace();
|
|
|
|
|
} else {
|
|
|
|
|
AddrSpace = Record[OpNum++];
|
|
|
|
|
@@ -3275,6 +3330,9 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
|
|
|
|
|
else
|
|
|
|
|
NewGA = GlobalIFunc::create(Ty, AddrSpace, getDecodedLinkage(Linkage), Name,
|
|
|
|
|
nullptr, TheModule);
|
|
|
|
|
|
|
|
|
|
assert(NewGA->getValueType() == flattenPointerTypes(FullTy) &&
|
|
|
|
|
"Incorrect fully structured type provided for GlobalIndirectSymbol");
|
|
|
|
|
// Old bitcode files didn't have visibility field.
|
|
|
|
|
// Local linkage must have default visibility.
|
|
|
|
|
if (OpNum != Record.size()) {
|
|
|
|
|
@@ -3305,7 +3363,10 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
|
|
|
|
|
OpNum += 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ValueList.push_back(NewGA);
|
|
|
|
|
FullTy = PointerType::get(FullTy, AddrSpace);
|
|
|
|
|
assert(NewGA->getType() == flattenPointerTypes(FullTy) &&
|
|
|
|
|
"Incorrect fully structured type provided for GlobalIndirectSymbol");
|
|
|
|
|
ValueList.push_back(NewGA, FullTy);
|
|
|
|
|
IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
|
|
|
|
|
return Error::success();
|
|
|
|
|
}
|
|
|
|
|
@@ -3583,16 +3644,16 @@ Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) {
|
|
|
|
|
return Error::success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BitcodeReader::propagateByValTypes(CallBase *CB) {
|
|
|
|
|
for (unsigned i = 0; i < CB->getNumArgOperands(); ++i) {
|
|
|
|
|
if (CB->paramHasAttr(i, Attribute::ByVal) &&
|
|
|
|
|
!CB->getAttribute(i, Attribute::ByVal).getValueAsType()) {
|
|
|
|
|
CB->removeParamAttr(i, Attribute::ByVal);
|
|
|
|
|
CB->addParamAttr(
|
|
|
|
|
i, Attribute::getWithByValType(
|
|
|
|
|
Context,
|
|
|
|
|
CB->getArgOperand(i)->getType()->getPointerElementType()));
|
|
|
|
|
}
|
|
|
|
|
void BitcodeReader::propagateByValTypes(CallBase *CB,
|
|
|
|
|
ArrayRef<Type *> ArgsFullTys) {
|
|
|
|
|
for (unsigned i = 0; i != CB->arg_size(); ++i) {
|
|
|
|
|
if (!CB->paramHasAttr(i, Attribute::ByVal))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
CB->removeParamAttr(i, Attribute::ByVal);
|
|
|
|
|
CB->addParamAttr(
|
|
|
|
|
i, Attribute::getWithByValType(
|
|
|
|
|
Context, getPointerElementFlatType(ArgsFullTys[i])));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -3610,9 +3671,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
unsigned ModuleMDLoaderSize = MDLoader->size();
|
|
|
|
|
|
|
|
|
|
// Add all the function arguments to the value table.
|
|
|
|
|
for (Argument &I : F->args())
|
|
|
|
|
ValueList.push_back(&I);
|
|
|
|
|
|
|
|
|
|
unsigned ArgNo = 0;
|
|
|
|
|
FunctionType *FullFTy = FunctionTypes[F];
|
|
|
|
|
for (Argument &I : F->args()) {
|
|
|
|
|
assert(I.getType() == flattenPointerTypes(FullFTy->getParamType(ArgNo)) &&
|
|
|
|
|
"Incorrect fully specified type for Function Argument");
|
|
|
|
|
ValueList.push_back(&I, FullFTy->getParamType(ArgNo++));
|
|
|
|
|
}
|
|
|
|
|
unsigned NextValueNo = ValueList.size();
|
|
|
|
|
BasicBlock *CurBB = nullptr;
|
|
|
|
|
unsigned CurBBNo = 0;
|
|
|
|
|
@@ -3684,6 +3749,7 @@ 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();
|
|
|
|
|
@@ -3828,7 +3894,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
OpNum+2 != Record.size())
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
Type *ResTy = getTypeByID(Record[OpNum]);
|
|
|
|
|
FullTy = getFullyStructuredTypeByID(Record[OpNum]);
|
|
|
|
|
Type *ResTy = flattenPointerTypes(FullTy);
|
|
|
|
|
int Opc = getDecodedCastOpcode(Record[OpNum + 1]);
|
|
|
|
|
if (Opc == -1 || !ResTy)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
@@ -3857,22 +3924,22 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
|
|
|
|
|
if (BitCode == bitc::FUNC_CODE_INST_GEP) {
|
|
|
|
|
InBounds = Record[OpNum++];
|
|
|
|
|
Ty = getTypeByID(Record[OpNum++]);
|
|
|
|
|
FullTy = getFullyStructuredTypeByID(Record[OpNum++]);
|
|
|
|
|
Ty = flattenPointerTypes(FullTy);
|
|
|
|
|
} else {
|
|
|
|
|
InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
|
|
|
|
|
Ty = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Value *BasePtr;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr))
|
|
|
|
|
Type *FullBaseTy = nullptr;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr, &FullBaseTy))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
if (!Ty)
|
|
|
|
|
Ty = cast<PointerType>(BasePtr->getType()->getScalarType())
|
|
|
|
|
->getElementType();
|
|
|
|
|
else if (Ty !=
|
|
|
|
|
cast<PointerType>(BasePtr->getType()->getScalarType())
|
|
|
|
|
->getElementType())
|
|
|
|
|
if (!Ty) {
|
|
|
|
|
std::tie(FullTy, Ty) =
|
|
|
|
|
getPointerElementTypes(FullBaseTy->getScalarType());
|
|
|
|
|
} else if (Ty != getPointerElementFlatType(FullBaseTy->getScalarType()))
|
|
|
|
|
return error(
|
|
|
|
|
"Explicit gep type does not match pointee type of pointer operand");
|
|
|
|
|
|
|
|
|
|
@@ -3885,6 +3952,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx);
|
|
|
|
|
FullTy = GetElementPtrInst::getGEPReturnType(FullTy, I, GEPIdx);
|
|
|
|
|
|
|
|
|
|
InstructionList.push_back(I);
|
|
|
|
|
if (InBounds)
|
|
|
|
|
@@ -3896,7 +3964,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
// EXTRACTVAL: [opty, opval, n x indices]
|
|
|
|
|
unsigned OpNum = 0;
|
|
|
|
|
Value *Agg;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Agg, &FullTy))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
unsigned RecSize = Record.size();
|
|
|
|
|
@@ -3904,26 +3972,25 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
return error("EXTRACTVAL: Invalid instruction with 0 indices");
|
|
|
|
|
|
|
|
|
|
SmallVector<unsigned, 4> EXTRACTVALIdx;
|
|
|
|
|
Type *CurTy = Agg->getType();
|
|
|
|
|
for (; OpNum != RecSize; ++OpNum) {
|
|
|
|
|
bool IsArray = CurTy->isArrayTy();
|
|
|
|
|
bool IsStruct = CurTy->isStructTy();
|
|
|
|
|
bool IsArray = FullTy->isArrayTy();
|
|
|
|
|
bool IsStruct = FullTy->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 >= CurTy->getStructNumElements())
|
|
|
|
|
if (IsStruct && Index >= FullTy->getStructNumElements())
|
|
|
|
|
return error("EXTRACTVAL: Invalid struct index");
|
|
|
|
|
if (IsArray && Index >= CurTy->getArrayNumElements())
|
|
|
|
|
if (IsArray && Index >= FullTy->getArrayNumElements())
|
|
|
|
|
return error("EXTRACTVAL: Invalid array index");
|
|
|
|
|
EXTRACTVALIdx.push_back((unsigned)Index);
|
|
|
|
|
|
|
|
|
|
if (IsStruct)
|
|
|
|
|
CurTy = CurTy->getStructElementType(Index);
|
|
|
|
|
FullTy = FullTy->getStructElementType(Index);
|
|
|
|
|
else
|
|
|
|
|
CurTy = CurTy->getArrayElementType();
|
|
|
|
|
FullTy = FullTy->getArrayElementType();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
I = ExtractValueInst::Create(Agg, EXTRACTVALIdx);
|
|
|
|
|
@@ -3935,7 +4002,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))
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Agg, &FullTy))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
Value *Val;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Val))
|
|
|
|
|
@@ -3981,7 +4048,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) ||
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, &FullTy) ||
|
|
|
|
|
popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) ||
|
|
|
|
|
popValue(Record, OpNum, NextValueNo, Type::getInt1Ty(Context), Cond))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
@@ -3996,7 +4063,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) ||
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, &FullTy) ||
|
|
|
|
|
popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) ||
|
|
|
|
|
getValueTypePair(Record, OpNum, NextValueNo, Cond))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
@@ -4026,12 +4093,13 @@ 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) ||
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Vec, &FullTy) ||
|
|
|
|
|
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 = FullTy->getVectorElementType();
|
|
|
|
|
InstructionList.push_back(I);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -4039,7 +4107,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))
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Vec, &FullTy))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
if (!Vec->getType()->isVectorTy())
|
|
|
|
|
return error("Invalid type for value");
|
|
|
|
|
@@ -4055,7 +4123,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) ||
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Vec1, &FullTy) ||
|
|
|
|
|
popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec2))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
@@ -4064,6 +4132,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
if (!Vec1->getType()->isVectorTy() || !Vec2->getType()->isVectorTy())
|
|
|
|
|
return error("Invalid type for value");
|
|
|
|
|
I = new ShuffleVectorInst(Vec1, Vec2, Mask);
|
|
|
|
|
FullTy = VectorType::get(FullTy->getVectorElementType(),
|
|
|
|
|
Mask->getType()->getVectorNumElements());
|
|
|
|
|
InstructionList.push_back(I);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -4367,31 +4437,40 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
BasicBlock *UnwindBB = getBasicBlock(Record[OpNum++]);
|
|
|
|
|
|
|
|
|
|
FunctionType *FTy = nullptr;
|
|
|
|
|
if (CCInfo >> 13 & 1 &&
|
|
|
|
|
!(FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]))))
|
|
|
|
|
return error("Explicit invoke type is not a function type");
|
|
|
|
|
FunctionType *FullFTy = nullptr;
|
|
|
|
|
if ((CCInfo >> 13) & 1) {
|
|
|
|
|
FullFTy =
|
|
|
|
|
dyn_cast<FunctionType>(getFullyStructuredTypeByID(Record[OpNum++]));
|
|
|
|
|
if (!FullFTy)
|
|
|
|
|
return error("Explicit invoke type is not a function type");
|
|
|
|
|
FTy = cast<FunctionType>(flattenPointerTypes(FullFTy));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Value *Callee;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Callee, &FullTy))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
PointerType *CalleeTy = dyn_cast<PointerType>(Callee->getType());
|
|
|
|
|
if (!CalleeTy)
|
|
|
|
|
return error("Callee is not a pointer");
|
|
|
|
|
if (!FTy) {
|
|
|
|
|
FTy = dyn_cast<FunctionType>(CalleeTy->getElementType());
|
|
|
|
|
if (!FTy)
|
|
|
|
|
FullFTy =
|
|
|
|
|
dyn_cast<FunctionType>(cast<PointerType>(FullTy)->getElementType());
|
|
|
|
|
if (!FullFTy)
|
|
|
|
|
return error("Callee is not of pointer to function type");
|
|
|
|
|
} else if (CalleeTy->getElementType() != FTy)
|
|
|
|
|
FTy = cast<FunctionType>(flattenPointerTypes(FullFTy));
|
|
|
|
|
} else if (getPointerElementFlatType(FullTy) != 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;
|
|
|
|
|
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));
|
|
|
|
|
if (!Ops.back())
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
}
|
|
|
|
|
@@ -4403,20 +4482,23 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
// Read type/value pairs for varargs params.
|
|
|
|
|
while (OpNum != Record.size()) {
|
|
|
|
|
Value *Op;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op))
|
|
|
|
|
Type *FullTy;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
Ops.push_back(Op);
|
|
|
|
|
ArgsFullTys.push_back(FullTy);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
propagateByValTypes(cast<CallBase>(I));
|
|
|
|
|
propagateByValTypes(cast<CallBase>(I), ArgsFullTys);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -4442,22 +4524,29 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
IndirectDests.push_back(getBasicBlock(Record[OpNum++]));
|
|
|
|
|
|
|
|
|
|
FunctionType *FTy = nullptr;
|
|
|
|
|
if (CCInfo >> bitc::CALL_EXPLICIT_TYPE & 1 &&
|
|
|
|
|
!(FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]))))
|
|
|
|
|
return error("Explicit call type is not a function type");
|
|
|
|
|
FunctionType *FullFTy = nullptr;
|
|
|
|
|
if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) {
|
|
|
|
|
FullFTy =
|
|
|
|
|
dyn_cast<FunctionType>(getFullyStructuredTypeByID(Record[OpNum++]));
|
|
|
|
|
if (!FullFTy)
|
|
|
|
|
return error("Explicit call type is not a function type");
|
|
|
|
|
FTy = cast<FunctionType>(flattenPointerTypes(FullFTy));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Value *Callee;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Callee, &FullTy))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
|
|
|
|
|
if (!OpTy)
|
|
|
|
|
return error("Callee is not a pointer type");
|
|
|
|
|
if (!FTy) {
|
|
|
|
|
FTy = dyn_cast<FunctionType>(OpTy->getElementType());
|
|
|
|
|
if (!FTy)
|
|
|
|
|
FullFTy =
|
|
|
|
|
dyn_cast<FunctionType>(cast<PointerType>(FullTy)->getElementType());
|
|
|
|
|
if (!FullFTy)
|
|
|
|
|
return error("Callee is not of pointer to function type");
|
|
|
|
|
} else if (OpTy->getElementType() != FTy)
|
|
|
|
|
FTy = cast<FunctionType>(flattenPointerTypes(FullFTy));
|
|
|
|
|
} else if (getPointerElementFlatType(FullTy) != FTy)
|
|
|
|
|
return error("Explicit call type does not match pointee type of "
|
|
|
|
|
"callee operand");
|
|
|
|
|
if (Record.size() < FTy->getNumParams() + OpNum)
|
|
|
|
|
@@ -4490,6 +4579,7 @@ 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(
|
|
|
|
|
@@ -4504,7 +4594,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...]
|
|
|
|
|
if (Record.size() < 1 || ((Record.size()-1)&1))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
Type *Ty = getTypeByID(Record[0]);
|
|
|
|
|
FullTy = getFullyStructuredTypeByID(Record[0]);
|
|
|
|
|
Type *Ty = flattenPointerTypes(FullTy);
|
|
|
|
|
if (!Ty)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
@@ -4541,7 +4632,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
if (Record.size() < 4)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
}
|
|
|
|
|
Type *Ty = getTypeByID(Record[Idx++]);
|
|
|
|
|
FullTy = getFullyStructuredTypeByID(Record[Idx++]);
|
|
|
|
|
Type *Ty = flattenPointerTypes(FullTy);
|
|
|
|
|
if (!Ty)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
if (BitCode == bitc::FUNC_CODE_INST_LANDINGPAD_OLD) {
|
|
|
|
|
@@ -4594,12 +4686,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
SwiftErrorMask;
|
|
|
|
|
bool InAlloca = AlignRecord & InAllocaMask;
|
|
|
|
|
bool SwiftError = AlignRecord & SwiftErrorMask;
|
|
|
|
|
Type *Ty = getTypeByID(Record[0]);
|
|
|
|
|
FullTy = getFullyStructuredTypeByID(Record[0]);
|
|
|
|
|
Type *Ty = flattenPointerTypes(FullTy);
|
|
|
|
|
if ((AlignRecord & ExplicitTypeMask) == 0) {
|
|
|
|
|
auto *PTy = dyn_cast_or_null<PointerType>(Ty);
|
|
|
|
|
if (!PTy)
|
|
|
|
|
return error("Old-style alloca with a non-pointer type");
|
|
|
|
|
Ty = PTy->getElementType();
|
|
|
|
|
std::tie(FullTy, Ty) = getPointerElementTypes(FullTy);
|
|
|
|
|
}
|
|
|
|
|
Type *OpTy = getTypeByID(Record[1]);
|
|
|
|
|
Value *Size = getFnValueByID(Record[2], OpTy);
|
|
|
|
|
@@ -4618,29 +4711,34 @@ 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) ||
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy) ||
|
|
|
|
|
(OpNum + 2 != Record.size() && OpNum + 3 != Record.size()))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
if (!isa<PointerType>(Op->getType()))
|
|
|
|
|
return error("Load operand is not a pointer type");
|
|
|
|
|
|
|
|
|
|
Type *Ty = nullptr;
|
|
|
|
|
if (OpNum + 3 == Record.size())
|
|
|
|
|
Ty = getTypeByID(Record[OpNum++]);
|
|
|
|
|
if (OpNum + 3 == Record.size()) {
|
|
|
|
|
FullTy = getFullyStructuredTypeByID(Record[OpNum++]);
|
|
|
|
|
Ty = flattenPointerTypes(FullTy);
|
|
|
|
|
} else
|
|
|
|
|
std::tie(FullTy, Ty) = getPointerElementTypes(FullTy);
|
|
|
|
|
|
|
|
|
|
if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType()))
|
|
|
|
|
return Err;
|
|
|
|
|
if (!Ty)
|
|
|
|
|
Ty = cast<PointerType>(Op->getType())->getElementType();
|
|
|
|
|
|
|
|
|
|
unsigned Align;
|
|
|
|
|
if (Error Err = parseAlignmentValue(Record[OpNum], Align))
|
|
|
|
|
return Err;
|
|
|
|
|
I = new LoadInst(Ty, Op, "", Record[OpNum + 1], Align);
|
|
|
|
|
|
|
|
|
|
InstructionList.push_back(I);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -4648,17 +4746,22 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
// LOADATOMIC: [opty, op, align, vol, ordering, ssid]
|
|
|
|
|
unsigned OpNum = 0;
|
|
|
|
|
Value *Op;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy) ||
|
|
|
|
|
(OpNum + 4 != Record.size() && OpNum + 5 != Record.size()))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
if (!isa<PointerType>(Op->getType()))
|
|
|
|
|
return error("Load operand is not a pointer type");
|
|
|
|
|
|
|
|
|
|
Type *Ty = nullptr;
|
|
|
|
|
if (OpNum + 5 == Record.size())
|
|
|
|
|
Ty = getTypeByID(Record[OpNum++]);
|
|
|
|
|
if (OpNum + 5 == Record.size()) {
|
|
|
|
|
FullTy = getFullyStructuredTypeByID(Record[OpNum++]);
|
|
|
|
|
Ty = flattenPointerTypes(FullTy);
|
|
|
|
|
} else
|
|
|
|
|
std::tie(FullTy, Ty) = getPointerElementTypes(FullTy);
|
|
|
|
|
|
|
|
|
|
if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType()))
|
|
|
|
|
return Err;
|
|
|
|
|
if (!Ty)
|
|
|
|
|
Ty = cast<PointerType>(Op->getType())->getElementType();
|
|
|
|
|
|
|
|
|
|
AtomicOrdering Ordering = getDecodedOrdering(Record[OpNum + 2]);
|
|
|
|
|
if (Ordering == AtomicOrdering::NotAtomic ||
|
|
|
|
|
@@ -4673,7 +4776,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
if (Error Err = parseAlignmentValue(Record[OpNum], Align))
|
|
|
|
|
return Err;
|
|
|
|
|
I = new LoadInst(Ty, Op, "", Record[OpNum + 1], Align, Ordering, SSID);
|
|
|
|
|
|
|
|
|
|
InstructionList.push_back(I);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -4681,12 +4783,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;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
|
|
|
|
|
Type *FullTy;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy) ||
|
|
|
|
|
(BitCode == bitc::FUNC_CODE_INST_STORE
|
|
|
|
|
? getValueTypePair(Record, OpNum, NextValueNo, Val)
|
|
|
|
|
: popValue(Record, OpNum, NextValueNo,
|
|
|
|
|
cast<PointerType>(Ptr->getType())->getElementType(),
|
|
|
|
|
Val)) ||
|
|
|
|
|
getPointerElementFlatType(FullTy), Val)) ||
|
|
|
|
|
OpNum + 2 != Record.size())
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
@@ -4704,13 +4806,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
// STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, ssid]
|
|
|
|
|
unsigned OpNum = 0;
|
|
|
|
|
Value *Val, *Ptr;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
|
|
|
|
|
Type *FullTy;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy) ||
|
|
|
|
|
!isa<PointerType>(Ptr->getType()) ||
|
|
|
|
|
(BitCode == bitc::FUNC_CODE_INST_STOREATOMIC
|
|
|
|
|
? getValueTypePair(Record, OpNum, NextValueNo, Val)
|
|
|
|
|
: popValue(Record, OpNum, NextValueNo,
|
|
|
|
|
cast<PointerType>(Ptr->getType())->getElementType(),
|
|
|
|
|
Val)) ||
|
|
|
|
|
getPointerElementFlatType(FullTy), Val)) ||
|
|
|
|
|
OpNum + 4 != Record.size())
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
@@ -4738,15 +4840,25 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
// failureordering?, isweak?]
|
|
|
|
|
unsigned OpNum = 0;
|
|
|
|
|
Value *Ptr, *Cmp, *New;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
|
|
|
|
|
(BitCode == bitc::FUNC_CODE_INST_CMPXCHG
|
|
|
|
|
? getValueTypePair(Record, OpNum, NextValueNo, Cmp)
|
|
|
|
|
: popValue(Record, OpNum, NextValueNo,
|
|
|
|
|
cast<PointerType>(Ptr->getType())->getElementType(),
|
|
|
|
|
Cmp)) ||
|
|
|
|
|
popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) ||
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
if (!isa<PointerType>(Ptr->getType()))
|
|
|
|
|
return error("Cmpxchg operand is not a pointer type");
|
|
|
|
|
|
|
|
|
|
if (BitCode == bitc::FUNC_CODE_INST_CMPXCHG) {
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Cmp, &FullTy))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
} else if (popValue(Record, OpNum, NextValueNo,
|
|
|
|
|
getPointerElementFlatType(FullTy), Cmp))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
else
|
|
|
|
|
FullTy = cast<PointerType>(FullTy)->getElementType();
|
|
|
|
|
|
|
|
|
|
if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) ||
|
|
|
|
|
Record.size() < OpNum + 3 || Record.size() > OpNum + 5)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
AtomicOrdering SuccessOrdering = getDecodedOrdering(Record[OpNum + 1]);
|
|
|
|
|
if (SuccessOrdering == AtomicOrdering::NotAtomic ||
|
|
|
|
|
SuccessOrdering == AtomicOrdering::Unordered)
|
|
|
|
|
@@ -4764,6 +4876,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
|
|
|
|
|
I = new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering, FailureOrdering,
|
|
|
|
|
SSID);
|
|
|
|
|
FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)});
|
|
|
|
|
cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
|
|
|
|
|
|
|
|
|
|
if (Record.size() < 8) {
|
|
|
|
|
@@ -4772,6 +4885,7 @@ 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]);
|
|
|
|
|
}
|
|
|
|
|
@@ -4783,11 +4897,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
// ATOMICRMW:[ptrty, ptr, val, op, vol, ordering, ssid]
|
|
|
|
|
unsigned OpNum = 0;
|
|
|
|
|
Value *Ptr, *Val;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy) ||
|
|
|
|
|
!isa<PointerType>(Ptr->getType()) ||
|
|
|
|
|
popValue(Record, OpNum, NextValueNo,
|
|
|
|
|
cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
|
|
|
|
|
OpNum+4 != Record.size())
|
|
|
|
|
getPointerElementFlatType(FullTy), Val) ||
|
|
|
|
|
OpNum + 4 != Record.size())
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
AtomicRMWInst::BinOp Operation = getDecodedRMWOperation(Record[OpNum]);
|
|
|
|
|
if (Operation < AtomicRMWInst::FIRST_BINOP ||
|
|
|
|
|
@@ -4799,6 +4913,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 3]);
|
|
|
|
|
I = new AtomicRMWInst(Operation, Ptr, Val, Ordering, SSID);
|
|
|
|
|
FullTy = getPointerElementFlatType(FullTy);
|
|
|
|
|
cast<AtomicRMWInst>(I)->setVolatile(Record[OpNum+1]);
|
|
|
|
|
InstructionList.push_back(I);
|
|
|
|
|
break;
|
|
|
|
|
@@ -4833,28 +4948,36 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FunctionType *FTy = nullptr;
|
|
|
|
|
if (CCInfo >> bitc::CALL_EXPLICIT_TYPE & 1 &&
|
|
|
|
|
!(FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]))))
|
|
|
|
|
return error("Explicit call type is not a function type");
|
|
|
|
|
FunctionType *FullFTy = nullptr;
|
|
|
|
|
if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) {
|
|
|
|
|
FullFTy =
|
|
|
|
|
dyn_cast<FunctionType>(getFullyStructuredTypeByID(Record[OpNum++]));
|
|
|
|
|
if (!FullFTy)
|
|
|
|
|
return error("Explicit call type is not a function type");
|
|
|
|
|
FTy = cast<FunctionType>(flattenPointerTypes(FullFTy));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Value *Callee;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Callee, &FullTy))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
|
|
|
|
|
PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
|
|
|
|
|
if (!OpTy)
|
|
|
|
|
return error("Callee is not a pointer type");
|
|
|
|
|
if (!FTy) {
|
|
|
|
|
FTy = dyn_cast<FunctionType>(OpTy->getElementType());
|
|
|
|
|
if (!FTy)
|
|
|
|
|
FullFTy =
|
|
|
|
|
dyn_cast<FunctionType>(cast<PointerType>(FullTy)->getElementType());
|
|
|
|
|
if (!FullFTy)
|
|
|
|
|
return error("Callee is not of pointer to function type");
|
|
|
|
|
} else if (OpTy->getElementType() != FTy)
|
|
|
|
|
FTy = cast<FunctionType>(flattenPointerTypes(FullFTy));
|
|
|
|
|
} else if (getPointerElementFlatType(FullTy) != 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;
|
|
|
|
|
// Read the fixed params.
|
|
|
|
|
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
|
|
|
|
|
if (FTy->getParamType(i)->isLabelTy())
|
|
|
|
|
@@ -4862,6 +4985,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
else
|
|
|
|
|
Args.push_back(getValue(Record, OpNum, NextValueNo,
|
|
|
|
|
FTy->getParamType(i)));
|
|
|
|
|
ArgsFullTys.push_back(FullFTy->getParamType(i));
|
|
|
|
|
if (!Args.back())
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
}
|
|
|
|
|
@@ -4873,13 +4997,16 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
} else {
|
|
|
|
|
while (OpNum != Record.size()) {
|
|
|
|
|
Value *Op;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op))
|
|
|
|
|
Type *FullTy;
|
|
|
|
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy))
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
Args.push_back(Op);
|
|
|
|
|
ArgsFullTys.push_back(FullTy);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
I = CallInst::Create(FTy, Callee, Args, OperandBundles);
|
|
|
|
|
FullTy = FullFTy->getReturnType();
|
|
|
|
|
OperandBundles.clear();
|
|
|
|
|
InstructionList.push_back(I);
|
|
|
|
|
cast<CallInst>(I)->setCallingConv(
|
|
|
|
|
@@ -4893,7 +5020,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
TCK = CallInst::TCK_NoTail;
|
|
|
|
|
cast<CallInst>(I)->setTailCallKind(TCK);
|
|
|
|
|
cast<CallInst>(I)->setAttributes(PAL);
|
|
|
|
|
propagateByValTypes(cast<CallBase>(I));
|
|
|
|
|
propagateByValTypes(cast<CallBase>(I), ArgsFullTys);
|
|
|
|
|
if (FMF.any()) {
|
|
|
|
|
if (!isa<FPMathOperator>(I))
|
|
|
|
|
return error("Fast-math-flags specified for call without "
|
|
|
|
|
@@ -4907,7 +5034,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
Type *OpTy = getTypeByID(Record[0]);
|
|
|
|
|
Value *Op = getValue(Record, 1, NextValueNo, OpTy);
|
|
|
|
|
Type *ResTy = getTypeByID(Record[2]);
|
|
|
|
|
FullTy = getFullyStructuredTypeByID(Record[2]);
|
|
|
|
|
Type *ResTy = flattenPointerTypes(FullTy);
|
|
|
|
|
if (!OpTy || !Op || !ResTy)
|
|
|
|
|
return error("Invalid record");
|
|
|
|
|
I = new VAArgInst(Op, ResTy);
|
|
|
|
|
@@ -4957,8 +5085,23 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Non-void values get registered in the value table for future use.
|
|
|
|
|
if (I && !I->getType()->isVoidTy())
|
|
|
|
|
ValueList.assignValue(I, NextValueNo++);
|
|
|
|
|
if (I && !I->getType()->isVoidTy()) {
|
|
|
|
|
if (!FullTy) {
|
|
|
|
|
FullTy = I->getType();
|
|
|
|
|
assert(
|
|
|
|
|
!FullTy->isPointerTy() && !isa<StructType>(FullTy) &&
|
|
|
|
|
!isa<ArrayType>(FullTy) &&
|
|
|
|
|
(!isa<VectorType>(FullTy) ||
|
|
|
|
|
FullTy->getVectorElementType()->isFloatingPointTy() ||
|
|
|
|
|
FullTy->getVectorElementType()->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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OutOfRecordLoop:
|
|
|
|
|
|