diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -593,42 +593,12 @@ 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(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 getPointerElementTypes(Type *FullTy) { - Type *ElTy = cast(FullTy)->getElementType(); - return std::make_pair(ElTy, flattenPointerTypes(ElTy)); - } + Type *getTypeByID(unsigned ID); - /// Return the flattened type (suitable for use in a Value) - /// specified by the given \param ID . - Type *getTypeByID(unsigned ID) { - return flattenPointerTypes(getFullyStructuredTypeByID(ID)); - } - - /// Return the fully structured (bitcode-reader internal) type - /// corresponding to the given \param ID . - Type *getFullyStructuredTypeByID(unsigned ID); - - Value *getFnValueByID(unsigned ID, Type *Ty, Type **FullTy = nullptr) { + Value *getFnValueByID(unsigned ID, Type *Ty) { if (Ty && Ty->isMetadataTy()) return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID)); - return ValueList.getValueFwdRef(ID, Ty, FullTy); + return ValueList.getValueFwdRef(ID, Ty); } Metadata *getFnMetadataByID(unsigned ID) { @@ -650,8 +620,7 @@ /// Increment Slot past the number of slots used in the record. Return true on /// failure. bool getValueTypePair(const SmallVectorImpl &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 @@ 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 @@ unsigned TypeNo = (unsigned)Record[Slot++]; ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo)); - if (FullTy) - *FullTy = getFullyStructuredTypeByID(TypeNo); return ResVal == nullptr; } @@ -717,7 +684,7 @@ /// Upgrades old-style typeless byval or sret attributes by adding the /// corresponding argument's pointee type. - void propagateByValSRetTypes(CallBase *CB, ArrayRef ArgsFullTys); + void propagateByValSRetTypes(CallBase *CB, ArrayRef ArgsTys); /// Converts alignment exponent (i.e. power of two (or zero)) to the /// corresponding alignment to use. If alignment is too large, returns @@ -1194,7 +1161,7 @@ } } -Type *BitcodeReader::getFullyStructuredTypeByID(unsigned ID) { +Type *BitcodeReader::getTypeByID(unsigned ID) { // The type table size is always specified correctly. if (ID >= TypeList.size()) return nullptr; @@ -2369,13 +2336,11 @@ // Read all the records for this value table. Type *CurTy = Type::getInt32Ty(Context); - Type *CurFullTy = Type::getInt32Ty(Context); unsigned NextCstNo = ValueList.size(); struct DelayedShufTy { VectorType *OpTy; VectorType *RTy; - Type *CurFullTy; uint64_t Op0Idx; uint64_t Op1Idx; uint64_t Op2Idx; @@ -2416,7 +2381,7 @@ SmallVector Mask; ShuffleVectorInst::getShuffleMask(Op2, Mask); Value *V = ConstantExpr::getShuffleVector(Op0, Op1, Mask); - ValueList.assignValue(V, CstNo, DelayedShuffle.CurFullTy); + ValueList.assignValue(V, CstNo); } if (NextCstNo != ValueList.size()) @@ -2451,8 +2416,7 @@ return error("Invalid record"); if (TypeList[Record[0]] == VoidType) return error("Invalid constant type"); - CurFullTy = TypeList[Record[0]]; - CurTy = flattenPointerTypes(CurFullTy); + CurTy = TypeList[Record[0]]; continue; // Skip the ValueList manipulation. case bitc::CST_CODE_NULL: // NULL if (CurTy->isVoidTy() || CurTy->isFunctionTy() || CurTy->isLabelTy()) @@ -2689,7 +2653,7 @@ Type *Elt0FullTy = nullptr; while (OpNum != Record.size()) { if (!Elt0FullTy) - Elt0FullTy = getFullyStructuredTypeByID(Record[OpNum]); + Elt0FullTy = getTypeByID(Record[OpNum]); Type *ElTy = getTypeByID(Record[OpNum++]); if (!ElTy) return error("Invalid record"); @@ -2700,7 +2664,7 @@ return error("Invalid gep with no operands"); Type *ImplicitPointeeType = - getPointerElementFlatType(Elt0FullTy->getScalarType()); + cast(Elt0FullTy->getScalarType())->getElementType(); if (!PointeeType) PointeeType = ImplicitPointeeType; else if (PointeeType != ImplicitPointeeType) @@ -2784,7 +2748,7 @@ if (Record.size() < 3 || !OpTy) return error("Invalid record"); DelayedShuffles.push_back( - {OpTy, OpTy, CurFullTy, Record[0], Record[1], Record[2], NextCstNo}); + {OpTy, OpTy, Record[0], Record[1], Record[2], NextCstNo}); ++NextCstNo; continue; } @@ -2795,7 +2759,7 @@ if (Record.size() < 4 || !RTy || !OpTy) return error("Invalid record"); DelayedShuffles.push_back( - {OpTy, RTy, CurFullTy, Record[1], Record[2], Record[3], NextCstNo}); + {OpTy, RTy, Record[1], Record[2], Record[3], NextCstNo}); ++NextCstNo; continue; } @@ -2835,8 +2799,8 @@ ConstrStr += (char)Record[3+AsmStrSize+i]; UpgradeInlineAsmString(&AsmStr); V = InlineAsm::get( - cast(getPointerElementFlatType(CurFullTy)), AsmStr, - ConstrStr, HasSideEffects, IsAlignStack); + cast(cast(CurTy)->getElementType()), + AsmStr, ConstrStr, HasSideEffects, IsAlignStack); break; } // This version adds support for the asm dialect keywords (e.g., @@ -2861,8 +2825,8 @@ ConstrStr += (char)Record[3+AsmStrSize+i]; UpgradeInlineAsmString(&AsmStr); V = InlineAsm::get( - cast(getPointerElementFlatType(CurFullTy)), AsmStr, - ConstrStr, HasSideEffects, IsAlignStack, + cast(cast(CurTy)->getElementType()), + AsmStr, ConstrStr, HasSideEffects, IsAlignStack, InlineAsm::AsmDialect(AsmDialect)); break; } @@ -2888,8 +2852,8 @@ ConstrStr += (char)Record[3 + AsmStrSize + i]; UpgradeInlineAsmString(&AsmStr); V = InlineAsm::get( - cast(getPointerElementFlatType(CurFullTy)), AsmStr, - ConstrStr, HasSideEffects, IsAlignStack, + cast(cast(CurTy)->getElementType()), + AsmStr, ConstrStr, HasSideEffects, IsAlignStack, InlineAsm::AsmDialect(AsmDialect), CanThrow); break; } @@ -2950,9 +2914,7 @@ } } - assert(V->getType() == flattenPointerTypes(CurFullTy) && - "Incorrect fully structured type provided for Constant"); - ValueList.assignValue(V, NextCstNo, CurFullTy); + ValueList.assignValue(V, NextCstNo); ++NextCstNo; } } @@ -3230,8 +3192,7 @@ if (Record.size() < 6) return error("Invalid record"); - Type *FullTy = getFullyStructuredTypeByID(Record[0]); - Type *Ty = flattenPointerTypes(FullTy); + Type *Ty = getTypeByID(Record[0]); if (!Ty) return error("Invalid record"); bool isConstant = Record[1] & 1; @@ -3243,7 +3204,7 @@ if (!Ty->isPointerTy()) return error("Invalid type for value"); AddressSpace = cast(Ty)->getAddressSpace(); - std::tie(FullTy, Ty) = getPointerElementTypes(FullTy); + Ty = cast(Ty)->getElementType(); } uint64_t RawLinkage = Record[3]; @@ -3289,10 +3250,7 @@ else upgradeDLLImportExportLinkage(NewGV, RawLinkage); - FullTy = PointerType::get(FullTy, AddressSpace); - assert(NewGV->getType() == flattenPointerTypes(FullTy) && - "Incorrect fully specified type for GlobalVariable"); - ValueList.push_back(NewGV, FullTy); + ValueList.push_back(NewGV); // Remember which value to use for the global initializer. if (unsigned InitID = Record[2]) @@ -3335,12 +3293,11 @@ 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(FTy)) - std::tie(FullFTy, FTy) = getPointerElementTypes(FullFTy); + if (auto *PTy = dyn_cast(FTy)) + FTy = PTy->getElementType(); if (!isa(FTy)) return error("Invalid type for value"); @@ -3356,9 +3313,9 @@ Function::Create(cast(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(FullFTy); + FunctionTypes[Func] = cast(FTy); Func->setCallingConv(CC); bool isProto = Record[2]; @@ -3377,8 +3334,8 @@ Func->removeParamAttr(i, Kind); - Type *PTy = cast(FullFTy)->getParamType(i); - Type *PtrEltTy = getPointerElementFlatType(PTy); + Type *PTy = cast(FTy)->getParamType(i); + Type *PtrEltTy = cast(PTy)->getElementType(); Attribute NewAttr; switch (Kind) { case Attribute::ByVal: @@ -3455,10 +3412,7 @@ if (Record.size() > 18) Func->setPartition(StringRef(Strtab.data() + Record[17], Record[18])); - Type *FullTy = PointerType::get(FullFTy, AddrSpace); - assert(Func->getType() == flattenPointerTypes(FullTy) && - "Incorrect fully specified type provided for Function"); - ValueList.push_back(Func, FullTy); + ValueList.push_back(Func); // If this is a function with a body, remember the prototype we are // creating now, so that we can match up the body with them later. @@ -3487,8 +3441,7 @@ if (Record.size() < (3 + (unsigned)NewRecord)) return error("Invalid record"); unsigned OpNum = 0; - Type *FullTy = getFullyStructuredTypeByID(Record[OpNum++]); - Type *Ty = flattenPointerTypes(FullTy); + Type *Ty = getTypeByID(Record[OpNum++]); if (!Ty) return error("Invalid record"); @@ -3497,7 +3450,7 @@ auto *PTy = dyn_cast(Ty); if (!PTy) return error("Invalid type for value"); - std::tie(FullTy, Ty) = getPointerElementTypes(FullTy); + Ty = PTy->getElementType(); AddrSpace = PTy->getAddressSpace(); } else { AddrSpace = Record[OpNum++]; @@ -3514,8 +3467,6 @@ NewGA = GlobalIFunc::create(Ty, AddrSpace, getDecodedLinkage(Linkage), Name, nullptr, TheModule); - assert(NewGA->getValueType() == flattenPointerTypes(FullTy) && - "Incorrect fully structured type provided for GlobalIndirectSymbol"); // Local linkage must have default visibility. // auto-upgrade `hidden` and `protected` for old bitcode. if (OpNum != Record.size()) { @@ -3545,10 +3496,7 @@ OpNum += 2; } - FullTy = PointerType::get(FullTy, AddrSpace); - assert(NewGA->getType() == flattenPointerTypes(FullTy) && - "Incorrect fully structured type provided for GlobalIndirectSymbol"); - ValueList.push_back(NewGA, FullTy); + ValueList.push_back(NewGA); IndirectSymbolInits.push_back(std::make_pair(NewGA, Val)); return Error::success(); } @@ -3856,7 +3804,7 @@ } void BitcodeReader::propagateByValSRetTypes(CallBase *CB, - ArrayRef ArgsFullTys) { + ArrayRef ArgsTys) { for (unsigned i = 0; i != CB->arg_size(); ++i) { for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet, Attribute::InAlloca}) { @@ -3865,7 +3813,7 @@ CB->removeParamAttr(i, Kind); - Type *PtrEltTy = getPointerElementFlatType(ArgsFullTys[i]); + Type *PtrEltTy = cast(ArgsTys[i])->getElementType(); Attribute NewAttr; switch (Kind) { case Attribute::ByVal: @@ -3901,11 +3849,11 @@ // Add all the function arguments to the value table. unsigned ArgNo = 0; - FunctionType *FullFTy = FunctionTypes[F]; + FunctionType *FTy = FunctionTypes[F]; for (Argument &I : F->args()) { - assert(I.getType() == flattenPointerTypes(FullFTy->getParamType(ArgNo)) && + assert(I.getType() == FTy->getParamType(ArgNo++) && "Incorrect fully specified type for Function Argument"); - ValueList.push_back(&I, FullFTy->getParamType(ArgNo++)); + ValueList.push_back(&I); } unsigned NextValueNo = ValueList.size(); BasicBlock *CurBB = nullptr; @@ -3978,7 +3926,6 @@ // Read a record. Record.clear(); Instruction *I = nullptr; - Type *FullTy = nullptr; Expected MaybeBitCode = Stream.readRecord(Entry.ID, Record); if (!MaybeBitCode) return MaybeBitCode.takeError(); @@ -4124,8 +4071,7 @@ OpNum+2 != Record.size()) return error("Invalid record"); - FullTy = getFullyStructuredTypeByID(Record[OpNum]); - Type *ResTy = flattenPointerTypes(FullTy); + Type *ResTy = getTypeByID(Record[OpNum]); int Opc = getDecodedCastOpcode(Record[OpNum + 1]); if (Opc == -1 || !ResTy) return error("Invalid record"); @@ -4155,25 +4101,24 @@ if (BitCode == bitc::FUNC_CODE_INST_GEP) { InBounds = Record[OpNum++]; - FullTy = getFullyStructuredTypeByID(Record[OpNum++]); - Ty = flattenPointerTypes(FullTy); + Ty = getTypeByID(Record[OpNum++]); } else { InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD; Ty = nullptr; } Value *BasePtr; - Type *FullBaseTy = nullptr; - if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr, &FullBaseTy)) + if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr)) return error("Invalid record"); if (!Ty) { - std::tie(FullTy, Ty) = - getPointerElementTypes(FullBaseTy->getScalarType()); - } else if (!cast(FullBaseTy->getScalarType()) - ->isOpaqueOrPointeeTypeMatches(Ty)) + Ty = cast(BasePtr->getType()->getScalarType()) + ->getElementType(); + } else if (!cast(BasePtr->getType()->getScalarType()) + ->isOpaqueOrPointeeTypeMatches(Ty)) { return error( "Explicit gep type does not match pointee type of pointer operand"); + } SmallVector GEPIdx; while (OpNum != Record.size()) { @@ -4184,7 +4129,6 @@ } I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx); - FullTy = GetElementPtrInst::getGEPReturnType(FullTy, I, GEPIdx); InstructionList.push_back(I); if (InBounds) @@ -4196,8 +4140,9 @@ // EXTRACTVAL: [opty, opval, n x indices] unsigned OpNum = 0; Value *Agg; - if (getValueTypePair(Record, OpNum, NextValueNo, Agg, &FullTy)) + if (getValueTypePair(Record, OpNum, NextValueNo, Agg)) return error("Invalid record"); + Type *Ty = Agg->getType(); unsigned RecSize = Record.size(); if (OpNum == RecSize) @@ -4205,24 +4150,24 @@ SmallVector EXTRACTVALIdx; for (; OpNum != RecSize; ++OpNum) { - bool IsArray = FullTy->isArrayTy(); - bool IsStruct = FullTy->isStructTy(); + bool IsArray = Ty->isArrayTy(); + bool IsStruct = Ty->isStructTy(); uint64_t Index = Record[OpNum]; if (!IsStruct && !IsArray) return error("EXTRACTVAL: Invalid type"); if ((unsigned)Index != Index) return error("Invalid value"); - if (IsStruct && Index >= FullTy->getStructNumElements()) + if (IsStruct && Index >= Ty->getStructNumElements()) return error("EXTRACTVAL: Invalid struct index"); - if (IsArray && Index >= FullTy->getArrayNumElements()) + if (IsArray && Index >= Ty->getArrayNumElements()) return error("EXTRACTVAL: Invalid array index"); EXTRACTVALIdx.push_back((unsigned)Index); if (IsStruct) - FullTy = FullTy->getStructElementType(Index); + Ty = Ty->getStructElementType(Index); else - FullTy = FullTy->getArrayElementType(); + Ty = Ty->getArrayElementType(); } I = ExtractValueInst::Create(Agg, EXTRACTVALIdx); @@ -4234,7 +4179,7 @@ // INSERTVAL: [opty, opval, opty, opval, n x indices] unsigned OpNum = 0; Value *Agg; - if (getValueTypePair(Record, OpNum, NextValueNo, Agg, &FullTy)) + if (getValueTypePair(Record, OpNum, NextValueNo, Agg)) return error("Invalid record"); Value *Val; if (getValueTypePair(Record, OpNum, NextValueNo, Val)) @@ -4280,7 +4225,7 @@ // handles select i1 ... in old bitcode unsigned OpNum = 0; Value *TrueVal, *FalseVal, *Cond; - if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, &FullTy) || + if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) || popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) || popValue(Record, OpNum, NextValueNo, Type::getInt1Ty(Context), Cond)) return error("Invalid record"); @@ -4295,7 +4240,7 @@ // handles select i1 or select [N x i1] unsigned OpNum = 0; Value *TrueVal, *FalseVal, *Cond; - if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, &FullTy) || + if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) || popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) || getValueTypePair(Record, OpNum, NextValueNo, Cond)) return error("Invalid record"); @@ -4325,13 +4270,12 @@ 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(FullTy)->getElementType(); InstructionList.push_back(I); break; } @@ -4339,7 +4283,7 @@ case bitc::FUNC_CODE_INST_INSERTELT: { // INSERTELT: [ty, opval,opval,opval] unsigned OpNum = 0; Value *Vec, *Elt, *Idx; - if (getValueTypePair(Record, OpNum, NextValueNo, Vec, &FullTy)) + if (getValueTypePair(Record, OpNum, NextValueNo, Vec)) return error("Invalid record"); if (!Vec->getType()->isVectorTy()) return error("Invalid type for value"); @@ -4355,7 +4299,7 @@ case bitc::FUNC_CODE_INST_SHUFFLEVEC: {// SHUFFLEVEC: [opval,ty,opval,opval] unsigned OpNum = 0; Value *Vec1, *Vec2, *Mask; - if (getValueTypePair(Record, OpNum, NextValueNo, Vec1, &FullTy) || + if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) || popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec2)) return error("Invalid record"); @@ -4365,9 +4309,6 @@ return error("Invalid type for value"); I = new ShuffleVectorInst(Vec1, Vec2, Mask); - FullTy = - VectorType::get(cast(FullTy)->getElementType(), - cast(Mask->getType())->getElementCount()); InstructionList.push_back(I); break; } @@ -4675,40 +4616,36 @@ BasicBlock *UnwindBB = getBasicBlock(Record[OpNum++]); FunctionType *FTy = nullptr; - FunctionType *FullFTy = nullptr; if ((CCInfo >> 13) & 1) { - FullFTy = - dyn_cast(getFullyStructuredTypeByID(Record[OpNum++])); - if (!FullFTy) + FTy = dyn_cast(getTypeByID(Record[OpNum++])); + if (!FTy) return error("Explicit invoke type is not a function type"); - FTy = cast(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(Callee->getType()); if (!CalleeTy) return error("Callee is not a pointer"); if (!FTy) { - FullFTy = - dyn_cast(cast(FullTy)->getElementType()); - if (!FullFTy) + FTy = dyn_cast( + cast(Callee->getType())->getElementType()); + if (!FTy) return error("Callee is not of pointer to function type"); - FTy = cast(flattenPointerTypes(FullFTy)); - } else if (getPointerElementFlatType(FullTy) != FTy) + } else if (cast(Callee->getType())->getElementType() != FTy) return error("Explicit invoke type does not match pointee type of " "callee operand"); if (Record.size() < FTy->getNumParams() + OpNum) return error("Insufficient operands to call"); SmallVector Ops; - SmallVector ArgsFullTys; + SmallVector ArgsTys; for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { Ops.push_back(getValue(Record, OpNum, NextValueNo, FTy->getParamType(i))); - ArgsFullTys.push_back(FullFTy->getParamType(i)); + ArgsTys.push_back(FTy->getParamType(i)); if (!Ops.back()) return error("Invalid record"); } @@ -4720,23 +4657,21 @@ // 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(I)->setCallingConv( static_cast(CallingConv::MaxID & CCInfo)); cast(I)->setAttributes(PAL); - propagateByValSRetTypes(cast(I), ArgsFullTys); + propagateByValSRetTypes(cast(I), ArgsTys); break; } @@ -4762,29 +4697,25 @@ IndirectDests.push_back(getBasicBlock(Record[OpNum++])); FunctionType *FTy = nullptr; - FunctionType *FullFTy = nullptr; if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) { - FullFTy = - dyn_cast(getFullyStructuredTypeByID(Record[OpNum++])); - if (!FullFTy) + FTy = dyn_cast(getTypeByID(Record[OpNum++])); + if (!FTy) return error("Explicit call type is not a function type"); - FTy = cast(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(Callee->getType()); if (!OpTy) return error("Callee is not a pointer type"); if (!FTy) { - FullFTy = - dyn_cast(cast(FullTy)->getElementType()); - if (!FullFTy) + FTy = dyn_cast( + cast(Callee->getType())->getElementType()); + if (!FTy) return error("Callee is not of pointer to function type"); - FTy = cast(flattenPointerTypes(FullFTy)); - } else if (getPointerElementFlatType(FullTy) != FTy) + } else if (cast(Callee->getType())->getElementType() != FTy) return error("Explicit call type does not match pointee type of " "callee operand"); if (Record.size() < FTy->getNumParams() + OpNum) @@ -4817,7 +4748,6 @@ I = CallBrInst::Create(FTy, Callee, DefaultDest, IndirectDests, Args, OperandBundles); - FullTy = FullFTy->getReturnType(); OperandBundles.clear(); InstructionList.push_back(I); cast(I)->setCallingConv( @@ -4833,8 +4763,7 @@ if (Record.empty()) return error("Invalid record"); // The first record specifies the type. - FullTy = getFullyStructuredTypeByID(Record[0]); - Type *Ty = flattenPointerTypes(FullTy); + Type *Ty = getTypeByID(Record[0]); if (!Ty) return error("Invalid record"); @@ -4886,8 +4815,7 @@ if (Record.size() < 4) return error("Invalid record"); } - FullTy = getFullyStructuredTypeByID(Record[Idx++]); - Type *Ty = flattenPointerTypes(FullTy); + Type *Ty = getTypeByID(Record[Idx++]); if (!Ty) return error("Invalid record"); if (BitCode == bitc::FUNC_CODE_INST_LANDINGPAD_OLD) { @@ -4936,13 +4864,12 @@ const uint64_t Rec = Record[3]; const bool InAlloca = Bitfield::get(Rec); const bool SwiftError = Bitfield::get(Rec); - FullTy = getFullyStructuredTypeByID(Record[0]); - Type *Ty = flattenPointerTypes(FullTy); + Type *Ty = getTypeByID(Record[0]); if (!Bitfield::get(Rec)) { auto *PTy = dyn_cast_or_null(Ty); if (!PTy) return error("Old-style alloca with a non-pointer type"); - std::tie(FullTy, Ty) = getPointerElementTypes(FullTy); + Ty = PTy->getElementType(); } Type *OpTy = getTypeByID(Record[1]); Value *Size = getFnValueByID(Record[2], OpTy); @@ -4968,14 +4895,13 @@ AI->setUsedWithInAlloca(InAlloca); AI->setSwiftError(SwiftError); I = AI; - FullTy = PointerType::get(FullTy, AS); InstructionList.push_back(I); break; } case bitc::FUNC_CODE_INST_LOAD: { // LOAD: [opty, op, align, vol] unsigned OpNum = 0; Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy) || + if (getValueTypePair(Record, OpNum, NextValueNo, Op) || (OpNum + 2 != Record.size() && OpNum + 3 != Record.size())) return error("Invalid record"); @@ -4984,10 +4910,10 @@ 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(Op->getType())->getElementType(); + } if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType())) return Err; @@ -5008,7 +4934,7 @@ // LOADATOMIC: [opty, op, align, vol, ordering, ssid] unsigned OpNum = 0; Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy) || + if (getValueTypePair(Record, OpNum, NextValueNo, Op) || (OpNum + 4 != Record.size() && OpNum + 5 != Record.size())) return error("Invalid record"); @@ -5017,10 +4943,10 @@ 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(Op->getType())->getElementType(); + } if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType())) return Err; @@ -5047,12 +4973,12 @@ 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(Ptr->getType())->getElementType(), + Val)) || OpNum + 2 != Record.size()) return error("Invalid record"); @@ -5075,13 +5001,13 @@ // 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(Ptr->getType()) || (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC ? getValueTypePair(Record, OpNum, NextValueNo, Val) : popValue(Record, OpNum, NextValueNo, - getPointerElementFlatType(FullTy), Val)) || + cast(Ptr->getType())->getElementType(), + Val)) || OpNum + 4 != Record.size()) return error("Invalid record"); @@ -5111,7 +5037,7 @@ 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(Ptr->getType())) @@ -5119,11 +5045,10 @@ Value *Cmp = nullptr; if (popValue(Record, OpNum, NextValueNo, - getPointerElementFlatType(FullTy), Cmp)) + cast(Ptr->getType())->getPointerElementType(), + Cmp)) return error("Invalid record"); - FullTy = cast(FullTy)->getElementType(); - Value *New = nullptr; if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) || NumRecords < OpNum + 3 || NumRecords > OpNum + 5) @@ -5155,7 +5080,6 @@ I = new AtomicCmpXchgInst(Ptr, Cmp, New, Alignment, SuccessOrdering, FailureOrdering, SSID); cast(I)->setVolatile(Record[OpNum]); - FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)}); if (NumRecords < 8) { // Before weak cmpxchgs existed, the instruction simply returned the @@ -5163,7 +5087,6 @@ // expecting the first component of a modern cmpxchg. CurBB->getInstList().push_back(I); I = ExtractValueInst::Create(I, 0); - FullTy = cast(FullTy)->getElementType(0); } else { cast(I)->setWeak(Record[OpNum + 4]); } @@ -5177,14 +5100,14 @@ 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(Ptr->getType())) return error("Cmpxchg operand is not a pointer type"); Value *Cmp = nullptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Cmp, &FullTy)) + if (getValueTypePair(Record, OpNum, NextValueNo, Cmp)) return error("Invalid record"); Value *Val = nullptr; @@ -5225,7 +5148,6 @@ I = new AtomicCmpXchgInst(Ptr, Cmp, Val, *Alignment, SuccessOrdering, FailureOrdering, SSID); - FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)}); cast(I)->setVolatile(IsVol); cast(I)->setWeak(IsWeak); @@ -5240,7 +5162,7 @@ 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(Ptr->getType())) @@ -5249,13 +5171,12 @@ Value *Val = nullptr; if (BitCode == bitc::FUNC_CODE_INST_ATOMICRMW_OLD) { if (popValue(Record, OpNum, NextValueNo, - getPointerElementFlatType(FullTy), Val)) + cast(Ptr->getType())->getPointerElementType(), + Val)) return error("Invalid record"); - FullTy = getPointerElementFlatType(FullTy); } else { if (getValueTypePair(Record, OpNum, NextValueNo, Val)) return error("Invalid record"); - FullTy = Val->getType(); } if (!(NumRecords == (OpNum + 4) || NumRecords == (OpNum + 5))) @@ -5323,36 +5244,32 @@ } FunctionType *FTy = nullptr; - FunctionType *FullFTy = nullptr; if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) { - FullFTy = - dyn_cast(getFullyStructuredTypeByID(Record[OpNum++])); - if (!FullFTy) + FTy = dyn_cast(getTypeByID(Record[OpNum++])); + if (!FTy) return error("Explicit call type is not a function type"); - FTy = cast(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(Callee->getType()); if (!OpTy) return error("Callee is not a pointer type"); if (!FTy) { - FullFTy = - dyn_cast(cast(FullTy)->getElementType()); - if (!FullFTy) + FTy = dyn_cast( + cast(Callee->getType())->getElementType()); + if (!FTy) return error("Callee is not of pointer to function type"); - FTy = cast(flattenPointerTypes(FullFTy)); - } else if (getPointerElementFlatType(FullTy) != FTy) + } else if (cast(Callee->getType())->getElementType() != FTy) return error("Explicit call type does not match pointee type of " "callee operand"); if (Record.size() < FTy->getNumParams() + OpNum) return error("Insufficient operands to call"); SmallVector Args; - SmallVector ArgsFullTys; + SmallVector ArgsTys; // Read the fixed params. for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { if (FTy->getParamType(i)->isLabelTy()) @@ -5360,7 +5277,7 @@ else Args.push_back(getValue(Record, OpNum, NextValueNo, FTy->getParamType(i))); - ArgsFullTys.push_back(FullFTy->getParamType(i)); + ArgsTys.push_back(FTy->getParamType(i)); if (!Args.back()) return error("Invalid record"); } @@ -5372,16 +5289,14 @@ } 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(I)->setCallingConv( @@ -5395,7 +5310,7 @@ TCK = CallInst::TCK_NoTail; cast(I)->setTailCallKind(TCK); cast(I)->setAttributes(PAL); - propagateByValSRetTypes(cast(I), ArgsFullTys); + propagateByValSRetTypes(cast(I), ArgsTys); if (FMF.any()) { if (!isa(I)) return error("Fast-math-flags specified for call without " @@ -5409,8 +5324,7 @@ return error("Invalid record"); Type *OpTy = getTypeByID(Record[0]); Value *Op = getValue(Record, 1, NextValueNo, OpTy); - FullTy = getFullyStructuredTypeByID(Record[2]); - Type *ResTy = flattenPointerTypes(FullTy); + Type *ResTy = getTypeByID(Record[2]); if (!OpTy || !Op || !ResTy) return error("Invalid record"); I = new VAArgInst(Op, ResTy); @@ -5443,7 +5357,7 @@ case bitc::FUNC_CODE_INST_FREEZE: { // FREEZE: [opty,opval] unsigned OpNum = 0; Value *Op = nullptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy)) + if (getValueTypePair(Record, OpNum, NextValueNo, Op)) return error("Invalid record"); if (OpNum != Record.size()) return error("Invalid record"); @@ -5473,23 +5387,8 @@ } // 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(FullTy) && - !isa(FullTy) && - (!isa(FullTy) || - cast(FullTy)->getElementType()->isFloatingPointTy() || - cast(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: diff --git a/llvm/lib/Bitcode/Reader/ValueList.h b/llvm/lib/Bitcode/Reader/ValueList.h --- a/llvm/lib/Bitcode/Reader/ValueList.h +++ b/llvm/lib/Bitcode/Reader/ValueList.h @@ -28,13 +28,6 @@ class BitcodeReaderValueList { std::vector ValuePtrs; - /// Struct containing fully-specified copies of the type of each - /// value. When pointers are opaque, this will be contain non-opaque - /// variants so that restructuring instructions can determine their - /// type correctly even if being loaded from old bitcode where some - /// types are implicit. - std::vector FullTypes; - /// As we resolve forward-referenced constants, we add information about them /// to this vector. This allows us to resolve them in bulk instead of /// resolving each reference at a time. See the code in @@ -64,17 +57,12 @@ unsigned size() const { return ValuePtrs.size(); } void resize(unsigned N) { ValuePtrs.resize(N); - FullTypes.resize(N); - } - void push_back(Value *V, Type *Ty) { - ValuePtrs.emplace_back(V); - FullTypes.emplace_back(Ty); } + void push_back(Value *V) { ValuePtrs.emplace_back(V); } void clear() { assert(ResolveConstants.empty() && "Constants not resolved?"); ValuePtrs.clear(); - FullTypes.clear(); } Value *operator[](unsigned i) const { @@ -85,20 +73,18 @@ Value *back() const { return ValuePtrs.back(); } void pop_back() { ValuePtrs.pop_back(); - FullTypes.pop_back(); } bool empty() const { return ValuePtrs.empty(); } void shrinkTo(unsigned N) { assert(N <= size() && "Invalid shrinkTo request!"); ValuePtrs.resize(N); - FullTypes.resize(N); } Constant *getConstantFwdRef(unsigned Idx, Type *Ty); - Value *getValueFwdRef(unsigned Idx, Type *Ty, Type **FullTy = nullptr); + Value *getValueFwdRef(unsigned Idx, Type *Ty); - void assignValue(Value *V, unsigned Idx, Type *FullTy); + void assignValue(Value *V, unsigned Idx); /// Once all constants are read, this method bulk resolves any forward /// references. diff --git a/llvm/lib/Bitcode/Reader/ValueList.cpp b/llvm/lib/Bitcode/Reader/ValueList.cpp --- a/llvm/lib/Bitcode/Reader/ValueList.cpp +++ b/llvm/lib/Bitcode/Reader/ValueList.cpp @@ -62,18 +62,15 @@ } // end namespace llvm -void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx, Type *FullTy) { +void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) { if (Idx == size()) { - push_back(V, FullTy); + push_back(V); return; } if (Idx >= size()) resize(Idx + 1); - assert(FullTypes[Idx] == nullptr || FullTypes[Idx] == FullTy); - FullTypes[Idx] = FullTy; - WeakTrackingVH &OldV = ValuePtrs[Idx]; if (!OldV) { OldV = V; @@ -102,8 +99,12 @@ resize(Idx + 1); if (Value *V = ValuePtrs[Idx]) { - if (Ty != V->getType()) + if (Ty != V->getType()) { + Ty->dump(); + V->getType()->dump(); + V->dump(); report_fatal_error("Type mismatch in constant table!"); + } return cast(V); } @@ -113,8 +114,7 @@ return C; } -Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty, - Type **FullTy) { +Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) { // Bail out for a clearly invalid value. if (Idx >= RefsUpperBound) return nullptr; @@ -126,8 +126,6 @@ // If the types don't match, it's invalid. if (Ty && Ty != V->getType()) return nullptr; - if (FullTy) - *FullTy = FullTypes[Idx]; return V; }