diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-18 20:30:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-06 20:11:55 +0000 |
commit | 5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch) | |
tree | 1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp | |
parent | 3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff) | |
parent | 312c0ed19cc5276a17bacf2120097bec4515b0f1 (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 | 156 |
1 files changed, 112 insertions, 44 deletions
diff --git a/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 3797a44c1793..8907f6fa4ff3 100644 --- a/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -904,10 +904,6 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase { /// path to the bitcode file. StringRef ModulePath; - /// For per-module summary indexes, the unique numerical identifier given to - /// this module by the client. - unsigned ModuleId; - /// Callback to ask whether a symbol is the prevailing copy when invoked /// during combined index building. std::function<bool(GlobalValue::GUID)> IsPrevailing; @@ -919,7 +915,7 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase { public: ModuleSummaryIndexBitcodeReader( BitstreamCursor Stream, StringRef Strtab, ModuleSummaryIndex &TheIndex, - StringRef ModulePath, unsigned ModuleId, + StringRef ModulePath, std::function<bool(GlobalValue::GUID)> IsPrevailing = nullptr); Error parseModule(); @@ -1121,6 +1117,22 @@ static GlobalVarSummary::GVarFlags getDecodedGVarFlags(uint64_t RawFlags) { (GlobalObject::VCallVisibility)(RawFlags >> 3)); } +static std::pair<CalleeInfo::HotnessType, bool> +getDecodedHotnessCallEdgeInfo(uint64_t RawFlags) { + CalleeInfo::HotnessType Hotness = + static_cast<CalleeInfo::HotnessType>(RawFlags & 0x7); // 3 bits + bool HasTailCall = (RawFlags & 0x8); // 1 bit + return {Hotness, HasTailCall}; +} + +static void getDecodedRelBFCallEdgeInfo(uint64_t RawFlags, uint64_t &RelBF, + bool &HasTailCall) { + static constexpr uint64_t RelBlockFreqMask = + (1 << CalleeInfo::RelBlockFreqBits) - 1; + RelBF = RawFlags & RelBlockFreqMask; // RelBlockFreqBits bits + HasTailCall = (RawFlags & (1 << CalleeInfo::RelBlockFreqBits)); // 1 bit +} + static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) { switch (Val) { default: // Map unknown visibilities to default. @@ -1148,6 +1160,23 @@ static bool getDecodedDSOLocal(unsigned Val) { } } +static std::optional<CodeModel::Model> getDecodedCodeModel(unsigned Val) { + switch (Val) { + case 1: + return CodeModel::Tiny; + case 2: + return CodeModel::Small; + case 3: + return CodeModel::Kernel; + case 4: + return CodeModel::Medium; + case 5: + return CodeModel::Large; + } + + return {}; +} + static GlobalVariable::ThreadLocalMode getDecodedThreadLocalMode(unsigned Val) { switch (Val) { case 0: return GlobalVariable::NotThreadLocal; @@ -1398,6 +1427,9 @@ static bool isConstExprSupported(const BitcodeConstant *BC) { if (Instruction::isBinaryOp(Opcode)) return ConstantExpr::isSupportedBinOp(Opcode); + if (Instruction::isCast(Opcode)) + return ConstantExpr::isSupportedCastOp(Opcode); + if (Opcode == Instruction::GetElementPtr) return ConstantExpr::isSupportedGetElementPtr(BC->SrcElemTy); @@ -1984,6 +2016,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::NoSanitizeCoverage; case bitc::ATTR_KIND_NULL_POINTER_IS_VALID: return Attribute::NullPointerIsValid; + case bitc::ATTR_KIND_OPTIMIZE_FOR_DEBUGGING: + return Attribute::OptimizeForDebugging; case bitc::ATTR_KIND_OPT_FOR_FUZZING: return Attribute::OptForFuzzing; case bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE: @@ -2060,6 +2094,12 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::Hot; case bitc::ATTR_KIND_PRESPLIT_COROUTINE: return Attribute::PresplitCoroutine; + case bitc::ATTR_KIND_WRITABLE: + return Attribute::Writable; + case bitc::ATTR_KIND_CORO_ONLY_DESTROY_WHEN_COMPLETE: + return Attribute::CoroDestroyOnlyWhenComplete; + case bitc::ATTR_KIND_DEAD_ON_UNWIND: + return Attribute::DeadOnUnwind; } } @@ -2648,7 +2688,7 @@ Expected<Value *> BitcodeReader::recordValue(SmallVectorImpl<uint64_t> &Record, Value *V = ValueList[ValueID]; StringRef NameStr(ValueName.data(), ValueName.size()); - if (NameStr.find_first_of(0) != StringRef::npos) + if (NameStr.contains(0)) return error("Invalid value name"); V->setName(NameStr); auto *GO = dyn_cast<GlobalObject>(V); @@ -2894,11 +2934,7 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() { return error("Alias and aliasee types don't match"); GA->setAliasee(C); } else if (auto *GI = dyn_cast<GlobalIFunc>(GV)) { - Type *ResolverFTy = - GlobalIFunc::getResolverFunctionType(GI->getValueType()); - // Transparently fix up the type for compatibility with older bitcode - GI->setResolver(ConstantExpr::getBitCast( - C, ResolverFTy->getPointerTo(GI->getAddressSpace()))); + GI->setResolver(C); } else { return error("Expected an alias or an ifunc"); } @@ -3196,7 +3232,7 @@ Error BitcodeReader::parseConstants() { Opc == Instruction::LShr || Opc == Instruction::AShr) { if (Record[3] & (1 << bitc::PEO_EXACT)) - Flags |= SDivOperator::IsExact; + Flags |= PossiblyExactOperator::IsExact; } } V = BitcodeConstant::create(Alloc, CurTy, {(uint8_t)Opc, Flags}, @@ -3804,6 +3840,7 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { // dllstorageclass, comdat, attributes, preemption specifier, // partition strtab offset, partition strtab size] (name in VST) // v2: [strtab_offset, strtab_size, v1] + // v3: [v2, code_model] StringRef Name; std::tie(Name, Record) = readNameFromStrtab(Record); @@ -3912,6 +3949,13 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { NewGV->setSanitizerMetadata(Meta); } + if (Record.size() > 17 && Record[17]) { + if (auto CM = getDecodedCodeModel(Record[17])) + NewGV->setCodeModel(*CM); + else + return error("Invalid global variable code model"); + } + return Error::success(); } @@ -4865,12 +4909,14 @@ Error BitcodeReader::parseFunctionBody(Function *F) { Opc == Instruction::AShr) { if (Record[OpNum] & (1 << bitc::PEO_EXACT)) cast<BinaryOperator>(I)->setIsExact(true); + } else if (Opc == Instruction::Or) { + if (Record[OpNum] & (1 << bitc::PDI_DISJOINT)) + cast<PossiblyDisjointInst>(I)->setIsDisjoint(true); } else if (isa<FPMathOperator>(I)) { FastMathFlags FMF = getDecodedFastMathFlags(Record[OpNum]); if (FMF.any()) I->setFastMathFlags(FMF); } - } break; } @@ -4879,12 +4925,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) { Value *Op; unsigned OpTypeID; if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB) || - OpNum+2 != Record.size()) + OpNum + 1 > Record.size()) return error("Invalid record"); - ResTypeID = Record[OpNum]; + ResTypeID = Record[OpNum++]; Type *ResTy = getTypeByID(ResTypeID); - int Opc = getDecodedCastOpcode(Record[OpNum + 1]); + int Opc = getDecodedCastOpcode(Record[OpNum++]); + if (Opc == -1 || !ResTy) return error("Invalid record"); Instruction *Temp = nullptr; @@ -4900,6 +4947,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("Invalid cast"); I = CastInst::Create(CastOp, Op, ResTy); } + if (OpNum < Record.size() && isa<PossiblyNonNegInst>(I) && + (Record[OpNum] & (1 << bitc::PNNI_NON_NEG))) + I->setNonNeg(true); InstructionList.push_back(I); break; } @@ -5200,7 +5250,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error( "Invalid record: operand number exceeded available operands"); - unsigned PredVal = Record[OpNum]; + CmpInst::Predicate PredVal = CmpInst::Predicate(Record[OpNum]); bool IsFP = LHS->getType()->isFPOrFPVectorTy(); FastMathFlags FMF; if (IsFP && Record.size() > OpNum+1) @@ -5209,10 +5259,15 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (OpNum+1 != Record.size()) return error("Invalid record"); - if (LHS->getType()->isFPOrFPVectorTy()) - I = new FCmpInst((FCmpInst::Predicate)PredVal, LHS, RHS); - else - I = new ICmpInst((ICmpInst::Predicate)PredVal, LHS, RHS); + if (IsFP) { + if (!CmpInst::isFPPredicate(PredVal)) + return error("Invalid fcmp predicate"); + I = new FCmpInst(PredVal, LHS, RHS); + } else { + if (!CmpInst::isIntPredicate(PredVal)) + return error("Invalid icmp predicate"); + I = new ICmpInst(PredVal, LHS, RHS); + } ResTypeID = getVirtualTypeID(I->getType()->getScalarType()); if (LHS->getType()->isVectorTy()) @@ -5315,6 +5370,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { Type *TokenTy = Type::getTokenTy(Context); Value *ParentPad = getValue(Record, Idx++, NextValueNo, TokenTy, getVirtualTypeID(TokenTy), CurBB); + if (!ParentPad) + return error("Invalid record"); unsigned NumHandlers = Record[Idx++]; @@ -5356,6 +5413,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { Type *TokenTy = Type::getTokenTy(Context); Value *ParentPad = getValue(Record, Idx++, NextValueNo, TokenTy, getVirtualTypeID(TokenTy), CurBB); + if (!ParentPad) + return error("Invald record"); unsigned NumArgOperands = Record[Idx++]; @@ -5910,6 +5969,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (!Align) Align = DL.getPrefTypeAlign(Ty); + if (!Size->getType()->isIntegerTy()) + return error("alloca element count must have integer type"); + AllocaInst *AI = new AllocaInst(Ty, AS, Size, *Align); AI->setUsedWithInAlloca(InAlloca); AI->setSwiftError(SwiftError); @@ -5936,10 +5998,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } else { ResTypeID = getContainedTypeID(OpTypeID); Ty = getTypeByID(ResTypeID); - if (!Ty) - return error("Missing element type for old-style load"); } + if (!Ty) + return error("Missing load type"); + if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType())) return Err; @@ -5974,10 +6037,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } else { ResTypeID = getContainedTypeID(OpTypeID); Ty = getTypeByID(ResTypeID); - if (!Ty) - return error("Missing element type for old style atomic load"); } + if (!Ty) + return error("Missing atomic load type"); + if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType())) return Err; @@ -6370,7 +6434,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { cast<CallInst>(I)->setCallingConv( static_cast<CallingConv::ID>((0x7ff & CCInfo) >> bitc::CALL_CCONV)); CallInst::TailCallKind TCK = CallInst::TCK_None; - if (CCInfo & 1 << bitc::CALL_TAIL) + if (CCInfo & (1 << bitc::CALL_TAIL)) TCK = CallInst::TCK_Tail; if (CCInfo & (1 << bitc::CALL_MUSTTAIL)) TCK = CallInst::TCK_MustTail; @@ -6699,13 +6763,12 @@ std::vector<StructType *> BitcodeReader::getIdentifiedStructTypes() const { ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader( BitstreamCursor Cursor, StringRef Strtab, ModuleSummaryIndex &TheIndex, - StringRef ModulePath, unsigned ModuleId, - std::function<bool(GlobalValue::GUID)> IsPrevailing) + StringRef ModulePath, std::function<bool(GlobalValue::GUID)> IsPrevailing) : BitcodeReaderBase(std::move(Cursor), Strtab), TheIndex(TheIndex), - ModulePath(ModulePath), ModuleId(ModuleId), IsPrevailing(IsPrevailing) {} + ModulePath(ModulePath), IsPrevailing(IsPrevailing) {} void ModuleSummaryIndexBitcodeReader::addThisModule() { - TheIndex.addModule(ModulePath, ModuleId); + TheIndex.addModule(ModulePath); } ModuleSummaryIndex::ModuleInfo * @@ -6936,7 +6999,7 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { case bitc::MODULE_CODE_HASH: { if (Record.size() != 5) return error("Invalid hash length " + Twine(Record.size()).str()); - auto &Hash = getThisModule()->second.second; + auto &Hash = getThisModule()->second; int Pos = 0; for (auto &Val : Record) { assert(!(Val >> 32) && "Unexpected high bits set"); @@ -6999,6 +7062,7 @@ ModuleSummaryIndexBitcodeReader::makeCallList(ArrayRef<uint64_t> Record, Ret.reserve(Record.size()); for (unsigned I = 0, E = Record.size(); I != E; ++I) { CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown; + bool HasTailCall = false; uint64_t RelBF = 0; ValueInfo Callee = std::get<0>(getValueInfoFromValueId(Record[I])); if (IsOldProfileFormat) { @@ -7006,10 +7070,12 @@ ModuleSummaryIndexBitcodeReader::makeCallList(ArrayRef<uint64_t> Record, if (HasProfile) I += 1; // Skip old profilecount field } else if (HasProfile) - Hotness = static_cast<CalleeInfo::HotnessType>(Record[++I]); + std::tie(Hotness, HasTailCall) = + getDecodedHotnessCallEdgeInfo(Record[++I]); else if (HasRelBF) - RelBF = Record[++I]; - Ret.push_back(FunctionSummary::EdgeTy{Callee, CalleeInfo(Hotness, RelBF)}); + getDecodedRelBFCallEdgeInfo(Record[++I], RelBF, HasTailCall); + Ret.push_back(FunctionSummary::EdgeTy{ + Callee, CalleeInfo(Hotness, HasTailCall, RelBF)}); } return Ret; } @@ -7223,14 +7289,15 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { TheIndex.getOrInsertValueInfo(RefGUID), RefGUID, RefGUID); break; } + // FS_PERMODULE is legacy and does not have support for the tail call flag. // FS_PERMODULE: [valueid, flags, instcount, fflags, numrefs, // numrefs x valueid, n x (valueid)] // FS_PERMODULE_PROFILE: [valueid, flags, instcount, fflags, numrefs, // numrefs x valueid, - // n x (valueid, hotness)] + // n x (valueid, hotness+tailcall flags)] // FS_PERMODULE_RELBF: [valueid, flags, instcount, fflags, numrefs, // numrefs x valueid, - // n x (valueid, relblockfreq)] + // n x (valueid, relblockfreq+tailcall)] case bitc::FS_PERMODULE: case bitc::FS_PERMODULE_RELBF: case bitc::FS_PERMODULE_PROFILE: { @@ -7377,10 +7444,12 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { TheIndex.addGlobalValueSummary(std::get<0>(GUID), std::move(VS)); break; } + // FS_COMBINED is legacy and does not have support for the tail call flag. // FS_COMBINED: [valueid, modid, flags, instcount, fflags, numrefs, // numrefs x valueid, n x (valueid)] // FS_COMBINED_PROFILE: [valueid, modid, flags, instcount, fflags, numrefs, - // numrefs x valueid, n x (valueid, hotness)] + // numrefs x valueid, + // n x (valueid, hotness+tailcall flags)] case bitc::FS_COMBINED: case bitc::FS_COMBINED_PROFILE: { unsigned ValueID = Record[0]; @@ -7697,7 +7766,7 @@ Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() { if (convertToString(Record, 1, ModulePath)) return error("Invalid record"); - LastSeenModule = TheIndex.addModule(ModulePath, ModuleId); + LastSeenModule = TheIndex.addModule(ModulePath); ModuleIdMap[ModuleId] = LastSeenModule->first(); ModulePath.clear(); @@ -7712,7 +7781,7 @@ Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() { int Pos = 0; for (auto &Val : Record) { assert(!(Val >> 32) && "Unexpected high bits set"); - LastSeenModule->second.second[Pos++] = Val; + LastSeenModule->second[Pos++] = Val; } // Reset LastSeenModule to avoid overriding the hash unexpectedly. LastSeenModule = nullptr; @@ -7970,14 +8039,14 @@ BitcodeModule::getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata, // module path used in the combined summary (e.g. when reading summaries for // regular LTO modules). Error BitcodeModule::readSummary( - ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, uint64_t ModuleId, + ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, std::function<bool(GlobalValue::GUID)> IsPrevailing) { BitstreamCursor Stream(Buffer); if (Error JumpFailed = Stream.JumpToBit(ModuleBit)) return JumpFailed; ModuleSummaryIndexBitcodeReader R(std::move(Stream), Strtab, CombinedIndex, - ModulePath, ModuleId, IsPrevailing); + ModulePath, IsPrevailing); return R.parseModule(); } @@ -8183,13 +8252,12 @@ Expected<std::string> llvm::getBitcodeProducerString(MemoryBufferRef Buffer) { } Error llvm::readModuleSummaryIndex(MemoryBufferRef Buffer, - ModuleSummaryIndex &CombinedIndex, - uint64_t ModuleId) { + ModuleSummaryIndex &CombinedIndex) { Expected<BitcodeModule> BM = getSingleModule(Buffer); if (!BM) return BM.takeError(); - return BM->readSummary(CombinedIndex, BM->getModuleIdentifier(), ModuleId); + return BM->readSummary(CombinedIndex, BM->getModuleIdentifier()); } Expected<std::unique_ptr<ModuleSummaryIndex>> |