diff options
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 137 |
1 files changed, 65 insertions, 72 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index f014521264c1..3797a44c1793 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -17,13 +17,13 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" #include "llvm/Bitcode/BitcodeCommon.h" #include "llvm/Bitcode/LLVMBitCodes.h" #include "llvm/Bitstream/BitstreamReader.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/Argument.h" +#include "llvm/IR/AttributeMask.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/BasicBlock.h" @@ -72,6 +72,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/ModRef.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/Triple.h" #include <algorithm> #include <cassert> #include <cstddef> @@ -1355,13 +1356,7 @@ Type *BitcodeReader::getPtrElementTypeByID(unsigned ID) { if (!Ty->isPointerTy()) return nullptr; - Type *ElemTy = getTypeByID(getContainedTypeID(ID, 0)); - if (!ElemTy) - return nullptr; - - assert(cast<PointerType>(Ty)->isOpaqueOrPointeeTypeMatches(ElemTy) && - "Incorrect element type"); - return ElemTy; + return getTypeByID(getContainedTypeID(ID, 0)); } unsigned BitcodeReader::getVirtualTypeID(Type *Ty, @@ -1380,17 +1375,6 @@ unsigned BitcodeReader::getVirtualTypeID(Type *Ty, return It->second; } -#ifndef NDEBUG - if (!Ty->isOpaquePointerTy()) { - assert(Ty->getNumContainedTypes() == ChildTypeIDs.size() && - "Wrong number of contained types"); - for (auto Pair : zip(Ty->subtypes(), ChildTypeIDs)) { - assert(std::get<0>(Pair) == getTypeByID(std::get<1>(Pair)) && - "Incorrect contained type ID"); - } - } -#endif - unsigned TypeID = TypeList.size(); TypeList.push_back(Ty); if (!ChildTypeIDs.empty()) @@ -1399,7 +1383,9 @@ unsigned BitcodeReader::getVirtualTypeID(Type *Ty, return TypeID; } -static bool isConstExprSupported(uint8_t Opcode) { +static bool isConstExprSupported(const BitcodeConstant *BC) { + uint8_t Opcode = BC->Opcode; + // These are not real constant expressions, always consider them supported. if (Opcode >= BitcodeConstant::FirstSpecialOpcode) return true; @@ -1412,7 +1398,16 @@ static bool isConstExprSupported(uint8_t Opcode) { if (Instruction::isBinaryOp(Opcode)) return ConstantExpr::isSupportedBinOp(Opcode); - return Opcode != Instruction::FNeg; + if (Opcode == Instruction::GetElementPtr) + return ConstantExpr::isSupportedGetElementPtr(BC->SrcElemTy); + + switch (Opcode) { + case Instruction::FNeg: + case Instruction::Select: + return false; + default: + return true; + } } Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, @@ -1467,7 +1462,7 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, ConstOps.push_back(C); // Materialize as constant expression if possible. - if (isConstExprSupported(BC->Opcode) && ConstOps.size() == Ops.size()) { + if (isConstExprSupported(BC) && ConstOps.size() == Ops.size()) { Constant *C; if (Instruction::isCast(BC->Opcode)) { C = UpgradeBitCastExpr(BC->Opcode, ConstOps[0], BC->getType()); @@ -1544,9 +1539,6 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, ArrayRef(ConstOps).drop_front(), BC->Flags, BC->getInRangeIndex()); break; - case Instruction::Select: - C = ConstantExpr::getSelect(ConstOps[0], ConstOps[1], ConstOps[2]); - break; case Instruction::ExtractElement: C = ConstantExpr::getExtractElement(ConstOps[0], ConstOps[1]); break; @@ -1928,6 +1920,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::JumpTable; case bitc::ATTR_KIND_MEMORY: return Attribute::Memory; + case bitc::ATTR_KIND_NOFPCLASS: + return Attribute::NoFPClass; case bitc::ATTR_KIND_MIN_SIZE: return Attribute::MinSize; case bitc::ATTR_KIND_NAKED: @@ -2205,6 +2199,9 @@ Error BitcodeReader::parseAttributeGroupBlock() { B.addAllocKindAttr(static_cast<AllocFnKind>(Record[++i])); else if (Kind == Attribute::Memory) B.addMemoryAttr(MemoryEffects::createFromIntValue(Record[++i])); + else if (Kind == Attribute::NoFPClass) + B.addNoFPClassAttr( + static_cast<FPClassTest>(Record[++i] & fcAllFlags)); } else if (Record[i] == 3 || Record[i] == 4) { // String attribute bool HasValue = (Record[i++] == 4); SmallString<64> KindStr; @@ -2369,9 +2366,6 @@ Error BitcodeReader::parseTypeTableBody() { case bitc::TYPE_CODE_OPAQUE_POINTER: { // OPAQUE_POINTER: [addrspace] if (Record.size() != 1) return error("Invalid opaque pointer record"); - if (Context.supportsTypedPointers()) - return error( - "Opaque pointers are only supported in -opaque-pointers mode"); unsigned AddressSpace = Record[0]; ResultTy = PointerType::get(Context, AddressSpace); break; @@ -3273,9 +3267,7 @@ Error BitcodeReader::parseConstants() { PointeeType = getPtrElementTypeByID(BaseTypeID); if (!PointeeType) return error("Missing element type for old-style constant GEP"); - } else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType)) - return error("Explicit gep operator type does not match pointee type " - "of pointer operand"); + } V = BitcodeConstant::create(Alloc, CurTy, {Instruction::GetElementPtr, InBounds, @@ -3693,7 +3685,7 @@ Error BitcodeReader::globalCleanup() { UpgradedVariables.emplace_back(&GV, Upgraded); for (auto &Pair : UpgradedVariables) { Pair.first->eraseFromParent(); - TheModule->getGlobalList().push_back(Pair.second); + TheModule->insertGlobalVariable(Pair.second); } // Force deallocation of memory for these vectors to favor the client that @@ -3868,7 +3860,8 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { GlobalVariable *NewGV = new GlobalVariable(*TheModule, Ty, isConstant, Linkage, nullptr, Name, nullptr, TLM, AddressSpace, ExternallyInitialized); - NewGV->setAlignment(Alignment); + if (Alignment) + NewGV->setAlignment(*Alignment); if (!Section.empty()) NewGV->setSection(Section); NewGV->setVisibility(Visibility); @@ -4027,7 +4020,8 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { MaybeAlign Alignment; if (Error Err = parseAlignmentValue(Record[5], Alignment)) return Err; - Func->setAlignment(Alignment); + if (Alignment) + Func->setAlignment(*Alignment); if (Record[6]) { if (Record[6] - 1 >= SectionTable.size()) return error("Invalid ID"); @@ -4513,10 +4507,6 @@ 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"); - - if (!cast<PointerType>(PtrType)->isOpaqueOrPointeeTypeMatches(ValType)) - return error("Explicit load/store type does not match pointee " - "type of pointer operand"); if (!PointerType::isLoadableOrStorableType(ValType)) return error("Cannot load/store from pointer"); return Error::success(); @@ -4943,10 +4933,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (BasePtr->getType()->isVectorTy()) TyID = getContainedTypeID(TyID); Ty = getTypeByID(TyID); - } 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; @@ -5537,9 +5523,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID)); if (!FTy) return error("Callee is not of pointer to function type"); - } 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"); @@ -5633,9 +5617,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID)); if (!FTy) return error("Callee is not of pointer to function type"); - } 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"); @@ -6343,9 +6325,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID)); if (!FTy) return error("Callee is not of pointer to function type"); - } 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"); @@ -8017,14 +7997,17 @@ Expected<std::unique_ptr<ModuleSummaryIndex>> BitcodeModule::getSummary() { return std::move(Index); } -static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, - unsigned ID) { +static Expected<std::pair<bool, bool>> +getEnableSplitLTOUnitAndUnifiedFlag(BitstreamCursor &Stream, + unsigned ID, + BitcodeLTOInfo <OInfo) { if (Error Err = Stream.EnterSubBlock(ID)) return std::move(Err); SmallVector<uint64_t, 64> Record; while (true) { BitstreamEntry Entry; + std::pair<bool, bool> Result = {false,false}; if (Error E = Stream.advanceSkippingSubblocks().moveInto(Entry)) return std::move(E); @@ -8032,10 +8015,10 @@ static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: return error("Malformed block"); - case BitstreamEntry::EndBlock: - // If no flags record found, conservatively return true to mimic - // behavior before this flag was added. - return true; + case BitstreamEntry::EndBlock: { + // If no flags record found, set both flags to false. + return Result; + } case BitstreamEntry::Record: // The interesting case. break; @@ -8052,9 +8035,13 @@ static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, case bitc::FS_FLAGS: { // [flags] uint64_t Flags = Record[0]; // Scan flags. - assert(Flags <= 0xff && "Unexpected bits in flag"); + assert(Flags <= 0x2ff && "Unexpected bits in flag"); + + bool EnableSplitLTOUnit = Flags & 0x8; + bool UnifiedLTO = Flags & 0x200; + Result = {EnableSplitLTOUnit, UnifiedLTO}; - return Flags & 0x8; + return Result; } } } @@ -8080,25 +8067,31 @@ Expected<BitcodeLTOInfo> BitcodeModule::getLTOInfo() { return error("Malformed block"); case BitstreamEntry::EndBlock: return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/false, - /*EnableSplitLTOUnit=*/false}; + /*EnableSplitLTOUnit=*/false, /*UnifiedLTO=*/false}; case BitstreamEntry::SubBlock: if (Entry.ID == bitc::GLOBALVAL_SUMMARY_BLOCK_ID) { - Expected<bool> EnableSplitLTOUnit = - getEnableSplitLTOUnitFlag(Stream, Entry.ID); - if (!EnableSplitLTOUnit) - return EnableSplitLTOUnit.takeError(); - return BitcodeLTOInfo{/*IsThinLTO=*/true, /*HasSummary=*/true, - *EnableSplitLTOUnit}; + BitcodeLTOInfo LTOInfo; + Expected<std::pair<bool, bool>> Flags = + getEnableSplitLTOUnitAndUnifiedFlag(Stream, Entry.ID, LTOInfo); + if (!Flags) + return Flags.takeError(); + std::tie(LTOInfo.EnableSplitLTOUnit, LTOInfo.UnifiedLTO) = Flags.get(); + LTOInfo.IsThinLTO = true; + LTOInfo.HasSummary = true; + return LTOInfo; } if (Entry.ID == bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID) { - Expected<bool> EnableSplitLTOUnit = - getEnableSplitLTOUnitFlag(Stream, Entry.ID); - if (!EnableSplitLTOUnit) - return EnableSplitLTOUnit.takeError(); - return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/true, - *EnableSplitLTOUnit}; + BitcodeLTOInfo LTOInfo; + Expected<std::pair<bool, bool>> Flags = + getEnableSplitLTOUnitAndUnifiedFlag(Stream, Entry.ID, LTOInfo); + if (!Flags) + return Flags.takeError(); + std::tie(LTOInfo.EnableSplitLTOUnit, LTOInfo.UnifiedLTO) = Flags.get(); + LTOInfo.IsThinLTO = false; + LTOInfo.HasSummary = true; + return LTOInfo; } // Ignore other sub-blocks. |