aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp166
1 files changed, 114 insertions, 52 deletions
diff --git a/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index f5a878f8788a..720ab560f988 100644
--- a/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1349,7 +1349,7 @@ Error BitcodeReader::parseAttributeBlock() {
return error("Invalid record");
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
- AttrBuilder B;
+ AttrBuilder B(Context);
decodeLLVMAttributesForBitcode(B, Record[i+1]);
Attrs.push_back(AttributeList::get(Context, Record[i], B));
}
@@ -1591,7 +1591,7 @@ Error BitcodeReader::parseAttributeGroupBlock() {
uint64_t GrpID = Record[0];
uint64_t Idx = Record[1]; // Index of the object this attribute refers to.
- AttrBuilder B;
+ AttrBuilder B(Context);
for (unsigned i = 2, e = Record.size(); i != e; ++i) {
if (Record[i] == 0) { // Enum attribute
Attribute::AttrKind Kind;
@@ -2702,7 +2702,7 @@ Error BitcodeReader::parseConstants() {
PointerType *OrigPtrTy = cast<PointerType>(Elt0FullTy->getScalarType());
if (!PointeeType)
- PointeeType = OrigPtrTy->getElementType();
+ PointeeType = OrigPtrTy->getPointerElementType();
else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType))
return error("Explicit gep operator type does not match pointee type "
"of pointer operand");
@@ -2824,9 +2824,9 @@ Error BitcodeReader::parseConstants() {
for (unsigned i = 0; i != ConstStrSize; ++i)
ConstrStr += (char)Record[3+AsmStrSize+i];
UpgradeInlineAsmString(&AsmStr);
- V = InlineAsm::get(
- cast<FunctionType>(cast<PointerType>(CurTy)->getElementType()),
- AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
+ // FIXME: support upgrading in opaque pointers mode.
+ V = InlineAsm::get(cast<FunctionType>(CurTy->getPointerElementType()),
+ AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
break;
}
// This version adds support for the asm dialect keywords (e.g.,
@@ -2850,37 +2850,74 @@ Error BitcodeReader::parseConstants() {
for (unsigned i = 0; i != ConstStrSize; ++i)
ConstrStr += (char)Record[3+AsmStrSize+i];
UpgradeInlineAsmString(&AsmStr);
- V = InlineAsm::get(
- cast<FunctionType>(cast<PointerType>(CurTy)->getElementType()),
- AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
- InlineAsm::AsmDialect(AsmDialect));
+ // FIXME: support upgrading in opaque pointers mode.
+ V = InlineAsm::get(cast<FunctionType>(CurTy->getPointerElementType()),
+ AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
+ InlineAsm::AsmDialect(AsmDialect));
break;
}
// This version adds support for the unwind keyword.
- case bitc::CST_CODE_INLINEASM: {
+ case bitc::CST_CODE_INLINEASM_OLD3: {
if (Record.size() < 2)
return error("Invalid record");
+ unsigned OpNum = 0;
std::string AsmStr, ConstrStr;
- bool HasSideEffects = Record[0] & 1;
- bool IsAlignStack = (Record[0] >> 1) & 1;
- unsigned AsmDialect = (Record[0] >> 2) & 1;
- bool CanThrow = (Record[0] >> 3) & 1;
- unsigned AsmStrSize = Record[1];
- if (2 + AsmStrSize >= Record.size())
+ bool HasSideEffects = Record[OpNum] & 1;
+ bool IsAlignStack = (Record[OpNum] >> 1) & 1;
+ unsigned AsmDialect = (Record[OpNum] >> 2) & 1;
+ bool CanThrow = (Record[OpNum] >> 3) & 1;
+ ++OpNum;
+ unsigned AsmStrSize = Record[OpNum];
+ ++OpNum;
+ if (OpNum + AsmStrSize >= Record.size())
return error("Invalid record");
- unsigned ConstStrSize = Record[2 + AsmStrSize];
- if (3 + AsmStrSize + ConstStrSize > Record.size())
+ unsigned ConstStrSize = Record[OpNum + AsmStrSize];
+ if (OpNum + 1 + AsmStrSize + ConstStrSize > Record.size())
return error("Invalid record");
for (unsigned i = 0; i != AsmStrSize; ++i)
- AsmStr += (char)Record[2 + i];
+ AsmStr += (char)Record[OpNum + i];
+ ++OpNum;
for (unsigned i = 0; i != ConstStrSize; ++i)
- ConstrStr += (char)Record[3 + AsmStrSize + i];
+ ConstrStr += (char)Record[OpNum + AsmStrSize + i];
UpgradeInlineAsmString(&AsmStr);
- V = InlineAsm::get(
- cast<FunctionType>(cast<PointerType>(CurTy)->getElementType()),
- AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
- InlineAsm::AsmDialect(AsmDialect), CanThrow);
+ // FIXME: support upgrading in opaque pointers mode.
+ V = InlineAsm::get(cast<FunctionType>(CurTy->getPointerElementType()),
+ AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
+ InlineAsm::AsmDialect(AsmDialect), CanThrow);
+ break;
+ }
+ // This version adds explicit function type.
+ case bitc::CST_CODE_INLINEASM: {
+ if (Record.size() < 3)
+ return error("Invalid record");
+ unsigned OpNum = 0;
+ auto *FnTy = dyn_cast_or_null<FunctionType>(getTypeByID(Record[OpNum]));
+ ++OpNum;
+ if (!FnTy)
+ return error("Invalid record");
+ std::string AsmStr, ConstrStr;
+ bool HasSideEffects = Record[OpNum] & 1;
+ bool IsAlignStack = (Record[OpNum] >> 1) & 1;
+ unsigned AsmDialect = (Record[OpNum] >> 2) & 1;
+ bool CanThrow = (Record[OpNum] >> 3) & 1;
+ ++OpNum;
+ unsigned AsmStrSize = Record[OpNum];
+ ++OpNum;
+ if (OpNum + AsmStrSize >= Record.size())
+ return error("Invalid record");
+ unsigned ConstStrSize = Record[OpNum + AsmStrSize];
+ if (OpNum + 1 + AsmStrSize + ConstStrSize > Record.size())
+ return error("Invalid record");
+
+ for (unsigned i = 0; i != AsmStrSize; ++i)
+ AsmStr += (char)Record[OpNum + i];
+ ++OpNum;
+ for (unsigned i = 0; i != ConstStrSize; ++i)
+ ConstrStr += (char)Record[OpNum + AsmStrSize + i];
+ UpgradeInlineAsmString(&AsmStr);
+ V = InlineAsm::get(FnTy, AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
+ InlineAsm::AsmDialect(AsmDialect), CanThrow);
break;
}
case bitc::CST_CODE_BLOCKADDRESS:{
@@ -3242,7 +3279,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();
+ Ty = Ty->getPointerElementType();
}
uint64_t RawLinkage = Record[3];
@@ -3335,7 +3372,7 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
if (!FTy)
return error("Invalid record");
if (auto *PTy = dyn_cast<PointerType>(FTy))
- FTy = PTy->getElementType();
+ FTy = PTy->getPointerElementType();
if (!isa<FunctionType>(FTy))
return error("Invalid type for value");
@@ -3376,7 +3413,7 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
Func->removeParamAttr(i, Kind);
Type *PTy = cast<FunctionType>(FTy)->getParamType(i);
- Type *PtrEltTy = cast<PointerType>(PTy)->getElementType();
+ Type *PtrEltTy = PTy->getPointerElementType();
Attribute NewAttr;
switch (Kind) {
case Attribute::ByVal:
@@ -3499,7 +3536,7 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
auto *PTy = dyn_cast<PointerType>(Ty);
if (!PTy)
return error("Invalid type for value");
- Ty = PTy->getElementType();
+ Ty = PTy->getPointerElementType();
AddrSpace = PTy->getAddressSpace();
} else {
AddrSpace = Record[OpNum++];
@@ -3795,6 +3832,11 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
if (Error Err = parseComdatRecord(Record))
return Err;
break;
+ // FIXME: BitcodeReader should handle {GLOBALVAR, FUNCTION, ALIAS, IFUNC}
+ // written by ThinLinkBitcodeWriter. See
+ // `ThinLinkBitcodeWriter::writeSimplifiedModuleInfo` for the format of each
+ // record
+ // (https://github.com/llvm/llvm-project/blob/b6a93967d9c11e79802b5e75cec1584d6c8aa472/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp#L4714)
case bitc::MODULE_CODE_GLOBALVAR:
if (Error Err = parseGlobalVarRecord(Record))
return Err;
@@ -3857,12 +3899,13 @@ void BitcodeReader::propagateAttributeTypes(CallBase *CB,
for (unsigned i = 0; i != CB->arg_size(); ++i) {
for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet,
Attribute::InAlloca}) {
- if (!CB->paramHasAttr(i, Kind))
+ if (!CB->paramHasAttr(i, Kind) ||
+ CB->getParamAttr(i, Kind).getValueAsType())
continue;
CB->removeParamAttr(i, Kind);
- Type *PtrEltTy = cast<PointerType>(ArgsTys[i])->getElementType();
+ Type *PtrEltTy = ArgsTys[i]->getPointerElementType();
Attribute NewAttr;
switch (Kind) {
case Attribute::ByVal:
@@ -3882,11 +3925,28 @@ void BitcodeReader::propagateAttributeTypes(CallBase *CB,
}
}
+ if (CB->isInlineAsm()) {
+ const InlineAsm *IA = cast<InlineAsm>(CB->getCalledOperand());
+ unsigned ArgNo = 0;
+ for (const InlineAsm::ConstraintInfo &CI : IA->ParseConstraints()) {
+ if (!CI.hasArg())
+ continue;
+
+ if (CI.isIndirect && !CB->getAttributes().getParamElementType(ArgNo)) {
+ Type *ElemTy = ArgsTys[ArgNo]->getPointerElementType();
+ CB->addParamAttr(
+ ArgNo, Attribute::get(Context, Attribute::ElementType, ElemTy));
+ }
+
+ ArgNo++;
+ }
+ }
+
switch (CB->getIntrinsicID()) {
case Intrinsic::preserve_array_access_index:
case Intrinsic::preserve_struct_access_index:
if (!CB->getAttributes().getParamElementType(0)) {
- Type *ElTy = cast<PointerType>(ArgsTys[0])->getElementType();
+ Type *ElTy = ArgsTys[0]->getPointerElementType();
Attribute NewAttr = Attribute::get(Context, Attribute::ElementType, ElTy);
CB->addParamAttr(0, NewAttr);
}
@@ -4176,8 +4236,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
return error("Invalid record");
if (!Ty) {
- Ty = cast<PointerType>(BasePtr->getType()->getScalarType())
- ->getElementType();
+ Ty = BasePtr->getType()->getScalarType()->getPointerElementType();
} else if (!cast<PointerType>(BasePtr->getType()->getScalarType())
->isOpaqueOrPointeeTypeMatches(Ty)) {
return error(
@@ -4693,8 +4752,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (!CalleeTy)
return error("Callee is not a pointer");
if (!FTy) {
- FTy = dyn_cast<FunctionType>(
- cast<PointerType>(Callee->getType())->getElementType());
+ FTy =
+ dyn_cast<FunctionType>(Callee->getType()->getPointerElementType());
if (!FTy)
return error("Callee is not of pointer to function type");
} else if (!CalleeTy->isOpaqueOrPointeeTypeMatches(FTy))
@@ -4774,26 +4833,29 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (!OpTy)
return error("Callee is not a pointer type");
if (!FTy) {
- FTy = dyn_cast<FunctionType>(
- cast<PointerType>(Callee->getType())->getElementType());
+ FTy =
+ dyn_cast<FunctionType>(Callee->getType()->getPointerElementType());
if (!FTy)
return error("Callee is not of pointer to function type");
- } else if (cast<PointerType>(Callee->getType())->getElementType() != FTy)
+ } else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy))
return error("Explicit call type does not match pointee type of "
"callee operand");
if (Record.size() < FTy->getNumParams() + OpNum)
return error("Insufficient operands to call");
SmallVector<Value*, 16> Args;
+ SmallVector<Type *, 16> ArgsTys;
// Read the fixed params.
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
+ Value *Arg;
if (FTy->getParamType(i)->isLabelTy())
- Args.push_back(getBasicBlock(Record[OpNum]));
+ Arg = getBasicBlock(Record[OpNum]);
else
- Args.push_back(getValue(Record, OpNum, NextValueNo,
- FTy->getParamType(i)));
- if (!Args.back())
+ Arg = getValue(Record, OpNum, NextValueNo, FTy->getParamType(i));
+ if (!Arg)
return error("Invalid record");
+ Args.push_back(Arg);
+ ArgsTys.push_back(Arg->getType());
}
// Read type/value pairs for varargs params.
@@ -4806,6 +4868,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (getValueTypePair(Record, OpNum, NextValueNo, Op))
return error("Invalid record");
Args.push_back(Op);
+ ArgsTys.push_back(Op->getType());
}
}
@@ -4816,6 +4879,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
cast<CallBrInst>(I)->setCallingConv(
static_cast<CallingConv::ID>((0x7ff & CCInfo) >> bitc::CALL_CCONV));
cast<CallBrInst>(I)->setAttributes(PAL);
+ propagateAttributeTypes(cast<CallBase>(I), ArgsTys);
break;
}
case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
@@ -4932,7 +4996,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
auto *PTy = dyn_cast_or_null<PointerType>(Ty);
if (!PTy)
return error("Old-style alloca with a non-pointer type");
- Ty = PTy->getElementType();
+ Ty = PTy->getPointerElementType();
}
Type *OpTy = getTypeByID(Record[1]);
Value *Size = getFnValueByID(Record[2], OpTy);
@@ -4977,7 +5041,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (OpNum + 3 == Record.size()) {
Ty = getTypeByID(Record[OpNum++]);
} else {
- Ty = cast<PointerType>(Op->getType())->getElementType();
+ Ty = Op->getType()->getPointerElementType();
}
if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType()))
@@ -5010,7 +5074,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (OpNum + 5 == Record.size()) {
Ty = getTypeByID(Record[OpNum++]);
} else {
- Ty = cast<PointerType>(Op->getType())->getElementType();
+ Ty = Op->getType()->getPointerElementType();
}
if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType()))
@@ -5042,8 +5106,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
(BitCode == bitc::FUNC_CODE_INST_STORE
? getValueTypePair(Record, OpNum, NextValueNo, Val)
: popValue(Record, OpNum, NextValueNo,
- cast<PointerType>(Ptr->getType())->getElementType(),
- Val)) ||
+ Ptr->getType()->getPointerElementType(), Val)) ||
OpNum + 2 != Record.size())
return error("Invalid record");
@@ -5071,8 +5134,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
(BitCode == bitc::FUNC_CODE_INST_STOREATOMIC
? getValueTypePair(Record, OpNum, NextValueNo, Val)
: popValue(Record, OpNum, NextValueNo,
- cast<PointerType>(Ptr->getType())->getElementType(),
- Val)) ||
+ Ptr->getType()->getPointerElementType(), Val)) ||
OpNum + 4 != Record.size())
return error("Invalid record");
@@ -5323,8 +5385,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (!OpTy)
return error("Callee is not a pointer type");
if (!FTy) {
- FTy = dyn_cast<FunctionType>(
- cast<PointerType>(Callee->getType())->getElementType());
+ FTy =
+ dyn_cast<FunctionType>(Callee->getType()->getPointerElementType());
if (!FTy)
return error("Callee is not of pointer to function type");
} else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy))