diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-08-22 19:00:43 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-11-13 20:39:49 +0000 |
commit | fe6060f10f634930ff71b7c50291ddc610da2475 (patch) | |
tree | 1483580c790bd4d27b6500a7542b5ee00534d3cc /contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp | |
parent | b61bce17f346d79cecfd8f195a64b10f77be43b1 (diff) | |
parent | 344a3780b2e33f6ca763666c380202b18aab72a3 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 639 |
1 files changed, 357 insertions, 282 deletions
diff --git a/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index f2800201e871..d5e366c21f7d 100644 --- a/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -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; - } - - /// 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)); - } + Type *getTypeByID(unsigned 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; } @@ -715,9 +682,10 @@ private: return getFnValueByID(ValNo, Ty); } - /// Upgrades old-style typeless byval or sret attributes by adding the - /// corresponding argument's pointee type. - void propagateByValSRetTypes(CallBase *CB, ArrayRef<Type *> ArgsFullTys); + /// Upgrades old-style typeless byval/sret/inalloca attributes by adding the + /// corresponding argument's pointee type. Also upgrades intrinsics that now + /// require an elementtype attribute. + void propagateAttributeTypes(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 @@ -968,13 +936,17 @@ static FunctionSummary::FFlags getDecodedFFlags(uint64_t RawFlags) { return Flags; } -/// Decode the flags for GlobalValue in the summary. +// Decode the flags for GlobalValue in the summary. The bits for each attribute: +// +// linkage: [0,4), notEligibleToImport: 4, live: 5, local: 6, canAutoHide: 7, +// visibility: [8, 10). static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags, uint64_t Version) { // Summary were not emitted before LLVM 3.9, we don't need to upgrade Linkage // like getDecodedLinkage() above. Any future change to the linkage enum and // to getDecodedLinkage() will need to be taken into account here as above. auto Linkage = GlobalValue::LinkageTypes(RawFlags & 0xF); // 4 bits + auto Visibility = GlobalValue::VisibilityTypes((RawFlags >> 8) & 3); // 2 bits RawFlags = RawFlags >> 4; bool NotEligibleToImport = (RawFlags & 0x1) || Version < 3; // The Live flag wasn't introduced until version 3. For dead stripping @@ -984,7 +956,8 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags, bool Local = (RawFlags & 0x4); bool AutoHide = (RawFlags & 0x8); - return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, Live, Local, AutoHide); + return GlobalValueSummary::GVFlags(Linkage, Visibility, NotEligibleToImport, + Live, Local, AutoHide); } // Decode the flags for GlobalVariable in the summary @@ -1155,7 +1128,7 @@ static Comdat::SelectionKind getDecodedComdatSelectionKind(unsigned Val) { case bitc::COMDAT_SELECTION_KIND_LARGEST: return Comdat::Largest; case bitc::COMDAT_SELECTION_KIND_NO_DUPLICATES: - return Comdat::NoDuplicates; + return Comdat::NoDeduplicate; case bitc::COMDAT_SELECTION_KIND_SAME_SIZE: return Comdat::SameSize; } @@ -1189,7 +1162,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; @@ -1307,6 +1280,8 @@ static void addRawAttributeValue(AttrBuilder &B, uint64_t Val) { B.addAlignmentAttr(1ULL << ((A >> 16) - 1)); else if (I == Attribute::StackAlignment) B.addStackAlignmentAttr(1ULL << ((A >> 26)-1)); + else if (Attribute::isTypeAttrKind(I)) + B.addTypeAttr(I, nullptr); // Type will be auto-upgraded. else B.addAttribute(I); } @@ -1413,6 +1388,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::Cold; case bitc::ATTR_KIND_CONVERGENT: return Attribute::Convergent; + case bitc::ATTR_KIND_ELEMENTTYPE: + return Attribute::ElementType; case bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY: return Attribute::InaccessibleMemOnly; case bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY: @@ -1467,8 +1444,12 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::NoSync; case bitc::ATTR_KIND_NOCF_CHECK: return Attribute::NoCfCheck; + case bitc::ATTR_KIND_NO_PROFILE: + return Attribute::NoProfile; case bitc::ATTR_KIND_NO_UNWIND: return Attribute::NoUnwind; + case bitc::ATTR_KIND_NO_SANITIZE_COVERAGE: + return Attribute::NoSanitizeCoverage; case bitc::ATTR_KIND_NULL_POINTER_IS_VALID: return Attribute::NullPointerIsValid; case bitc::ATTR_KIND_OPT_FOR_FUZZING: @@ -1519,8 +1500,12 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::SwiftError; case bitc::ATTR_KIND_SWIFT_SELF: return Attribute::SwiftSelf; + case bitc::ATTR_KIND_SWIFT_ASYNC: + return Attribute::SwiftAsync; case bitc::ATTR_KIND_UW_TABLE: return Attribute::UWTable; + case bitc::ATTR_KIND_VSCALE_RANGE: + return Attribute::VScaleRange; case bitc::ATTR_KIND_WILLRETURN: return Attribute::WillReturn; case bitc::ATTR_KIND_WRITEONLY: @@ -1617,12 +1602,18 @@ Error BitcodeReader::parseAttributeGroupBlock() { B.addByValAttr(nullptr); else if (Kind == Attribute::StructRet) B.addStructRetAttr(nullptr); - - B.addAttribute(Kind); + else if (Kind == Attribute::InAlloca) + B.addInAllocaAttr(nullptr); + else if (Attribute::isEnumAttrKind(Kind)) + B.addAttribute(Kind); + else + return error("Not an enum attribute"); } else if (Record[i] == 1) { // Integer attribute Attribute::AttrKind Kind; if (Error Err = parseAttrKind(Record[++i], &Kind)) return Err; + if (!Attribute::isIntAttrKind(Kind)) + return error("Not an int attribute"); if (Kind == Attribute::Alignment) B.addAlignmentAttr(Record[++i]); else if (Kind == Attribute::StackAlignment) @@ -1633,6 +1624,8 @@ Error BitcodeReader::parseAttributeGroupBlock() { B.addDereferenceableOrNullAttr(Record[++i]); else if (Kind == Attribute::AllocSize) B.addAllocSizeAttrFromRawRepr(Record[++i]); + else if (Kind == Attribute::VScaleRange) + B.addVScaleRangeAttrFromRawRepr(Record[++i]); } else if (Record[i] == 3 || Record[i] == 4) { // String attribute bool HasValue = (Record[i++] == 4); SmallString<64> KindStr; @@ -1658,15 +1651,10 @@ Error BitcodeReader::parseAttributeGroupBlock() { Attribute::AttrKind Kind; if (Error Err = parseAttrKind(Record[++i], &Kind)) return Err; - if (Kind == Attribute::ByVal) { - B.addByValAttr(HasType ? getTypeByID(Record[++i]) : nullptr); - } else if (Kind == Attribute::StructRet) { - B.addStructRetAttr(HasType ? getTypeByID(Record[++i]) : nullptr); - } else if (Kind == Attribute::ByRef) { - B.addByRefAttr(getTypeByID(Record[++i])); - } else if (Kind == Attribute::Preallocated) { - B.addPreallocatedAttr(getTypeByID(Record[++i])); - } + if (!Attribute::isTypeAttrKind(Kind)) + return error("Not a type attribute"); + + B.addTypeAttr(Kind, HasType ? getTypeByID(Record[++i]) : nullptr); } } @@ -1794,6 +1782,13 @@ Error BitcodeReader::parseTypeTableBody() { ResultTy = PointerType::get(ResultTy, AddressSpace); break; } + case bitc::TYPE_CODE_OPAQUE_POINTER: { // OPAQUE_POINTER: [addrspace] + if (Record.size() != 1) + return error("Invalid record"); + unsigned AddressSpace = Record[0]; + ResultTy = PointerType::get(Context, AddressSpace); + break; + } case bitc::TYPE_CODE_FUNCTION_OLD: { // Deprecated, but still needed to read old bitcode files. // FUNCTION: [vararg, attrid, retty, paramty x N] @@ -2345,13 +2340,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; @@ -2392,7 +2385,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()) @@ -2427,8 +2420,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()) @@ -2665,7 +2657,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"); @@ -2675,11 +2667,10 @@ Error BitcodeReader::parseConstants() { if (Elts.size() < 1) return error("Invalid gep with no operands"); - Type *ImplicitPointeeType = - getPointerElementFlatType(Elt0FullTy->getScalarType()); + PointerType *OrigPtrTy = cast<PointerType>(Elt0FullTy->getScalarType()); if (!PointeeType) - PointeeType = ImplicitPointeeType; - else if (PointeeType != ImplicitPointeeType) + PointeeType = OrigPtrTy->getElementType(); + else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType)) return error("Explicit gep operator type does not match pointee type " "of pointer operand"); @@ -2760,7 +2751,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; } @@ -2771,7 +2762,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; } @@ -2811,13 +2802,13 @@ 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., // inteldialect). - case bitc::CST_CODE_INLINEASM: { + case bitc::CST_CODE_INLINEASM_OLD2: { if (Record.size() < 2) return error("Invalid record"); std::string AsmStr, ConstrStr; @@ -2837,11 +2828,38 @@ 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; } + // This version adds support for the unwind keyword. + case bitc::CST_CODE_INLINEASM: { + if (Record.size() < 2) + return error("Invalid record"); + 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()) + return error("Invalid record"); + unsigned ConstStrSize = Record[2 + AsmStrSize]; + if (3 + AsmStrSize + ConstStrSize > Record.size()) + return error("Invalid record"); + + for (unsigned i = 0; i != AsmStrSize; ++i) + AsmStr += (char)Record[2 + i]; + 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), CanThrow); + break; + } case bitc::CST_CODE_BLOCKADDRESS:{ if (Record.size() < 3) return error("Invalid record"); @@ -2883,11 +2901,23 @@ Error BitcodeReader::parseConstants() { V = BlockAddress::get(Fn, BB); break; } + case bitc::CST_CODE_DSO_LOCAL_EQUIVALENT: { + if (Record.size() < 2) + return error("Invalid record"); + Type *GVTy = getTypeByID(Record[0]); + if (!GVTy) + return error("Invalid record"); + GlobalValue *GV = dyn_cast_or_null<GlobalValue>( + ValueList.getConstantFwdRef(Record[1], GVTy)); + if (!GV) + return error("Invalid record"); + + V = DSOLocalEquivalent::get(GV); + break; + } } - assert(V->getType() == flattenPointerTypes(CurFullTy) && - "Incorrect fully structured type provided for Constant"); - ValueList.assignValue(V, NextCstNo, CurFullTy); + ValueList.assignValue(V, NextCstNo); ++NextCstNo; } } @@ -3165,8 +3195,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; @@ -3178,7 +3207,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]; @@ -3224,10 +3253,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]) @@ -3270,12 +3296,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"); @@ -3291,9 +3316,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]; @@ -3305,18 +3330,33 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { // argument's pointee type. There should be no opaque pointers where the byval // type is implicit. for (unsigned i = 0; i != Func->arg_size(); ++i) { - for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet}) { + for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet, + Attribute::InAlloca}) { if (!Func->hasParamAttribute(i, Kind)) continue; + if (Func->getParamAttribute(i, Kind).getValueAsType()) + continue; + Func->removeParamAttr(i, Kind); - Type *PTy = cast<FunctionType>(FullFTy)->getParamType(i); - Type *PtrEltTy = getPointerElementFlatType(PTy); - Attribute NewAttr = - Kind == Attribute::ByVal - ? Attribute::getWithByValType(Context, PtrEltTy) - : Attribute::getWithStructRetType(Context, PtrEltTy); + Type *PTy = cast<FunctionType>(FTy)->getParamType(i); + Type *PtrEltTy = cast<PointerType>(PTy)->getElementType(); + Attribute NewAttr; + switch (Kind) { + case Attribute::ByVal: + NewAttr = Attribute::getWithByValType(Context, PtrEltTy); + break; + case Attribute::StructRet: + NewAttr = Attribute::getWithStructRetType(Context, PtrEltTy); + break; + case Attribute::InAlloca: + NewAttr = Attribute::getWithInAllocaType(Context, PtrEltTy); + break; + default: + llvm_unreachable("not an upgraded type attribute"); + } + Func->addParamAttr(i, NewAttr); } } @@ -3374,14 +3414,14 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { // Record[16] is the address space number. - // Check whether we have enough values to read a partition name. - if (Record.size() > 18) + // Check whether we have enough values to read a partition name. Also make + // sure Strtab has enough values. + if (Record.size() > 18 && Strtab.data() && + Record[17] + Record[18] <= Strtab.size()) { 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. @@ -3410,8 +3450,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"); @@ -3420,7 +3459,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++]; @@ -3437,8 +3476,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()) { @@ -3468,10 +3505,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(); } @@ -3769,33 +3803,57 @@ Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata, Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) { if (!isa<PointerType>(PtrType)) return error("Load/Store operand is not a pointer type"); - Type *ElemType = cast<PointerType>(PtrType)->getElementType(); - if (ValType && ValType != ElemType) + if (!cast<PointerType>(PtrType)->isOpaqueOrPointeeTypeMatches(ValType)) return error("Explicit load/store type does not match pointee " "type of pointer operand"); - if (!PointerType::isLoadableOrStorableType(ElemType)) + if (!PointerType::isLoadableOrStorableType(ValType)) return error("Cannot load/store from pointer"); return Error::success(); } -void BitcodeReader::propagateByValSRetTypes(CallBase *CB, - ArrayRef<Type *> ArgsFullTys) { +void BitcodeReader::propagateAttributeTypes(CallBase *CB, + ArrayRef<Type *> ArgsTys) { for (unsigned i = 0; i != CB->arg_size(); ++i) { - for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet}) { + for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet, + Attribute::InAlloca}) { if (!CB->paramHasAttr(i, Kind)) continue; CB->removeParamAttr(i, Kind); - Type *PtrEltTy = getPointerElementFlatType(ArgsFullTys[i]); - Attribute NewAttr = - Kind == Attribute::ByVal - ? Attribute::getWithByValType(Context, PtrEltTy) - : Attribute::getWithStructRetType(Context, PtrEltTy); + Type *PtrEltTy = cast<PointerType>(ArgsTys[i])->getElementType(); + Attribute NewAttr; + switch (Kind) { + case Attribute::ByVal: + NewAttr = Attribute::getWithByValType(Context, PtrEltTy); + break; + case Attribute::StructRet: + NewAttr = Attribute::getWithStructRetType(Context, PtrEltTy); + break; + case Attribute::InAlloca: + NewAttr = Attribute::getWithInAllocaType(Context, PtrEltTy); + break; + default: + llvm_unreachable("not an upgraded type attribute"); + } + CB->addParamAttr(i, NewAttr); } } + + 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(); + Attribute NewAttr = Attribute::get(Context, Attribute::ElementType, ElTy); + CB->addParamAttr(0, NewAttr); + } + break; + default: + break; + } } /// Lazily parse the specified function body block. @@ -3812,12 +3870,14 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned ModuleMDLoaderSize = MDLoader->size(); // Add all the function arguments to the value table. +#ifndef NDEBUG unsigned ArgNo = 0; - FunctionType *FullFTy = FunctionTypes[F]; + FunctionType *FTy = FunctionTypes[F]; +#endif 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; @@ -3890,7 +3950,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(); @@ -4036,8 +4095,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"); @@ -4067,24 +4125,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 (Ty != getPointerElementFlatType(FullBaseTy->getScalarType())) + 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()) { @@ -4095,7 +4153,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx); - FullTy = GetElementPtrInst::getGEPReturnType(FullTy, I, GEPIdx); InstructionList.push_back(I); if (InBounds) @@ -4107,8 +4164,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) @@ -4116,24 +4174,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); @@ -4145,7 +4203,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)) @@ -4191,7 +4249,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"); @@ -4206,7 +4264,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"); @@ -4236,13 +4294,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; } @@ -4250,7 +4307,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"); @@ -4266,7 +4323,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"); @@ -4276,9 +4333,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; } @@ -4586,40 +4640,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 (!CalleeTy->isOpaqueOrPointeeTypeMatches(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"); } @@ -4631,23 +4681,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); + propagateAttributeTypes(cast<CallBase>(I), ArgsTys); break; } @@ -4673,29 +4721,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) @@ -4728,7 +4772,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( @@ -4744,8 +4787,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"); @@ -4797,8 +4839,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) { @@ -4847,13 +4888,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); @@ -4879,14 +4919,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"); @@ -4895,10 +4934,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; @@ -4919,7 +4958,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"); @@ -4928,10 +4967,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; @@ -4958,12 +4997,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"); @@ -4986,13 +5025,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"); @@ -5022,7 +5061,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())) @@ -5030,11 +5069,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) @@ -5056,13 +5094,16 @@ Error BitcodeReader::parseFunctionBody(Function *F) { ? AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrdering) : getDecodedOrdering(Record[OpNum + 3]); + if (FailureOrdering == AtomicOrdering::NotAtomic || + FailureOrdering == AtomicOrdering::Unordered) + return error("Invalid record"); + const Align Alignment( TheModule->getDataLayout().getTypeStoreSize(Cmp->getType())); 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 @@ -5070,7 +5111,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]); } @@ -5080,30 +5120,33 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } case bitc::FUNC_CODE_INST_CMPXCHG: { // CMPXCHG: [ptrty, ptr, cmp, val, vol, success_ordering, synchscope, - // failure_ordering, weak] + // failure_ordering, weak, align?] 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; - if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), Val) || - NumRecords < OpNum + 3 || NumRecords > OpNum + 5) + if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), Val)) + return error("Invalid record"); + + if (NumRecords < OpNum + 3 || NumRecords > OpNum + 6) return error("Invalid record"); + const bool IsVol = Record[OpNum]; + const AtomicOrdering SuccessOrdering = getDecodedOrdering(Record[OpNum + 1]); - if (SuccessOrdering == AtomicOrdering::NotAtomic || - SuccessOrdering == AtomicOrdering::Unordered) - return error("Invalid record"); + if (!AtomicCmpXchgInst::isValidSuccessOrdering(SuccessOrdering)) + return error("Invalid cmpxchg success ordering"); const SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 2]); @@ -5112,43 +5155,86 @@ Error BitcodeReader::parseFunctionBody(Function *F) { const AtomicOrdering FailureOrdering = getDecodedOrdering(Record[OpNum + 3]); + if (!AtomicCmpXchgInst::isValidFailureOrdering(FailureOrdering)) + return error("Invalid cmpxchg failure ordering"); - const Align Alignment( - TheModule->getDataLayout().getTypeStoreSize(Cmp->getType())); + const bool IsWeak = Record[OpNum + 4]; + + MaybeAlign Alignment; - I = new AtomicCmpXchgInst(Ptr, Cmp, Val, Alignment, SuccessOrdering, + if (NumRecords == (OpNum + 6)) { + if (Error Err = parseAlignmentValue(Record[OpNum + 5], Alignment)) + return Err; + } + if (!Alignment) + Alignment = + Align(TheModule->getDataLayout().getTypeStoreSize(Cmp->getType())); + + I = new AtomicCmpXchgInst(Ptr, Cmp, Val, *Alignment, SuccessOrdering, FailureOrdering, SSID); - FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)}); - cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]); - cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum + 4]); + cast<AtomicCmpXchgInst>(I)->setVolatile(IsVol); + cast<AtomicCmpXchgInst>(I)->setWeak(IsWeak); InstructionList.push_back(I); break; } + case bitc::FUNC_CODE_INST_ATOMICRMW_OLD: case bitc::FUNC_CODE_INST_ATOMICRMW: { - // ATOMICRMW:[ptrty, ptr, val, op, vol, ordering, ssid] + // ATOMICRMW_OLD: [ptrty, ptr, val, op, vol, ordering, ssid, align?] + // ATOMICRMW: [ptrty, ptr, valty, val, op, vol, ordering, ssid, align?] + const size_t NumRecords = Record.size(); unsigned OpNum = 0; - Value *Ptr, *Val; - if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy) || - !isa<PointerType>(Ptr->getType()) || - popValue(Record, OpNum, NextValueNo, - getPointerElementFlatType(FullTy), Val) || - OpNum + 4 != Record.size()) + + Value *Ptr = nullptr; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr)) return error("Invalid record"); - AtomicRMWInst::BinOp Operation = getDecodedRMWOperation(Record[OpNum]); + + if (!isa<PointerType>(Ptr->getType())) + return error("Invalid record"); + + Value *Val = nullptr; + if (BitCode == bitc::FUNC_CODE_INST_ATOMICRMW_OLD) { + if (popValue(Record, OpNum, NextValueNo, + cast<PointerType>(Ptr->getType())->getPointerElementType(), + Val)) + return error("Invalid record"); + } else { + if (getValueTypePair(Record, OpNum, NextValueNo, Val)) + return error("Invalid record"); + } + + if (!(NumRecords == (OpNum + 4) || NumRecords == (OpNum + 5))) + return error("Invalid record"); + + const AtomicRMWInst::BinOp Operation = + getDecodedRMWOperation(Record[OpNum]); if (Operation < AtomicRMWInst::FIRST_BINOP || Operation > AtomicRMWInst::LAST_BINOP) return error("Invalid record"); - AtomicOrdering Ordering = getDecodedOrdering(Record[OpNum + 2]); + + const bool IsVol = Record[OpNum + 1]; + + const AtomicOrdering Ordering = getDecodedOrdering(Record[OpNum + 2]); if (Ordering == AtomicOrdering::NotAtomic || Ordering == AtomicOrdering::Unordered) return error("Invalid record"); - SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 3]); - Align Alignment( - TheModule->getDataLayout().getTypeStoreSize(Val->getType())); - I = new AtomicRMWInst(Operation, Ptr, Val, Alignment, Ordering, SSID); - FullTy = getPointerElementFlatType(FullTy); - cast<AtomicRMWInst>(I)->setVolatile(Record[OpNum+1]); + + const SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 3]); + + MaybeAlign Alignment; + + if (NumRecords == (OpNum + 5)) { + if (Error Err = parseAlignmentValue(Record[OpNum + 4], Alignment)) + return Err; + } + + if (!Alignment) + Alignment = + Align(TheModule->getDataLayout().getTypeStoreSize(Val->getType())); + + I = new AtomicRMWInst(Operation, Ptr, Val, *Alignment, Ordering, SSID); + cast<AtomicRMWInst>(I)->setVolatile(IsVol); + InstructionList.push_back(I); break; } @@ -5182,36 +5268,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 (!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> 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()) @@ -5219,7 +5301,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"); } @@ -5231,16 +5313,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( @@ -5254,7 +5334,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); + propagateAttributeTypes(cast<CallBase>(I), ArgsTys); if (FMF.any()) { if (!isa<FPMathOperator>(I)) return error("Fast-math-flags specified for call without " @@ -5268,8 +5348,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); @@ -5302,7 +5381,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"); @@ -5332,23 +5411,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: @@ -5472,8 +5536,8 @@ Error BitcodeReader::materialize(GlobalValue *GV) { } } - // "Upgrade" older incorrect branch weights by dropping them. for (auto &I : instructions(F)) { + // "Upgrade" older incorrect branch weights by dropping them. if (auto *MD = I.getMetadata(LLVMContext::MD_prof)) { if (MD->getOperand(0) != nullptr && isa<MDString>(MD->getOperand(0))) { MDString *MDS = cast<MDString>(MD->getOperand(0)); @@ -5500,6 +5564,17 @@ Error BitcodeReader::materialize(GlobalValue *GV) { I.setMetadata(LLVMContext::MD_prof, nullptr); } } + + // Remove incompatible attributes on function calls. + if (auto *CI = dyn_cast<CallBase>(&I)) { + CI->removeAttributes(AttributeList::ReturnIndex, + AttributeFuncs::typeIncompatible( + CI->getFunctionType()->getReturnType())); + + for (unsigned ArgNo = 0; ArgNo < CI->arg_size(); ++ArgNo) + CI->removeParamAttrs(ArgNo, AttributeFuncs::typeIncompatible( + CI->getArgOperand(ArgNo)->getType())); + } } // Look for functions that rely on old function attribute behavior. @@ -6801,7 +6876,7 @@ static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, case bitc::FS_FLAGS: { // [flags] uint64_t Flags = Record[0]; // Scan flags. - assert(Flags <= 0x3f && "Unexpected bits in flag"); + assert(Flags <= 0x7f && "Unexpected bits in flag"); return Flags & 0x8; } |