diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Bitcode | |
parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) |
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp | 93 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 583 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 82 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/MetadataLoader.h | 16 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 249 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.h | 4 |
6 files changed, 764 insertions, 263 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp index 1d16211c65bf..7005011980eb 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp @@ -13,6 +13,7 @@ #include "llvm/Bitstream/BitstreamReader.h" #include "llvm/Support/Format.h" #include "llvm/Support/SHA1.h" +#include <optional> using namespace llvm; @@ -21,14 +22,14 @@ static Error reportError(StringRef Message) { } /// Return a symbolic block name if known, otherwise return null. -static Optional<const char *> GetBlockName(unsigned BlockID, - const BitstreamBlockInfo &BlockInfo, - CurStreamTypeType CurStreamType) { +static std::optional<const char *> +GetBlockName(unsigned BlockID, const BitstreamBlockInfo &BlockInfo, + CurStreamTypeType CurStreamType) { // Standard blocks for all bitcode files. if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { if (BlockID == bitc::BLOCKINFO_BLOCK_ID) return "BLOCKINFO_BLOCK"; - return None; + return std::nullopt; } // Check to see if we have a blockinfo record for this block, with a name. @@ -39,11 +40,11 @@ static Optional<const char *> GetBlockName(unsigned BlockID, } if (CurStreamType != LLVMIRBitstream) - return None; + return std::nullopt; switch (BlockID) { default: - return None; + return std::nullopt; case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID: return "OPERAND_BUNDLE_TAGS_BLOCK"; case bitc::MODULE_BLOCK_ID: @@ -84,15 +85,16 @@ static Optional<const char *> GetBlockName(unsigned BlockID, } /// Return a symbolic code name if known, otherwise return null. -static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, - const BitstreamBlockInfo &BlockInfo, - CurStreamTypeType CurStreamType) { +static std::optional<const char *> +GetCodeName(unsigned CodeID, unsigned BlockID, + const BitstreamBlockInfo &BlockInfo, + CurStreamTypeType CurStreamType) { // Standard blocks for all bitcode files. if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { switch (CodeID) { default: - return None; + return std::nullopt; case bitc::BLOCKINFO_CODE_SETBID: return "SETBID"; case bitc::BLOCKINFO_CODE_BLOCKNAME: @@ -101,7 +103,7 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, return "SETRECORDNAME"; } } - return None; + return std::nullopt; } // Check to see if we have a blockinfo record for this record, with a name. @@ -113,18 +115,18 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, } if (CurStreamType != LLVMIRBitstream) - return None; + return std::nullopt; #define STRINGIFY_CODE(PREFIX, CODE) \ case bitc::PREFIX##_##CODE: \ return #CODE; switch (BlockID) { default: - return None; + return std::nullopt; case bitc::MODULE_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; STRINGIFY_CODE(MODULE_CODE, VERSION) STRINGIFY_CODE(MODULE_CODE, TRIPLE) STRINGIFY_CODE(MODULE_CODE, DATALAYOUT) @@ -144,14 +146,14 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::IDENTIFICATION_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; STRINGIFY_CODE(IDENTIFICATION_CODE, STRING) STRINGIFY_CODE(IDENTIFICATION_CODE, EPOCH) } case bitc::PARAMATTR_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; // FIXME: Should these be different? case bitc::PARAMATTR_CODE_ENTRY_OLD: return "ENTRY"; @@ -161,14 +163,14 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::PARAMATTR_GROUP_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; case bitc::PARAMATTR_GRP_CODE_ENTRY: return "ENTRY"; } case bitc::TYPE_BLOCK_ID_NEW: switch (CodeID) { default: - return None; + return std::nullopt; STRINGIFY_CODE(TYPE_CODE, NUMENTRY) STRINGIFY_CODE(TYPE_CODE, VOID) STRINGIFY_CODE(TYPE_CODE, FLOAT) @@ -196,7 +198,7 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::CONSTANTS_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; STRINGIFY_CODE(CST_CODE, SETTYPE) STRINGIFY_CODE(CST_CODE, NULL) STRINGIFY_CODE(CST_CODE, UNDEF) @@ -227,7 +229,7 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::FUNCTION_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; STRINGIFY_CODE(FUNC_CODE, DECLAREBLOCKS) STRINGIFY_CODE(FUNC_CODE, INST_BINOP) STRINGIFY_CODE(FUNC_CODE, INST_CAST) @@ -272,7 +274,7 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::VALUE_SYMTAB_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; STRINGIFY_CODE(VST_CODE, ENTRY) STRINGIFY_CODE(VST_CODE, BBENTRY) STRINGIFY_CODE(VST_CODE, FNENTRY) @@ -281,7 +283,7 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::MODULE_STRTAB_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; STRINGIFY_CODE(MST_CODE, ENTRY) STRINGIFY_CODE(MST_CODE, HASH) } @@ -289,7 +291,7 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; STRINGIFY_CODE(FS, PERMODULE) STRINGIFY_CODE(FS, PERMODULE_PROFILE) STRINGIFY_CODE(FS, PERMODULE_RELBF) @@ -315,17 +317,22 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, STRINGIFY_CODE(FS, TYPE_ID_METADATA) STRINGIFY_CODE(FS, BLOCK_COUNT) STRINGIFY_CODE(FS, PARAM_ACCESS) + STRINGIFY_CODE(FS, PERMODULE_CALLSITE_INFO) + STRINGIFY_CODE(FS, PERMODULE_ALLOC_INFO) + STRINGIFY_CODE(FS, COMBINED_CALLSITE_INFO) + STRINGIFY_CODE(FS, COMBINED_ALLOC_INFO) + STRINGIFY_CODE(FS, STACK_IDS) } case bitc::METADATA_ATTACHMENT_ID: switch (CodeID) { default: - return None; + return std::nullopt; STRINGIFY_CODE(METADATA, ATTACHMENT) } case bitc::METADATA_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; STRINGIFY_CODE(METADATA, STRING_OLD) STRINGIFY_CODE(METADATA, VALUE) STRINGIFY_CODE(METADATA, NODE) @@ -369,13 +376,13 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::METADATA_KIND_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; STRINGIFY_CODE(METADATA, KIND) } case bitc::USELIST_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; case bitc::USELIST_CODE_DEFAULT: return "USELIST_CODE_DEFAULT"; case bitc::USELIST_CODE_BB: @@ -385,21 +392,21 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; case bitc::OPERAND_BUNDLE_TAG: return "OPERAND_BUNDLE_TAG"; } case bitc::STRTAB_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; case bitc::STRTAB_BLOB: return "BLOB"; } case bitc::SYMTAB_BLOCK_ID: switch (CodeID) { default: - return None; + return std::nullopt; case bitc::SYMTAB_BLOB: return "BLOB"; } @@ -468,7 +475,7 @@ static Expected<CurStreamTypeType> ReadSignature(BitstreamCursor &Stream) { return UnknownBitstream; } -static Expected<CurStreamTypeType> analyzeHeader(Optional<BCDumpOptions> O, +static Expected<CurStreamTypeType> analyzeHeader(std::optional<BCDumpOptions> O, BitstreamCursor &Stream) { ArrayRef<uint8_t> Bytes = Stream.getBitcodeBytes(); const unsigned char *BufPtr = (const unsigned char *)Bytes.data(); @@ -548,14 +555,14 @@ Error BitcodeAnalyzer::decodeMetadataStringsBlob(StringRef Indent, } BitcodeAnalyzer::BitcodeAnalyzer(StringRef Buffer, - Optional<StringRef> BlockInfoBuffer) + std::optional<StringRef> BlockInfoBuffer) : Stream(Buffer) { if (BlockInfoBuffer) BlockInfoStream.emplace(*BlockInfoBuffer); } -Error BitcodeAnalyzer::analyze(Optional<BCDumpOptions> O, - Optional<StringRef> CheckHash) { +Error BitcodeAnalyzer::analyze(std::optional<BCDumpOptions> O, + std::optional<StringRef> CheckHash) { if (Error E = analyzeHeader(O, Stream).moveInto(CurStreamType)) return E; @@ -579,7 +586,7 @@ Error BitcodeAnalyzer::analyze(Optional<BCDumpOptions> O, if (!MaybeBlockID) return MaybeBlockID.takeError(); if (MaybeBlockID.get() == bitc::BLOCKINFO_BLOCK_ID) { - Optional<BitstreamBlockInfo> NewBlockInfo; + std::optional<BitstreamBlockInfo> NewBlockInfo; if (Error E = BlockInfoCursor.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true) .moveInto(NewBlockInfo)) @@ -616,7 +623,7 @@ Error BitcodeAnalyzer::analyze(Optional<BCDumpOptions> O, } void BitcodeAnalyzer::printStats(BCDumpOptions O, - Optional<StringRef> Filename) { + std::optional<StringRef> Filename) { uint64_t BufferSizeBits = Stream.getBitcodeBytes().size() * CHAR_BIT; // Print a summary of the read file. O.OS << "Summary "; @@ -650,7 +657,7 @@ void BitcodeAnalyzer::printStats(BCDumpOptions O, O.OS << "Per-block Summary:\n"; for (const auto &Stat : BlockIDStats) { O.OS << " Block ID #" << Stat.first; - if (Optional<const char *> BlockName = + if (std::optional<const char *> BlockName = GetBlockName(Stat.first, BlockInfo, CurStreamType)) O.OS << " (" << *BlockName << ")"; O.OS << ":\n"; @@ -713,7 +720,7 @@ void BitcodeAnalyzer::printStats(BCDumpOptions O, O.OS << " "; O.OS << " "; - if (Optional<const char *> CodeName = GetCodeName( + if (std::optional<const char *> CodeName = GetCodeName( FreqPair.second, Stat.first, BlockInfo, CurStreamType)) O.OS << *CodeName << "\n"; else @@ -725,8 +732,8 @@ void BitcodeAnalyzer::printStats(BCDumpOptions O, } Error BitcodeAnalyzer::parseBlock(unsigned BlockID, unsigned IndentLevel, - Optional<BCDumpOptions> O, - Optional<StringRef> CheckHash) { + std::optional<BCDumpOptions> O, + std::optional<StringRef> CheckHash) { std::string Indent(IndentLevel * 2, ' '); uint64_t BlockBitStart = Stream.GetCurrentBitNo(); @@ -740,7 +747,7 @@ Error BitcodeAnalyzer::parseBlock(unsigned BlockID, unsigned IndentLevel, if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { if (O && !O->DumpBlockinfo) O->OS << Indent << "<BLOCKINFO_BLOCK/>\n"; - Optional<BitstreamBlockInfo> NewBlockInfo; + std::optional<BitstreamBlockInfo> NewBlockInfo; if (Error E = Stream.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true) .moveInto(NewBlockInfo)) return E; @@ -761,7 +768,7 @@ Error BitcodeAnalyzer::parseBlock(unsigned BlockID, unsigned IndentLevel, // Keep it for later, when we see a MODULE_HASH record uint64_t BlockEntryPos = Stream.getCurrentByteNo(); - Optional<const char *> BlockName = None; + std::optional<const char *> BlockName; if (DumpRecords) { O->OS << Indent << "<"; if ((BlockName = GetBlockName(BlockID, BlockInfo, CurStreamType))) @@ -855,7 +862,7 @@ Error BitcodeAnalyzer::parseBlock(unsigned BlockID, unsigned IndentLevel, if (DumpRecords) { O->OS << Indent << " <"; - Optional<const char *> CodeName = + std::optional<const char *> CodeName = GetCodeName(Code, BlockID, BlockInfo, CurStreamType); if (CodeName) O->OS << *CodeName; diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 1943b5db94c3..f014521264c1 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -13,7 +13,6 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -71,6 +70,7 @@ #include "llvm/Support/ErrorOr.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/ModRef.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> @@ -79,6 +79,7 @@ #include <deque> #include <map> #include <memory> +#include <optional> #include <set> #include <string> #include <system_error> @@ -546,13 +547,13 @@ public: static bool classof(const Value *V) { return V->getValueID() == SubclassID; } ArrayRef<unsigned> getOperandIDs() const { - return makeArrayRef(getTrailingObjects<unsigned>(), NumOperands); + return ArrayRef(getTrailingObjects<unsigned>(), NumOperands); } - Optional<unsigned> getInRangeIndex() const { + std::optional<unsigned> getInRangeIndex() const { assert(Opcode == Instruction::GetElementPtr); if (Extra == (unsigned)-1) - return None; + return std::nullopt; return Extra; } @@ -592,7 +593,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { /// ValueList must be destroyed before Alloc. BumpPtrAllocator Alloc; BitcodeReaderValueList ValueList; - Optional<MetadataLoader> MDLoader; + std::optional<MetadataLoader> MDLoader; std::vector<Comdat *> ComdatList; DenseSet<GlobalObject *> ImplicitComdatObjects; SmallVector<Instruction *, 64> InstructionList; @@ -627,8 +628,6 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { // stored here with their replacement function. using UpdatedIntrinsicMap = DenseMap<Function *, Function *>; UpdatedIntrinsicMap UpgradedIntrinsics; - // Intrinsics which were remangled because of types rename - UpdatedIntrinsicMap RemangledIntrinsics; // Several operations happen after the module header has been read, but // before function bodies are processed. This keeps track of whether @@ -675,6 +674,8 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { std::vector<std::string> BundleTags; SmallVector<SyncScope::ID, 8> SSIDs; + std::optional<ValueTypeCallbackTy> ValueTypeCallback; + public: BitcodeReader(BitstreamCursor Stream, StringRef Strtab, StringRef ProducerIdentification, LLVMContext &Context); @@ -687,9 +688,8 @@ public: /// Main interface to parsing a bitcode buffer. /// \returns true if an error occurred. - Error parseBitcodeInto( - Module *M, bool ShouldLazyLoadMetadata, bool IsImporting, - DataLayoutCallbackTy DataLayoutCallback); + Error parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata, + bool IsImporting, ParserCallbacks Callbacks = {}); static uint64_t decodeSignRotatedValue(uint64_t V); @@ -710,6 +710,7 @@ private: unsigned getContainedTypeID(unsigned ID, unsigned Idx = 0); unsigned getVirtualTypeID(Type *Ty, ArrayRef<unsigned> ContainedTypeIDs = {}); + void callValueTypeCallback(Value *F, unsigned TypeID); Expected<Value *> materializeValue(unsigned ValID, BasicBlock *InsertBB); Expected<Constant *> getValueForInitializer(unsigned ID); @@ -820,9 +821,8 @@ private: /// a corresponding error code. Error parseAlignmentValue(uint64_t Exponent, MaybeAlign &Alignment); Error parseAttrKind(uint64_t Code, Attribute::AttrKind *Kind); - Error parseModule( - uint64_t ResumeBit, bool ShouldLazyLoadMetadata = false, - DataLayoutCallbackTy DataLayoutCallback = [](StringRef) { return None; }); + Error parseModule(uint64_t ResumeBit, bool ShouldLazyLoadMetadata = false, + ParserCallbacks Callbacks = {}); Error parseComdatRecord(ArrayRef<uint64_t> Record); Error parseGlobalVarRecord(ArrayRef<uint64_t> Record); @@ -884,8 +884,10 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase { // they are recorded in the summary index being built. // We save a GUID which refers to the same global as the ValueInfo, but // ignoring the linkage, i.e. for values other than local linkage they are - // identical. - DenseMap<unsigned, std::pair<ValueInfo, GlobalValue::GUID>> + // identical (this is the second tuple member). + // The third tuple member is the real GUID of the ValueInfo. + DenseMap<unsigned, + std::tuple<ValueInfo, GlobalValue::GUID, GlobalValue::GUID>> ValueIdToValueInfoMap; /// Map populated during module path string table parsing, from the @@ -905,10 +907,19 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase { /// 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; + + /// Saves the stack ids from the STACK_IDS record to consult when adding stack + /// ids from the lists in the callsite and alloc entries to the index. + std::vector<uint64_t> StackIds; + public: - ModuleSummaryIndexBitcodeReader(BitstreamCursor Stream, StringRef Strtab, - ModuleSummaryIndex &TheIndex, - StringRef ModulePath, unsigned ModuleId); + ModuleSummaryIndexBitcodeReader( + BitstreamCursor Stream, StringRef Strtab, ModuleSummaryIndex &TheIndex, + StringRef ModulePath, unsigned ModuleId, + std::function<bool(GlobalValue::GUID)> IsPrevailing = nullptr); Error parseModule(); @@ -932,7 +943,8 @@ private: std::vector<FunctionSummary::ParamAccess> parseParamAccesses(ArrayRef<uint64_t> Record); - std::pair<ValueInfo, GlobalValue::GUID> + template <bool AllowNullValueInfo = false> + std::tuple<ValueInfo, GlobalValue::GUID, GlobalValue::GUID> getValueInfoFromValueId(unsigned ValueId); void addThisModule(); @@ -1244,6 +1256,10 @@ static AtomicRMWInst::BinOp getDecodedRMWOperation(unsigned Val) { case bitc::RMW_FSUB: return AtomicRMWInst::FSub; case bitc::RMW_FMAX: return AtomicRMWInst::FMax; case bitc::RMW_FMIN: return AtomicRMWInst::FMin; + case bitc::RMW_UINC_WRAP: + return AtomicRMWInst::UIncWrap; + case bitc::RMW_UDEC_WRAP: + return AtomicRMWInst::UDecWrap; } } @@ -1298,6 +1314,9 @@ static FastMathFlags getDecodedFastMathFlags(unsigned Val) { } static void upgradeDLLImportExportLinkage(GlobalValue *GV, unsigned Val) { + // A GlobalValue with local linkage cannot have a DLL storage class. + if (GV->hasLocalLinkage()) + return; switch (Val) { case 5: GV->setDLLStorageClass(GlobalValue::DLLImportStorageClass); break; case 6: GV->setDLLStorageClass(GlobalValue::DLLExportStorageClass); break; @@ -1385,10 +1404,15 @@ static bool isConstExprSupported(uint8_t Opcode) { if (Opcode >= BitcodeConstant::FirstSpecialOpcode) return true; + // If -expand-constant-exprs is set, we want to consider all expressions + // as unsupported. + if (ExpandConstantExprs) + return false; + if (Instruction::isBinaryOp(Opcode)) return ConstantExpr::isSupportedBinOp(Opcode); - return !ExpandConstantExprs; + return Opcode != Instruction::FNeg; } Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, @@ -1449,8 +1473,6 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, C = UpgradeBitCastExpr(BC->Opcode, ConstOps[0], BC->getType()); if (!C) C = ConstantExpr::getCast(BC->Opcode, ConstOps[0], BC->getType()); - } else if (Instruction::isUnaryOp(BC->Opcode)) { - C = ConstantExpr::get(BC->Opcode, ConstOps[0], BC->Flags); } else if (Instruction::isBinaryOp(BC->Opcode)) { C = ConstantExpr::get(BC->Opcode, ConstOps[0], ConstOps[1], BC->Flags); } else { @@ -1518,9 +1540,9 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, C = ConstantExpr::getCompare(BC->Flags, ConstOps[0], ConstOps[1]); break; case Instruction::GetElementPtr: - C = ConstantExpr::getGetElementPtr( - BC->SrcElemTy, ConstOps[0], makeArrayRef(ConstOps).drop_front(), - BC->Flags, BC->getInRangeIndex()); + C = ConstantExpr::getGetElementPtr(BC->SrcElemTy, ConstOps[0], + ArrayRef(ConstOps).drop_front(), + BC->Flags, BC->getInRangeIndex()); break; case Instruction::Select: C = ConstantExpr::getSelect(ConstOps[0], ConstOps[1], ConstOps[2]); @@ -1577,8 +1599,6 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, I->setIsExact(); } else { switch (BC->Opcode) { - case BitcodeConstant::ConstantStructOpcode: - case BitcodeConstant::ConstantArrayOpcode: case BitcodeConstant::ConstantVectorOpcode: { Type *IdxTy = Type::getInt32Ty(BC->getContext()); Value *V = PoisonValue::get(BC->getType()); @@ -1590,6 +1610,15 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, I = cast<Instruction>(V); break; } + case BitcodeConstant::ConstantStructOpcode: + case BitcodeConstant::ConstantArrayOpcode: { + Value *V = PoisonValue::get(BC->getType()); + for (auto Pair : enumerate(Ops)) + V = InsertValueInst::Create(V, Pair.value(), Pair.index(), + "constexpr.ins", InsertBB); + I = cast<Instruction>(V); + break; + } case Instruction::ICmp: case Instruction::FCmp: I = CmpInst::Create((Instruction::OtherOps)BC->Opcode, @@ -1598,8 +1627,8 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, break; case Instruction::GetElementPtr: I = GetElementPtrInst::Create(BC->SrcElemTy, Ops[0], - makeArrayRef(Ops).drop_front(), - "constexpr", InsertBB); + ArrayRef(Ops).drop_front(), "constexpr", + InsertBB); if (BC->Flags) cast<GetElementPtrInst>(I)->setIsInBounds(); break; @@ -1706,8 +1735,8 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) { case Attribute::Convergent: return 1ULL << 46; case Attribute::SafeStack: return 1ULL << 47; case Attribute::NoRecurse: return 1ULL << 48; - case Attribute::InaccessibleMemOnly: return 1ULL << 49; - case Attribute::InaccessibleMemOrArgMemOnly: return 1ULL << 50; + // 1ULL << 49 is InaccessibleMemOnly, which is upgraded separately. + // 1ULL << 50 is InaccessibleMemOrArgMemOnly, which is upgraded separately. case Attribute::SwiftSelf: return 1ULL << 51; case Attribute::SwiftError: return 1ULL << 52; case Attribute::WriteOnly: return 1ULL << 53; @@ -1755,7 +1784,8 @@ static void addRawAttributeValue(AttrBuilder &B, uint64_t Val) { /// been decoded from the given integer. This function must stay in sync with /// 'encodeLLVMAttributesForBitcode'. static void decodeLLVMAttributesForBitcode(AttrBuilder &B, - uint64_t EncodedAttrs) { + uint64_t EncodedAttrs, + uint64_t AttrIdx) { // The alignment is stored as a 16-bit raw value from bits 31--16. We shift // the bits above 31 down by 11 bits. unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16; @@ -1764,8 +1794,43 @@ static void decodeLLVMAttributesForBitcode(AttrBuilder &B, if (Alignment) B.addAlignmentAttr(Alignment); - addRawAttributeValue(B, ((EncodedAttrs & (0xfffffULL << 32)) >> 11) | - (EncodedAttrs & 0xffff)); + + uint64_t Attrs = ((EncodedAttrs & (0xfffffULL << 32)) >> 11) | + (EncodedAttrs & 0xffff); + + if (AttrIdx == AttributeList::FunctionIndex) { + // Upgrade old memory attributes. + MemoryEffects ME = MemoryEffects::unknown(); + if (Attrs & (1ULL << 9)) { + // ReadNone + Attrs &= ~(1ULL << 9); + ME &= MemoryEffects::none(); + } + if (Attrs & (1ULL << 10)) { + // ReadOnly + Attrs &= ~(1ULL << 10); + ME &= MemoryEffects::readOnly(); + } + if (Attrs & (1ULL << 49)) { + // InaccessibleMemOnly + Attrs &= ~(1ULL << 49); + ME &= MemoryEffects::inaccessibleMemOnly(); + } + if (Attrs & (1ULL << 50)) { + // InaccessibleMemOrArgMemOnly + Attrs &= ~(1ULL << 50); + ME &= MemoryEffects::inaccessibleOrArgMemOnly(); + } + if (Attrs & (1ULL << 53)) { + // WriteOnly + Attrs &= ~(1ULL << 53); + ME &= MemoryEffects::writeOnly(); + } + if (ME != MemoryEffects::unknown()) + B.addMemoryAttr(ME); + } + + addRawAttributeValue(B, Attrs); } Error BitcodeReader::parseAttributeBlock() { @@ -1812,7 +1877,7 @@ Error BitcodeReader::parseAttributeBlock() { for (unsigned i = 0, e = Record.size(); i != e; i += 2) { AttrBuilder B(Context); - decodeLLVMAttributesForBitcode(B, Record[i+1]); + decodeLLVMAttributesForBitcode(B, Record[i+1], Record[i]); Attrs.push_back(AttributeList::get(Context, Record[i], B)); } @@ -1839,8 +1904,6 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::Alignment; case bitc::ATTR_KIND_ALWAYS_INLINE: return Attribute::AlwaysInline; - case bitc::ATTR_KIND_ARGMEMONLY: - return Attribute::ArgMemOnly; case bitc::ATTR_KIND_BUILTIN: return Attribute::Builtin; case bitc::ATTR_KIND_BY_VAL: @@ -1857,16 +1920,14 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::ElementType; case bitc::ATTR_KIND_FNRETTHUNK_EXTERN: return Attribute::FnRetThunkExtern; - case bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY: - return Attribute::InaccessibleMemOnly; - case bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY: - return Attribute::InaccessibleMemOrArgMemOnly; case bitc::ATTR_KIND_INLINE_HINT: return Attribute::InlineHint; case bitc::ATTR_KIND_IN_REG: return Attribute::InReg; case bitc::ATTR_KIND_JUMP_TABLE: return Attribute::JumpTable; + case bitc::ATTR_KIND_MEMORY: + return Attribute::Memory; case bitc::ATTR_KIND_MIN_SIZE: return Attribute::MinSize; case bitc::ATTR_KIND_NAKED: @@ -1919,6 +1980,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::NoCfCheck; case bitc::ATTR_KIND_NO_PROFILE: return Attribute::NoProfile; + case bitc::ATTR_KIND_SKIP_PROFILE: + return Attribute::SkipProfile; case bitc::ATTR_KIND_NO_UNWIND: return Attribute::NoUnwind; case bitc::ATTR_KIND_NO_SANITIZE_BOUNDS: @@ -2023,6 +2086,31 @@ Error BitcodeReader::parseAttrKind(uint64_t Code, Attribute::AttrKind *Kind) { return Error::success(); } +static bool upgradeOldMemoryAttribute(MemoryEffects &ME, uint64_t EncodedKind) { + switch (EncodedKind) { + case bitc::ATTR_KIND_READ_NONE: + ME &= MemoryEffects::none(); + return true; + case bitc::ATTR_KIND_READ_ONLY: + ME &= MemoryEffects::readOnly(); + return true; + case bitc::ATTR_KIND_WRITEONLY: + ME &= MemoryEffects::writeOnly(); + return true; + case bitc::ATTR_KIND_ARGMEMONLY: + ME &= MemoryEffects::argMemOnly(); + return true; + case bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY: + ME &= MemoryEffects::inaccessibleMemOnly(); + return true; + case bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY: + ME &= MemoryEffects::inaccessibleOrArgMemOnly(); + return true; + default: + return false; + } +} + Error BitcodeReader::parseAttributeGroupBlock() { if (Error Err = Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) return Err; @@ -2066,10 +2154,16 @@ Error BitcodeReader::parseAttributeGroupBlock() { uint64_t Idx = Record[1]; // Index of the object this attribute refers to. AttrBuilder B(Context); + MemoryEffects ME = MemoryEffects::unknown(); for (unsigned i = 2, e = Record.size(); i != e; ++i) { if (Record[i] == 0) { // Enum attribute Attribute::AttrKind Kind; - if (Error Err = parseAttrKind(Record[++i], &Kind)) + uint64_t EncodedKind = Record[++i]; + if (Idx == AttributeList::FunctionIndex && + upgradeOldMemoryAttribute(ME, EncodedKind)) + continue; + + if (Error Err = parseAttrKind(EncodedKind, &Kind)) return Err; // Upgrade old-style byval attribute to one with a type, even if it's @@ -2109,6 +2203,8 @@ Error BitcodeReader::parseAttributeGroupBlock() { B.addUWTableAttr(UWTableKind(Record[++i])); else if (Kind == Attribute::AllocKind) B.addAllocKindAttr(static_cast<AllocFnKind>(Record[++i])); + else if (Kind == Attribute::Memory) + B.addMemoryAttr(MemoryEffects::createFromIntValue(Record[++i])); } else if (Record[i] == 3 || Record[i] == 4) { // String attribute bool HasValue = (Record[i++] == 4); SmallString<64> KindStr; @@ -2141,6 +2237,9 @@ Error BitcodeReader::parseAttributeGroupBlock() { } } + if (ME != MemoryEffects::unknown()) + B.addMemoryAttr(ME); + UpgradeAttributes(B); MAttributeGroups[GrpID] = AttributeList::get(Context, Idx, B); break; @@ -2263,8 +2362,6 @@ Error BitcodeReader::parseTypeTableBody() { if (!ResultTy || !PointerType::isValidElementType(ResultTy)) return error("Invalid type"); - if (LLVM_UNLIKELY(!Context.hasSetOpaquePointersValue())) - Context.setOpaquePointers(false); ContainedIDs.push_back(Record[0]); ResultTy = PointerType::get(ResultTy, AddressSpace); break; @@ -2272,9 +2369,7 @@ Error BitcodeReader::parseTypeTableBody() { case bitc::TYPE_CODE_OPAQUE_POINTER: { // OPAQUE_POINTER: [addrspace] if (Record.size() != 1) return error("Invalid opaque pointer record"); - if (LLVM_UNLIKELY(!Context.hasSetOpaquePointersValue())) { - Context.setOpaquePointers(true); - } else if (Context.supportsTypedPointers()) + if (Context.supportsTypedPointers()) return error( "Opaque pointers are only supported in -opaque-pointers mode"); unsigned AddressSpace = Record[0]; @@ -2394,6 +2489,35 @@ Error BitcodeReader::parseTypeTableBody() { ResultTy = Res; break; } + case bitc::TYPE_CODE_TARGET_TYPE: { // TARGET_TYPE: [NumTy, Tys..., Ints...] + if (Record.size() < 1) + return error("Invalid target extension type record"); + + if (NumRecords >= TypeList.size()) + return error("Invalid TYPE table"); + + if (Record[0] >= Record.size()) + return error("Too many type parameters"); + + unsigned NumTys = Record[0]; + SmallVector<Type *, 4> TypeParams; + SmallVector<unsigned, 8> IntParams; + for (unsigned i = 0; i < NumTys; i++) { + if (Type *T = getTypeByID(Record[i + 1])) + TypeParams.push_back(T); + else + return error("Invalid type"); + } + + for (unsigned i = NumTys + 1, e = Record.size(); i < e; i++) { + if (Record[i] > UINT_MAX) + return error("Integer parameter too large"); + IntParams.push_back(Record[i]); + } + ResultTy = TargetExtType::get(Context, TypeName, TypeParams, IntParams); + TypeName.clear(); + break; + } case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty] if (Record.size() < 2) return error("Invalid array type record"); @@ -2778,9 +2902,9 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() { } else if (auto *GI = dyn_cast<GlobalIFunc>(GV)) { Type *ResolverFTy = GlobalIFunc::getResolverFunctionType(GI->getValueType()); - // Transparently fix up the type for compatiblity with older bitcode - GI->setResolver( - ConstantExpr::getBitCast(C, ResolverFTy->getPointerTo())); + // Transparently fix up the type for compatibility with older bitcode + GI->setResolver(ConstantExpr::getBitCast( + C, ResolverFTy->getPointerTo(GI->getAddressSpace()))); } else { return error("Expected an alias or an ifunc"); } @@ -2897,6 +3021,9 @@ Error BitcodeReader::parseConstants() { case bitc::CST_CODE_NULL: // NULL if (CurTy->isVoidTy() || CurTy->isFunctionTy() || CurTy->isLabelTy()) return error("Invalid type for a constant null value"); + if (auto *TETy = dyn_cast<TargetExtType>(CurTy)) + if (!TETy->hasProperty(TargetExtType::HasZeroInit)) + return error("Invalid type for a constant null value"); V = Constant::getNullValue(CurTy); break; case bitc::CST_CODE_INTEGER: // INTEGER: [intval] @@ -3111,7 +3238,7 @@ Error BitcodeReader::parseConstants() { PointeeType = getTypeByID(Record[OpNum++]); bool InBounds = false; - Optional<unsigned> InRangeIndex; + std::optional<unsigned> InRangeIndex; if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX) { uint64_t Op = Record[OpNum++]; InBounds = Op & 1; @@ -3443,7 +3570,7 @@ Error BitcodeReader::parseUseLists() { break; case bitc::USELIST_CODE_BB: IsBB = true; - LLVM_FALLTHROUGH; + [[fallthrough]]; case bitc::USELIST_CODE_DEFAULT: { unsigned RecordLength = Record.size(); if (RecordLength < 3) @@ -3555,11 +3682,6 @@ Error BitcodeReader::globalCleanup() { Function *NewFn; if (UpgradeIntrinsicFunction(&F, NewFn)) UpgradedIntrinsics[&F] = NewFn; - else if (auto Remangled = Intrinsic::remangleIntrinsicFunction(&F)) - // Some types could be renamed during loading if several modules are - // loaded in the same LLVMContext (LTO scenario). In this case we should - // remangle intrinsics names as well. - RemangledIntrinsics[&F] = *Remangled; // Look for functions that rely on old function attribute behavior. UpgradeFunctionAttributes(F); } @@ -3625,11 +3747,11 @@ Error BitcodeReader::rememberAndSkipFunctionBodies() { } Error BitcodeReaderBase::readBlockInfo() { - Expected<Optional<BitstreamBlockInfo>> MaybeNewBlockInfo = + Expected<std::optional<BitstreamBlockInfo>> MaybeNewBlockInfo = Stream.ReadBlockInfoBlock(); if (!MaybeNewBlockInfo) return MaybeNewBlockInfo.takeError(); - Optional<BitstreamBlockInfo> NewBlockInfo = + std::optional<BitstreamBlockInfo> NewBlockInfo = std::move(MaybeNewBlockInfo.get()); if (!NewBlockInfo) return error("Malformed block"); @@ -3752,10 +3874,14 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { NewGV->setVisibility(Visibility); NewGV->setUnnamedAddr(UnnamedAddr); - if (Record.size() > 10) - NewGV->setDLLStorageClass(getDecodedDLLStorageClass(Record[10])); - else + if (Record.size() > 10) { + // A GlobalValue with local linkage cannot have a DLL storage class. + if (!NewGV->hasLocalLinkage()) { + NewGV->setDLLStorageClass(getDecodedDLLStorageClass(Record[10])); + } + } else { upgradeDLLImportExportLinkage(NewGV, RawLinkage); + } ValueList.push_back(NewGV, getVirtualTypeID(NewGV->getType(), TyID)); @@ -3796,6 +3922,14 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { return Error::success(); } +void BitcodeReader::callValueTypeCallback(Value *F, unsigned TypeID) { + if (ValueTypeCallback) { + (*ValueTypeCallback)( + F, TypeID, [this](unsigned I) { return getTypeByID(I); }, + [this](unsigned I, unsigned J) { return getContainedTypeID(I, J); }); + } +} + Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { // v1: [type, callingconv, isproto, linkage, paramattr, alignment, section, // visibility, gc, unnamed_addr, prologuedata, dllstorageclass, comdat, @@ -3840,6 +3974,7 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { uint64_t RawLinkage = Record[3]; Func->setLinkage(getDecodedLinkage(RawLinkage)); Func->setAttributes(getAttributes(Record[4])); + callValueTypeCallback(Func, FTyID); // Upgrade any old-style byval or sret without a type by propagating the // argument's pointee type. There should be no opaque pointers where the byval @@ -3916,10 +4051,14 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { if (Record.size() > 10) OperandInfo.Prologue = Record[10]; - if (Record.size() > 11) - Func->setDLLStorageClass(getDecodedDLLStorageClass(Record[11])); - else + if (Record.size() > 11) { + // A GlobalValue with local linkage cannot have a DLL storage class. + if (!Func->hasLocalLinkage()) { + Func->setDLLStorageClass(getDecodedDLLStorageClass(Record[11])); + } + } else { upgradeDLLImportExportLinkage(Func, RawLinkage); + } if (Record.size() > 12) { if (unsigned ComdatID = Record[12]) { @@ -4022,8 +4161,12 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( } if (BitCode == bitc::MODULE_CODE_ALIAS || BitCode == bitc::MODULE_CODE_ALIAS_OLD) { - if (OpNum != Record.size()) - NewGA->setDLLStorageClass(getDecodedDLLStorageClass(Record[OpNum++])); + if (OpNum != Record.size()) { + auto S = Record[OpNum++]; + // A GlobalValue with local linkage cannot have a DLL storage class. + if (!NewGA->hasLocalLinkage()) + NewGA->setDLLStorageClass(getDecodedDLLStorageClass(S)); + } else upgradeDLLImportExportLinkage(NewGA, Linkage); if (OpNum != Record.size()) @@ -4049,7 +4192,8 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( Error BitcodeReader::parseModule(uint64_t ResumeBit, bool ShouldLazyLoadMetadata, - DataLayoutCallbackTy DataLayoutCallback) { + ParserCallbacks Callbacks) { + this->ValueTypeCallback = std::move(Callbacks.ValueType); if (ResumeBit) { if (Error JumpFailed = Stream.JumpToBit(ResumeBit)) return JumpFailed; @@ -4061,21 +4205,37 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, // Parts of bitcode parsing depend on the datalayout. Make sure we // finalize the datalayout before we run any of that code. bool ResolvedDataLayout = false; - auto ResolveDataLayout = [&] { + // In order to support importing modules with illegal data layout strings, + // delay parsing the data layout string until after upgrades and overrides + // have been applied, allowing to fix illegal data layout strings. + // Initialize to the current module's layout string in case none is specified. + std::string TentativeDataLayoutStr = TheModule->getDataLayoutStr(); + + auto ResolveDataLayout = [&]() -> Error { if (ResolvedDataLayout) - return; + return Error::success(); - // datalayout and triple can't be parsed after this point. + // Datalayout and triple can't be parsed after this point. ResolvedDataLayout = true; - // Upgrade data layout string. - std::string DL = llvm::UpgradeDataLayoutString( - TheModule->getDataLayoutStr(), TheModule->getTargetTriple()); - TheModule->setDataLayout(DL); + // Auto-upgrade the layout string + TentativeDataLayoutStr = llvm::UpgradeDataLayoutString( + TentativeDataLayoutStr, TheModule->getTargetTriple()); + + // Apply override + if (Callbacks.DataLayout) { + if (auto LayoutOverride = (*Callbacks.DataLayout)( + TheModule->getTargetTriple(), TentativeDataLayoutStr)) + TentativeDataLayoutStr = *LayoutOverride; + } + + // Now the layout string is finalized in TentativeDataLayoutStr. Parse it. + Expected<DataLayout> MaybeDL = DataLayout::parse(TentativeDataLayoutStr); + if (!MaybeDL) + return MaybeDL.takeError(); - if (auto LayoutOverride = - DataLayoutCallback(TheModule->getTargetTriple())) - TheModule->setDataLayout(*LayoutOverride); + TheModule->setDataLayout(MaybeDL.get()); + return Error::success(); }; // Read all the records for this module. @@ -4089,7 +4249,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, case BitstreamEntry::Error: return error("Malformed block"); case BitstreamEntry::EndBlock: - ResolveDataLayout(); + if (Error Err = ResolveDataLayout()) + return Err; return globalCleanup(); case BitstreamEntry::SubBlock: @@ -4154,7 +4315,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, return Err; break; case bitc::FUNCTION_BLOCK_ID: - ResolveDataLayout(); + if (Error Err = ResolveDataLayout()) + return Err; // If this is the first function body we've seen, reverse the // FunctionsWithBodies list. @@ -4253,13 +4415,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, case bitc::MODULE_CODE_DATALAYOUT: { // DATALAYOUT: [strchr x N] if (ResolvedDataLayout) return error("datalayout too late in module"); - std::string S; - if (convertToString(Record, 0, S)) + if (convertToString(Record, 0, TentativeDataLayoutStr)) return error("Invalid record"); - Expected<DataLayout> MaybeDL = DataLayout::parse(S); - if (!MaybeDL) - return MaybeDL.takeError(); - TheModule->setDataLayout(MaybeDL.get()); break; } case bitc::MODULE_CODE_ASM: { // ASM: [strchr x N] @@ -4305,7 +4462,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, return Err; break; case bitc::MODULE_CODE_FUNCTION: - ResolveDataLayout(); + if (Error Err = ResolveDataLayout()) + return Err; if (Error Err = parseFunctionRecord(Record)) return Err; break; @@ -4334,15 +4492,22 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, } Record.clear(); } + this->ValueTypeCallback = std::nullopt; + return Error::success(); } Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata, bool IsImporting, - DataLayoutCallbackTy DataLayoutCallback) { + ParserCallbacks Callbacks) { TheModule = M; - MDLoader = MetadataLoader(Stream, *M, ValueList, IsImporting, - [&](unsigned ID) { return getTypeByID(ID); }); - return parseModule(0, ShouldLazyLoadMetadata, DataLayoutCallback); + MetadataLoaderCallbacks MDCallbacks; + MDCallbacks.GetTypeByID = [&](unsigned ID) { return getTypeByID(ID); }; + MDCallbacks.GetContainedTypeID = [&](unsigned I, unsigned J) { + return getContainedTypeID(I, J); + }; + MDCallbacks.MDType = Callbacks.MDType; + MDLoader = MetadataLoader(Stream, *M, ValueList, IsImporting, MDCallbacks); + return parseModule(0, ShouldLazyLoadMetadata, Callbacks); } Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) { @@ -4737,7 +4902,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (Temp) { InstructionList.push_back(Temp); assert(CurBB && "No current BB?"); - CurBB->getInstList().push_back(Temp); + Temp->insertInto(CurBB, CurBB->end()); } } else { auto CastOp = (Instruction::CastOps)Opc; @@ -5261,7 +5426,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned ActiveWords = 1; if (ValueBitWidth > 64) ActiveWords = Record[CurIdx++]; - Low = readWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords), + Low = readWideAPInt(ArrayRef(&Record[CurIdx], ActiveWords), ValueBitWidth); CurIdx += ActiveWords; @@ -5269,8 +5434,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { ActiveWords = 1; if (ValueBitWidth > 64) ActiveWords = Record[CurIdx++]; - APInt High = readWideAPInt( - makeArrayRef(&Record[CurIdx], ActiveWords), ValueBitWidth); + APInt High = readWideAPInt(ArrayRef(&Record[CurIdx], ActiveWords), + ValueBitWidth); CurIdx += ActiveWords; // FIXME: It is not clear whether values in the range should be @@ -5985,7 +6150,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // Before weak cmpxchgs existed, the instruction simply returned the // value loaded from memory, so bitcode files from that era will be // expecting the first component of a modern cmpxchg. - CurBB->getInstList().push_back(I); + I->insertInto(CurBB, CurBB->end()); I = ExtractValueInst::Create(I, 0); ResTypeID = CmpTypeID; } else { @@ -6309,7 +6474,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { I->deleteValue(); return error("Operand bundles found with no consumer"); } - CurBB->getInstList().push_back(I); + I->insertInto(CurBB, CurBB->end()); // If this was a terminator instruction, move to the next block. if (I->isTerminator()) { @@ -6337,7 +6502,7 @@ OutOfRecordLoop: // We found at least one unresolved value. Nuke them all to avoid leaks. for (unsigned i = ModuleValueListSize, e = ValueList.size(); i != e; ++i){ if ((A = dyn_cast_or_null<Argument>(ValueList[i])) && !A->getParent()) { - A->replaceAllUsesWith(UndefValue::get(A->getType())); + A->replaceAllUsesWith(PoisonValue::get(A->getType())); delete A; } } @@ -6434,12 +6599,6 @@ Error BitcodeReader::materialize(GlobalValue *GV) { UpgradeIntrinsicCall(CI, I.second); } - // Update calls to the remangled intrinsics - for (auto &I : RemangledIntrinsics) - for (User *U : llvm::make_early_inc_range(I.first->materialized_users())) - // Don't expect any other users than call sites - cast<CallBase>(U)->setCalledFunction(I.second); - // Finish fn->subprogram upgrade for materialized functions. if (DISubprogram *SP = MDLoader->lookupSubprogramForFunction(F)) F->setSubprogram(SP); @@ -6544,12 +6703,6 @@ Error BitcodeReader::materializeModule() { I.first->eraseFromParent(); } UpgradedIntrinsics.clear(); - // Do the same for remangled intrinsics - for (auto &I : RemangledIntrinsics) { - I.first->replaceAllUsesWith(I.second); - I.first->eraseFromParent(); - } - RemangledIntrinsics.clear(); UpgradeDebugInfo(*TheModule); @@ -6566,9 +6719,10 @@ std::vector<StructType *> BitcodeReader::getIdentifiedStructTypes() const { ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader( BitstreamCursor Cursor, StringRef Strtab, ModuleSummaryIndex &TheIndex, - StringRef ModulePath, unsigned ModuleId) + StringRef ModulePath, unsigned ModuleId, + std::function<bool(GlobalValue::GUID)> IsPrevailing) : BitcodeReaderBase(std::move(Cursor), Strtab), TheIndex(TheIndex), - ModulePath(ModulePath), ModuleId(ModuleId) {} + ModulePath(ModulePath), ModuleId(ModuleId), IsPrevailing(IsPrevailing) {} void ModuleSummaryIndexBitcodeReader::addThisModule() { TheIndex.addModule(ModulePath, ModuleId); @@ -6579,10 +6733,15 @@ ModuleSummaryIndexBitcodeReader::getThisModule() { return TheIndex.getModule(ModulePath); } -std::pair<ValueInfo, GlobalValue::GUID> +template <bool AllowNullValueInfo> +std::tuple<ValueInfo, GlobalValue::GUID, GlobalValue::GUID> ModuleSummaryIndexBitcodeReader::getValueInfoFromValueId(unsigned ValueId) { auto VGI = ValueIdToValueInfoMap[ValueId]; - assert(VGI.first); + // We can have a null value info for memprof callsite info records in + // distributed ThinLTO index files when the callee function summary is not + // included in the index. The bitcode writer records 0 in that case, + // and the caller of this helper will set AllowNullValueInfo to true. + assert(AllowNullValueInfo || std::get<0>(VGI)); return VGI; } @@ -6602,11 +6761,10 @@ void ModuleSummaryIndexBitcodeReader::setValueGUID( // UseStrtab is false for legacy summary formats and value names are // created on stack. In that case we save the name in a string saver in // the index so that the value name can be recorded. - ValueIdToValueInfoMap[ValueID] = std::make_pair( + ValueIdToValueInfoMap[ValueID] = std::make_tuple( TheIndex.getOrInsertValueInfo( - ValueGUID, - UseStrtab ? ValueName : TheIndex.saveString(ValueName)), - OriginalNameID); + ValueGUID, UseStrtab ? ValueName : TheIndex.saveString(ValueName)), + OriginalNameID, ValueGUID); } // Specialized value symbol table parser used when reading module index @@ -6694,8 +6852,8 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( GlobalValue::GUID RefGUID = Record[1]; // The "original name", which is the second value of the pair will be // overriden later by a FS_COMBINED_ORIGINAL_NAME in the combined index. - ValueIdToValueInfoMap[ValueID] = - std::make_pair(TheIndex.getOrInsertValueInfo(RefGUID), RefGUID); + ValueIdToValueInfoMap[ValueID] = std::make_tuple( + TheIndex.getOrInsertValueInfo(RefGUID), RefGUID, RefGUID); break; } } @@ -6849,7 +7007,7 @@ ModuleSummaryIndexBitcodeReader::makeRefList(ArrayRef<uint64_t> Record) { std::vector<ValueInfo> Ret; Ret.reserve(Record.size()); for (uint64_t RefValueId : Record) - Ret.push_back(getValueInfoFromValueId(RefValueId).first); + Ret.push_back(std::get<0>(getValueInfoFromValueId(RefValueId))); return Ret; } @@ -6862,7 +7020,7 @@ ModuleSummaryIndexBitcodeReader::makeCallList(ArrayRef<uint64_t> Record, for (unsigned I = 0, E = Record.size(); I != E; ++I) { CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown; uint64_t RelBF = 0; - ValueInfo Callee = getValueInfoFromValueId(Record[I]).first; + ValueInfo Callee = std::get<0>(getValueInfoFromValueId(Record[I])); if (IsOldProfileFormat) { I += 1; // Skip old callsitecount field if (HasProfile) @@ -6953,7 +7111,7 @@ ModuleSummaryIndexBitcodeReader::parseParamAccesses(ArrayRef<uint64_t> Record) { for (auto &Call : ParamAccess.Calls) { Call.ParamNo = Record.front(); Record = Record.drop_front(); - Call.Callee = getValueInfoFromValueId(Record.front()).first; + Call.Callee = std::get<0>(getValueInfoFromValueId(Record.front())); Record = Record.drop_front(); Call.Offsets = ReadRange(); } @@ -6965,7 +7123,7 @@ void ModuleSummaryIndexBitcodeReader::parseTypeIdCompatibleVtableInfo( ArrayRef<uint64_t> Record, size_t &Slot, TypeIdCompatibleVtableInfo &TypeId) { uint64_t Offset = Record[Slot++]; - ValueInfo Callee = getValueInfoFromValueId(Record[Slot++]).first; + ValueInfo Callee = std::get<0>(getValueInfoFromValueId(Record[Slot++])); TypeId.push_back({Offset, Callee}); } @@ -7040,6 +7198,9 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { PendingTypeCheckedLoadConstVCalls; std::vector<FunctionSummary::ParamAccess> PendingParamAccesses; + std::vector<CallsiteInfo> PendingCallsites; + std::vector<AllocInfo> PendingAllocs; + while (true) { Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); if (!MaybeEntry) @@ -7078,8 +7239,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { case bitc::FS_VALUE_GUID: { // [valueid, refguid] uint64_t ValueID = Record[0]; GlobalValue::GUID RefGUID = Record[1]; - ValueIdToValueInfoMap[ValueID] = - std::make_pair(TheIndex.getOrInsertValueInfo(RefGUID), RefGUID); + ValueIdToValueInfoMap[ValueID] = std::make_tuple( + TheIndex.getOrInsertValueInfo(RefGUID), RefGUID, RefGUID); break; } // FS_PERMODULE: [valueid, flags, instcount, fflags, numrefs, @@ -7131,6 +7292,17 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex), IsOldProfileFormat, HasProfile, HasRelBF); setSpecialRefs(Refs, NumRORefs, NumWORefs); + auto VIAndOriginalGUID = getValueInfoFromValueId(ValueID); + // In order to save memory, only record the memprof summaries if this is + // the prevailing copy of a symbol. The linker doesn't resolve local + // linkage values so don't check whether those are prevailing. + auto LT = (GlobalValue::LinkageTypes)Flags.Linkage; + if (IsPrevailing && + !GlobalValue::isLocalLinkage(LT) && + !IsPrevailing(std::get<2>(VIAndOriginalGUID))) { + PendingCallsites.clear(); + PendingAllocs.clear(); + } auto FS = std::make_unique<FunctionSummary>( Flags, InstCount, getDecodedFFlags(RawFunFlags), /*EntryCount=*/0, std::move(Refs), std::move(Calls), std::move(PendingTypeTests), @@ -7138,11 +7310,12 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { std::move(PendingTypeCheckedLoadVCalls), std::move(PendingTypeTestAssumeConstVCalls), std::move(PendingTypeCheckedLoadConstVCalls), - std::move(PendingParamAccesses)); - auto VIAndOriginalGUID = getValueInfoFromValueId(ValueID); + std::move(PendingParamAccesses), std::move(PendingCallsites), + std::move(PendingAllocs)); FS->setModulePath(getThisModule()->first()); - FS->setOriginalName(VIAndOriginalGUID.second); - TheIndex.addGlobalValueSummary(VIAndOriginalGUID.first, std::move(FS)); + FS->setOriginalName(std::get<1>(VIAndOriginalGUID)); + TheIndex.addGlobalValueSummary(std::get<0>(VIAndOriginalGUID), + std::move(FS)); break; } // FS_ALIAS: [valueid, flags, valueid] @@ -7161,15 +7334,15 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { // ownership. AS->setModulePath(getThisModule()->first()); - auto AliaseeVI = getValueInfoFromValueId(AliaseeID).first; + auto AliaseeVI = std::get<0>(getValueInfoFromValueId(AliaseeID)); auto AliaseeInModule = TheIndex.findSummaryInModule(AliaseeVI, ModulePath); if (!AliaseeInModule) return error("Alias expects aliasee summary to be parsed"); AS->setAliasee(AliaseeVI, AliaseeInModule); auto GUID = getValueInfoFromValueId(ValueID); - AS->setOriginalName(GUID.second); - TheIndex.addGlobalValueSummary(GUID.first, std::move(AS)); + AS->setOriginalName(std::get<1>(GUID)); + TheIndex.addGlobalValueSummary(std::get<0>(GUID), std::move(AS)); break; } // FS_PERMODULE_GLOBALVAR_INIT_REFS: [valueid, flags, varflags, n x valueid] @@ -7192,8 +7365,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { std::make_unique<GlobalVarSummary>(Flags, GVF, std::move(Refs)); FS->setModulePath(getThisModule()->first()); auto GUID = getValueInfoFromValueId(ValueID); - FS->setOriginalName(GUID.second); - TheIndex.addGlobalValueSummary(GUID.first, std::move(FS)); + FS->setOriginalName(std::get<1>(GUID)); + TheIndex.addGlobalValueSummary(std::get<0>(GUID), std::move(FS)); break; } // FS_PERMODULE_VTABLE_GLOBALVAR_INIT_REFS: [valueid, flags, varflags, @@ -7211,7 +7384,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { ArrayRef<uint64_t>(Record).slice(RefListStartIndex, NumRefs)); VTableFuncList VTableFuncs; for (unsigned I = VTableListStartIndex, E = Record.size(); I != E; ++I) { - ValueInfo Callee = getValueInfoFromValueId(Record[I]).first; + ValueInfo Callee = std::get<0>(getValueInfoFromValueId(Record[I])); uint64_t Offset = Record[++I]; VTableFuncs.push_back({Callee, Offset}); } @@ -7220,8 +7393,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { VS->setModulePath(getThisModule()->first()); VS->setVTableFuncs(VTableFuncs); auto GUID = getValueInfoFromValueId(ValueID); - VS->setOriginalName(GUID.second); - TheIndex.addGlobalValueSummary(GUID.first, std::move(VS)); + VS->setOriginalName(std::get<1>(GUID)); + TheIndex.addGlobalValueSummary(std::get<0>(GUID), std::move(VS)); break; } // FS_COMBINED: [valueid, modid, flags, instcount, fflags, numrefs, @@ -7272,7 +7445,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { std::vector<FunctionSummary::EdgeTy> Edges = makeCallList( ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex), IsOldProfileFormat, HasProfile, false); - ValueInfo VI = getValueInfoFromValueId(ValueID).first; + ValueInfo VI = std::get<0>(getValueInfoFromValueId(ValueID)); setSpecialRefs(Refs, NumRORefs, NumWORefs); auto FS = std::make_unique<FunctionSummary>( Flags, InstCount, getDecodedFFlags(RawFunFlags), EntryCount, @@ -7281,7 +7454,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { std::move(PendingTypeCheckedLoadVCalls), std::move(PendingTypeTestAssumeConstVCalls), std::move(PendingTypeCheckedLoadConstVCalls), - std::move(PendingParamAccesses)); + std::move(PendingParamAccesses), std::move(PendingCallsites), + std::move(PendingAllocs)); LastSeenSummary = FS.get(); LastSeenGUID = VI.getGUID(); FS->setModulePath(ModuleIdMap[ModuleId]); @@ -7301,11 +7475,11 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { LastSeenSummary = AS.get(); AS->setModulePath(ModuleIdMap[ModuleId]); - auto AliaseeVI = getValueInfoFromValueId(AliaseeValueId).first; + auto AliaseeVI = std::get<0>(getValueInfoFromValueId(AliaseeValueId)); auto AliaseeInModule = TheIndex.findSummaryInModule(AliaseeVI, AS->modulePath()); AS->setAliasee(AliaseeVI, AliaseeInModule); - ValueInfo VI = getValueInfoFromValueId(ValueID).first; + ValueInfo VI = std::get<0>(getValueInfoFromValueId(ValueID)); LastSeenGUID = VI.getGUID(); TheIndex.addGlobalValueSummary(VI, std::move(AS)); break; @@ -7331,7 +7505,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { std::make_unique<GlobalVarSummary>(Flags, GVF, std::move(Refs)); LastSeenSummary = FS.get(); FS->setModulePath(ModuleIdMap[ModuleId]); - ValueInfo VI = getValueInfoFromValueId(ValueID).first; + ValueInfo VI = std::get<0>(getValueInfoFromValueId(ValueID)); LastSeenGUID = VI.getGUID(); TheIndex.addGlobalValueSummary(VI, std::move(FS)); break; @@ -7407,6 +7581,95 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { PendingParamAccesses = parseParamAccesses(Record); break; } + + case bitc::FS_STACK_IDS: { // [n x stackid] + // Save stack ids in the reader to consult when adding stack ids from the + // lists in the stack node and alloc node entries. + StackIds = ArrayRef<uint64_t>(Record); + break; + } + + case bitc::FS_PERMODULE_CALLSITE_INFO: { + unsigned ValueID = Record[0]; + SmallVector<unsigned> StackIdList; + for (auto R = Record.begin() + 1; R != Record.end(); R++) { + assert(*R < StackIds.size()); + StackIdList.push_back(TheIndex.addOrGetStackIdIndex(StackIds[*R])); + } + ValueInfo VI = std::get<0>(getValueInfoFromValueId(ValueID)); + PendingCallsites.push_back(CallsiteInfo({VI, std::move(StackIdList)})); + break; + } + + case bitc::FS_COMBINED_CALLSITE_INFO: { + auto RecordIter = Record.begin(); + unsigned ValueID = *RecordIter++; + unsigned NumStackIds = *RecordIter++; + unsigned NumVersions = *RecordIter++; + assert(Record.size() == 3 + NumStackIds + NumVersions); + SmallVector<unsigned> StackIdList; + for (unsigned J = 0; J < NumStackIds; J++) { + assert(*RecordIter < StackIds.size()); + StackIdList.push_back( + TheIndex.addOrGetStackIdIndex(StackIds[*RecordIter++])); + } + SmallVector<unsigned> Versions; + for (unsigned J = 0; J < NumVersions; J++) + Versions.push_back(*RecordIter++); + ValueInfo VI = std::get<0>( + getValueInfoFromValueId</*AllowNullValueInfo*/ true>(ValueID)); + PendingCallsites.push_back( + CallsiteInfo({VI, std::move(Versions), std::move(StackIdList)})); + break; + } + + case bitc::FS_PERMODULE_ALLOC_INFO: { + unsigned I = 0; + std::vector<MIBInfo> MIBs; + while (I < Record.size()) { + assert(Record.size() - I >= 2); + AllocationType AllocType = (AllocationType)Record[I++]; + unsigned NumStackEntries = Record[I++]; + assert(Record.size() - I >= NumStackEntries); + SmallVector<unsigned> StackIdList; + for (unsigned J = 0; J < NumStackEntries; J++) { + assert(Record[I] < StackIds.size()); + StackIdList.push_back( + TheIndex.addOrGetStackIdIndex(StackIds[Record[I++]])); + } + MIBs.push_back(MIBInfo(AllocType, std::move(StackIdList))); + } + PendingAllocs.push_back(AllocInfo(std::move(MIBs))); + break; + } + + case bitc::FS_COMBINED_ALLOC_INFO: { + unsigned I = 0; + std::vector<MIBInfo> MIBs; + unsigned NumMIBs = Record[I++]; + unsigned NumVersions = Record[I++]; + unsigned MIBsRead = 0; + while (MIBsRead++ < NumMIBs) { + assert(Record.size() - I >= 2); + AllocationType AllocType = (AllocationType)Record[I++]; + unsigned NumStackEntries = Record[I++]; + assert(Record.size() - I >= NumStackEntries); + SmallVector<unsigned> StackIdList; + for (unsigned J = 0; J < NumStackEntries; J++) { + assert(Record[I] < StackIds.size()); + StackIdList.push_back( + TheIndex.addOrGetStackIdIndex(StackIds[Record[I++]])); + } + MIBs.push_back(MIBInfo(AllocType, std::move(StackIdList))); + } + assert(Record.size() - I >= NumVersions); + SmallVector<uint8_t> Versions; + for (unsigned J = 0; J < NumVersions; J++) + Versions.push_back(Record[I++]); + PendingAllocs.push_back( + AllocInfo(std::move(Versions), std::move(MIBs))); + break; + } } } llvm_unreachable("Exit infinite loop"); @@ -7677,7 +7940,7 @@ llvm::getBitcodeFileContents(MemoryBufferRef Buffer) { Expected<std::unique_ptr<Module>> BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll, bool ShouldLazyLoadMetadata, bool IsImporting, - DataLayoutCallbackTy DataLayoutCallback) { + ParserCallbacks Callbacks) { BitstreamCursor Stream(Buffer); std::string ProducerIdentification; @@ -7700,7 +7963,7 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll, // Delay parsing Metadata if ShouldLazyLoadMetadata is true. if (Error Err = R->parseBitcodeInto(M.get(), ShouldLazyLoadMetadata, - IsImporting, DataLayoutCallback)) + IsImporting, Callbacks)) return std::move(Err); if (MaterializeAll) { @@ -7717,23 +7980,24 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll, Expected<std::unique_ptr<Module>> BitcodeModule::getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata, - bool IsImporting) { + bool IsImporting, ParserCallbacks Callbacks) { return getModuleImpl(Context, false, ShouldLazyLoadMetadata, IsImporting, - [](StringRef) { return None; }); + Callbacks); } // Parse the specified bitcode buffer and merge the index into CombinedIndex. // We don't use ModuleIdentifier here because the client may need to control the // 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) { +Error BitcodeModule::readSummary( + ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, uint64_t ModuleId, + 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); + ModulePath, ModuleId, IsPrevailing); return R.parseModule(); } @@ -7864,40 +8128,41 @@ static Expected<BitcodeModule> getSingleModule(MemoryBufferRef Buffer) { Expected<std::unique_ptr<Module>> llvm::getLazyBitcodeModule(MemoryBufferRef Buffer, LLVMContext &Context, - bool ShouldLazyLoadMetadata, bool IsImporting) { + bool ShouldLazyLoadMetadata, bool IsImporting, + ParserCallbacks Callbacks) { Expected<BitcodeModule> BM = getSingleModule(Buffer); if (!BM) return BM.takeError(); - return BM->getLazyModule(Context, ShouldLazyLoadMetadata, IsImporting); + return BM->getLazyModule(Context, ShouldLazyLoadMetadata, IsImporting, + Callbacks); } Expected<std::unique_ptr<Module>> llvm::getOwningLazyBitcodeModule( std::unique_ptr<MemoryBuffer> &&Buffer, LLVMContext &Context, - bool ShouldLazyLoadMetadata, bool IsImporting) { + bool ShouldLazyLoadMetadata, bool IsImporting, ParserCallbacks Callbacks) { auto MOrErr = getLazyBitcodeModule(*Buffer, Context, ShouldLazyLoadMetadata, - IsImporting); + IsImporting, Callbacks); if (MOrErr) (*MOrErr)->setOwnedMemoryBuffer(std::move(Buffer)); return MOrErr; } Expected<std::unique_ptr<Module>> -BitcodeModule::parseModule(LLVMContext &Context, - DataLayoutCallbackTy DataLayoutCallback) { - return getModuleImpl(Context, true, false, false, DataLayoutCallback); +BitcodeModule::parseModule(LLVMContext &Context, ParserCallbacks Callbacks) { + return getModuleImpl(Context, true, false, false, Callbacks); // TODO: Restore the use-lists to the in-memory state when the bitcode was // written. We must defer until the Module has been fully materialized. } Expected<std::unique_ptr<Module>> llvm::parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context, - DataLayoutCallbackTy DataLayoutCallback) { + ParserCallbacks Callbacks) { Expected<BitcodeModule> BM = getSingleModule(Buffer); if (!BM) return BM.takeError(); - return BM->parseModule(Context, DataLayoutCallback); + return BM->parseModule(Context, Callbacks); } Expected<std::string> llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer) { diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 13d53a35084d..4b5cfedaa99c 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -14,8 +14,6 @@ #include "llvm/ADT/BitmaskEnum.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -55,6 +53,7 @@ #include <deque> #include <iterator> #include <limits> +#include <optional> #include <string> #include <tuple> #include <type_traits> @@ -222,7 +221,7 @@ Metadata *BitcodeReaderMetadataList::getMetadataFwdRef(unsigned Idx) { // Create and return a placeholder, which will later be RAUW'd. ++NumMDNodeTemporary; - Metadata *MD = MDNode::getTemporary(Context, None).release(); + Metadata *MD = MDNode::getTemporary(Context, std::nullopt).release(); MetadataPtrs[Idx].reset(MD); return MD; } @@ -304,7 +303,7 @@ Metadata *BitcodeReaderMetadataList::upgradeTypeRef(Metadata *MaybeUUID) { auto &Ref = OldTypeRefs.Unknown[UUID]; if (!Ref) - Ref = MDNode::getTemporary(Context, None); + Ref = MDNode::getTemporary(Context, std::nullopt); return Ref.get(); } @@ -321,7 +320,7 @@ Metadata *BitcodeReaderMetadataList::upgradeTypeRefArray(Metadata *MaybeTuple) { // resolveTypeRefArrays() will be resolve this forward reference. OldTypeRefs.Arrays.emplace_back( std::piecewise_construct, std::forward_as_tuple(Tuple), - std::forward_as_tuple(MDTuple::getTemporary(Context, None))); + std::forward_as_tuple(MDTuple::getTemporary(Context, std::nullopt))); return OldTypeRefs.Arrays.back().second.get(); } @@ -407,7 +406,7 @@ class MetadataLoader::MetadataLoaderImpl { BitstreamCursor &Stream; LLVMContext &Context; Module &TheModule; - std::function<Type *(unsigned)> getTypeByID; + MetadataLoaderCallbacks Callbacks; /// Cursor associated with the lazy-loading of Metadata. This is the easy way /// to keep around the right "context" (Abbrev list) to be able to jump in @@ -552,7 +551,7 @@ class MetadataLoader::MetadataLoaderImpl { case 0: if (N >= 3 && Expr[N - 3] == dwarf::DW_OP_bit_piece) Expr[N - 3] = dwarf::DW_OP_LLVM_fragment; - LLVM_FALLTHROUGH; + [[fallthrough]]; case 1: // Move DW_OP_deref to the end. if (N && Expr[0] == dwarf::DW_OP_deref) { @@ -564,7 +563,7 @@ class MetadataLoader::MetadataLoaderImpl { *std::prev(End) = dwarf::DW_OP_deref; } NeedDeclareExpressionUpgrade = true; - LLVM_FALLTHROUGH; + [[fallthrough]]; case 2: { // Change DW_OP_plus to DW_OP_plus_uconst. // Change DW_OP_minus to DW_OP_uconst, DW_OP_minus @@ -613,7 +612,7 @@ class MetadataLoader::MetadataLoaderImpl { SubExpr = SubExpr.slice(HistoricSize); } Expr = MutableArrayRef<uint64_t>(Buffer); - LLVM_FALLTHROUGH; + [[fallthrough]]; } case 3: // Up-to-date! @@ -628,14 +627,15 @@ class MetadataLoader::MetadataLoaderImpl { upgradeCUVariables(); } + void callMDTypeCallback(Metadata **Val, unsigned TypeID); + public: MetadataLoaderImpl(BitstreamCursor &Stream, Module &TheModule, BitcodeReaderValueList &ValueList, - std::function<Type *(unsigned)> getTypeByID, - bool IsImporting) + MetadataLoaderCallbacks Callbacks, bool IsImporting) : MetadataList(TheModule.getContext(), Stream.SizeInBytes()), ValueList(ValueList), Stream(Stream), Context(TheModule.getContext()), - TheModule(TheModule), getTypeByID(std::move(getTypeByID)), + TheModule(TheModule), Callbacks(std::move(Callbacks)), IsImporting(IsImporting) {} Error parseMetadata(bool ModuleLevel); @@ -856,6 +856,7 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() { case bitc::METADATA_TEMPLATE_VALUE: case bitc::METADATA_GLOBAL_VAR: case bitc::METADATA_LOCAL_VAR: + case bitc::METADATA_ASSIGN_ID: case bitc::METADATA_LABEL: case bitc::METADATA_EXPRESSION: case bitc::METADATA_OBJC_PROPERTY: @@ -952,6 +953,14 @@ Expected<bool> MetadataLoader::MetadataLoaderImpl::loadGlobalDeclAttachments() { } } +void MetadataLoader::MetadataLoaderImpl::callMDTypeCallback(Metadata **Val, + unsigned TypeID) { + if (Callbacks.MDType) { + (*Callbacks.MDType)(Val, TypeID, Callbacks.GetTypeByID, + Callbacks.GetContainedTypeID); + } +} + /// Parse a METADATA_BLOCK. If ModuleLevel is true then we are parsing /// module level metadata. Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) { @@ -1211,7 +1220,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( // If this isn't a LocalAsMetadata record, we're dropping it. This used // to be legal, but there's no upgrade path. auto dropRecord = [&] { - MetadataList.assignValue(MDNode::get(Context, None), NextMetadataNo); + MetadataList.assignValue(MDNode::get(Context, std::nullopt), + NextMetadataNo); NextMetadataNo++; }; if (Record.size() != 2) { @@ -1220,7 +1230,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( } unsigned TyID = Record[0]; - Type *Ty = getTypeByID(TyID); + Type *Ty = Callbacks.GetTypeByID(TyID); if (Ty->isMetadataTy() || Ty->isVoidTy()) { dropRecord(); break; @@ -1244,7 +1254,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( SmallVector<Metadata *, 8> Elts; for (unsigned i = 0; i != Size; i += 2) { unsigned TyID = Record[i]; - Type *Ty = getTypeByID(TyID); + Type *Ty = Callbacks.GetTypeByID(TyID); if (!Ty) return error("Invalid record"); if (Ty->isMetadataTy()) @@ -1254,9 +1264,10 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( /*ConstExprInsertBB*/ nullptr); if (!V) return error("Invalid value reference from old metadata"); - auto *MD = ValueAsMetadata::get(V); + Metadata *MD = ValueAsMetadata::get(V); assert(isa<ConstantAsMetadata>(MD) && "Expected non-function-local metadata"); + callMDTypeCallback(&MD, TyID); Elts.push_back(MD); } else Elts.push_back(nullptr); @@ -1270,7 +1281,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( return error("Invalid record"); unsigned TyID = Record[0]; - Type *Ty = getTypeByID(TyID); + Type *Ty = Callbacks.GetTypeByID(TyID); if (Ty->isMetadataTy() || Ty->isVoidTy()) return error("Invalid record"); @@ -1279,13 +1290,15 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( if (!V) return error("Invalid value reference from metadata"); - MetadataList.assignValue(ValueAsMetadata::get(V), NextMetadataNo); + Metadata *MD = ValueAsMetadata::get(V); + callMDTypeCallback(&MD, TyID); + MetadataList.assignValue(MD, NextMetadataNo); NextMetadataNo++; break; } case bitc::METADATA_DISTINCT_NODE: IsDistinct = true; - LLVM_FALLTHROUGH; + [[fallthrough]]; case bitc::METADATA_NODE: { SmallVector<Metadata *, 8> Elts; Elts.reserve(Record.size()); @@ -1392,7 +1405,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( if (IsBigInt) { const uint64_t BitWidth = Record[1]; const size_t NumWords = Record.size() - 3; - Value = readWideAPInt(makeArrayRef(&Record[3], NumWords), BitWidth); + Value = readWideAPInt(ArrayRef(&Record[3], NumWords), BitWidth); } else Value = APInt(64, unrotateSign(Record[1]), !IsUnsigned); @@ -1446,7 +1459,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( // DWARF address space is encoded as N->getDWARFAddressSpace() + 1. 0 means // that there is no DWARF address space associated with DIDerivedType. - Optional<unsigned> DWARFAddressSpace; + std::optional<unsigned> DWARFAddressSpace; if (Record.size() > 12 && Record[12]) DWARFAddressSpace = Record[12] - 1; @@ -1609,7 +1622,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( return error("Invalid record"); IsDistinct = Record[0]; - Optional<DIFile::ChecksumInfo<MDString *>> Checksum; + std::optional<DIFile::ChecksumInfo<MDString *>> Checksum; // The BitcodeWriter writes null bytes into Record[3:4] when the Checksum // is not present. This matches up with the old internal representation, // and the old encoding for CSK_None in the ChecksumKind. The new @@ -1619,11 +1632,10 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( Checksum.emplace(static_cast<DIFile::ChecksumKind>(Record[3]), getMDString(Record[4])); MetadataList.assignValue( - GET_OR_DISTINCT( - DIFile, - (Context, getMDString(Record[1]), getMDString(Record[2]), Checksum, - Record.size() > 5 ? Optional<MDString *>(getMDString(Record[5])) - : None)), + GET_OR_DISTINCT(DIFile, + (Context, getMDString(Record[1]), + getMDString(Record[2]), Checksum, + Record.size() > 5 ? getMDString(Record[5]) : nullptr)), NextMetadataNo); NextMetadataNo++; break; @@ -1964,6 +1976,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } + case bitc::METADATA_ASSIGN_ID: { + if (Record.size() != 1) + return error("Invalid DIAssignID record."); + + IsDistinct = Record[0] & 1; + if (!IsDistinct) + return error("Invalid DIAssignID record. Must be distinct"); + + MetadataList.assignValue(DIAssignID::getDistinct(Context), NextMetadataNo); + NextMetadataNo++; + break; + } case bitc::METADATA_LOCAL_VAR: { // 10th field is for the obseleted 'inlinedAt:' field. if (Record.size() < 8 || Record.size() > 10) @@ -2347,9 +2371,9 @@ MetadataLoader::~MetadataLoader() = default; MetadataLoader::MetadataLoader(BitstreamCursor &Stream, Module &TheModule, BitcodeReaderValueList &ValueList, bool IsImporting, - std::function<Type *(unsigned)> getTypeByID) + MetadataLoaderCallbacks Callbacks) : Pimpl(std::make_unique<MetadataLoaderImpl>( - Stream, TheModule, ValueList, std::move(getTypeByID), IsImporting)) {} + Stream, TheModule, ValueList, std::move(Callbacks), IsImporting)) {} Error MetadataLoader::parseMetadata(bool ModuleLevel) { return Pimpl->parseMetadata(ModuleLevel); diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.h b/llvm/lib/Bitcode/Reader/MetadataLoader.h index 653f1402bead..fbee7e49f8df 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.h +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.h @@ -29,6 +29,20 @@ class Module; class Type; template <typename T> class ArrayRef; +typedef std::function<Type *(unsigned)> GetTypeByIDTy; + +typedef std::function<unsigned(unsigned, unsigned)> GetContainedTypeIDTy; + +typedef std::function<void(Metadata **, unsigned, GetTypeByIDTy, + GetContainedTypeIDTy)> + MDTypeCallbackTy; + +struct MetadataLoaderCallbacks { + GetTypeByIDTy GetTypeByID; + GetContainedTypeIDTy GetContainedTypeID; + std::optional<MDTypeCallbackTy> MDType; +}; + /// Helper class that handles loading Metadatas and keeping them available. class MetadataLoader { class MetadataLoaderImpl; @@ -39,7 +53,7 @@ public: ~MetadataLoader(); MetadataLoader(BitstreamCursor &Stream, Module &TheModule, BitcodeReaderValueList &ValueList, bool IsImporting, - std::function<Type *(unsigned)> getTypeByID); + MetadataLoaderCallbacks Callbacks); MetadataLoader &operator=(MetadataLoader &&); MetadataLoader(MetadataLoader &&); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index d7e012fb6a9e..f85fd86c114c 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -16,8 +16,6 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -78,6 +76,7 @@ #include <iterator> #include <map> #include <memory> +#include <optional> #include <string> #include <utility> #include <vector> @@ -96,7 +95,9 @@ static cl::opt<bool> WriteRelBFToSummary( "write-relbf-to-summary", cl::Hidden, cl::init(false), cl::desc("Write relative block frequency to function summary ")); +namespace llvm { extern FunctionSummary::ForceSummaryHotnessType ForceSummaryEdgesCold; +} namespace { @@ -211,12 +212,10 @@ protected: void writePerModuleGlobalValueSummary(); private: - void writePerModuleFunctionSummaryRecord(SmallVector<uint64_t, 64> &NameVals, - GlobalValueSummary *Summary, - unsigned ValueID, - unsigned FSCallsAbbrev, - unsigned FSCallsProfileAbbrev, - const Function &F); + void writePerModuleFunctionSummaryRecord( + SmallVector<uint64_t, 64> &NameVals, GlobalValueSummary *Summary, + unsigned ValueID, unsigned FSCallsAbbrev, unsigned FSCallsProfileAbbrev, + unsigned CallsiteAbbrev, unsigned AllocAbbrev, const Function &F); void writeModuleLevelReferences(const GlobalVariable &V, SmallVector<uint64_t, 64> &NameVals, unsigned FSModRefsAbbrev, @@ -340,6 +339,8 @@ private: unsigned Abbrev); void writeDIModule(const DIModule *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); + void writeDIAssignID(const DIAssignID *N, SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev); void writeDITemplateTypeParameter(const DITemplateTypeParameter *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); @@ -422,6 +423,11 @@ class IndexBitcodeWriter : public BitcodeWriterBase { /// index and a value id generated by this class to use in references. std::map<GlobalValue::GUID, unsigned> GUIDToValueIdMap; + // The sorted stack id indices actually used in the summary entries being + // written, which will be a subset of those in the full index in the case of + // distributed indexes. + std::vector<unsigned> StackIdIndices; + /// Tracks the last value id recorded in the GUIDToValueMap. unsigned GlobalValueId = 0; @@ -439,9 +445,28 @@ public: // in writing out the call graph edges. Save the mapping from GUID // to the new global value id to use when writing those edges, which // are currently saved in the index in terms of GUID. - forEachSummary([&](GVInfo I, bool) { + forEachSummary([&](GVInfo I, bool IsAliasee) { GUIDToValueIdMap[I.first] = ++GlobalValueId; + if (IsAliasee) + return; + auto *FS = dyn_cast<FunctionSummary>(I.second); + if (!FS) + return; + // Record all stack id indices actually used in the summary entries being + // written, so that we can compact them in the case of distributed ThinLTO + // indexes. + for (auto &CI : FS->callsites()) + for (auto Idx : CI.StackIdIndices) + StackIdIndices.push_back(Idx); + for (auto &AI : FS->allocs()) + for (auto &MIB : AI.MIBs) + for (auto Idx : MIB.StackIdIndices) + StackIdIndices.push_back(Idx); }); + llvm::sort(StackIdIndices); + StackIdIndices.erase( + std::unique(StackIdIndices.begin(), StackIdIndices.end()), + StackIdIndices.end()); } /// The below iterator returns the GUID and associated summary. @@ -499,10 +524,10 @@ private: void writeModStrings(); void writeCombinedGlobalValueSummary(); - Optional<unsigned> getValueId(GlobalValue::GUID ValGUID) { + std::optional<unsigned> getValueId(GlobalValue::GUID ValGUID) { auto VMI = GUIDToValueIdMap.find(ValGUID); if (VMI == GUIDToValueIdMap.end()) - return None; + return std::nullopt; return VMI->second; } @@ -579,6 +604,10 @@ static unsigned getEncodedRMWOperation(AtomicRMWInst::BinOp Op) { case AtomicRMWInst::FSub: return bitc::RMW_FSUB; case AtomicRMWInst::FMax: return bitc::RMW_FMAX; case AtomicRMWInst::FMin: return bitc::RMW_FMIN; + case AtomicRMWInst::UIncWrap: + return bitc::RMW_UINC_WRAP; + case AtomicRMWInst::UDecWrap: + return bitc::RMW_UDEC_WRAP; } } @@ -620,8 +649,6 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_ALLOC_SIZE; case Attribute::AlwaysInline: return bitc::ATTR_KIND_ALWAYS_INLINE; - case Attribute::ArgMemOnly: - return bitc::ATTR_KIND_ARGMEMONLY; case Attribute::Builtin: return bitc::ATTR_KIND_BUILTIN; case Attribute::ByVal: @@ -640,10 +667,6 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_HOT; case Attribute::ElementType: return bitc::ATTR_KIND_ELEMENTTYPE; - case Attribute::InaccessibleMemOnly: - return bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY; - case Attribute::InaccessibleMemOrArgMemOnly: - return bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY; case Attribute::InlineHint: return bitc::ATTR_KIND_INLINE_HINT; case Attribute::InReg: @@ -656,6 +679,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_ALLOCATED_POINTER; case Attribute::AllocKind: return bitc::ATTR_KIND_ALLOC_KIND; + case Attribute::Memory: + return bitc::ATTR_KIND_MEMORY; case Attribute::Naked: return bitc::ATTR_KIND_NAKED; case Attribute::Nest: @@ -698,6 +723,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_NOCF_CHECK; case Attribute::NoProfile: return bitc::ATTR_KIND_NO_PROFILE; + case Attribute::SkipProfile: + return bitc::ATTR_KIND_SKIP_PROFILE; case Attribute::NoUnwind: return bitc::ATTR_KIND_NO_UNWIND; case Attribute::NoSanitizeBounds: @@ -1029,8 +1056,20 @@ void ModuleBitcodeWriter::writeTypeTable() { TypeVals.push_back(true); break; } - case Type::DXILPointerTyID: - llvm_unreachable("DXIL pointers cannot be added to IR modules"); + case Type::TargetExtTyID: { + TargetExtType *TET = cast<TargetExtType>(T); + Code = bitc::TYPE_CODE_TARGET_TYPE; + writeStringRecord(Stream, bitc::TYPE_CODE_STRUCT_NAME, TET->getName(), + StructNameAbbrev); + TypeVals.push_back(TET->getNumTypeParameters()); + for (Type *InnerTy : TET->type_params()) + TypeVals.push_back(VE.getTypeID(InnerTy)); + for (unsigned IntParam : TET->int_params()) + TypeVals.push_back(IntParam); + break; + } + case Type::TypedPointerTyID: + llvm_unreachable("Typed pointers cannot be added to IR modules"); } // Emit the finished record. @@ -1784,7 +1823,7 @@ void ModuleBitcodeWriter::writeDIFile(const DIFile *N, } auto Source = N->getRawSource(); if (Source) - Record.push_back(VE.getMetadataOrNullID(*Source)); + Record.push_back(VE.getMetadataOrNullID(Source)); Stream.EmitRecord(bitc::METADATA_FILE, Record, Abbrev); Record.clear(); @@ -1951,6 +1990,15 @@ void ModuleBitcodeWriter::writeDIModule(const DIModule *N, Record.clear(); } +void ModuleBitcodeWriter::writeDIAssignID(const DIAssignID *N, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + // There are no arguments for this metadata type. + Record.push_back(N->isDistinct()); + Stream.EmitRecord(bitc::METADATA_ASSIGN_ID, Record, Abbrev); + Record.clear(); +} + void ModuleBitcodeWriter::writeDITemplateTypeParameter( const DITemplateTypeParameter *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { @@ -2624,7 +2672,7 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, Code = bitc::CST_CODE_CE_GEP; const auto *GO = cast<GEPOperator>(C); Record.push_back(VE.getTypeID(GO->getSourceElementType())); - if (Optional<unsigned> Idx = GO->getInRangeIndex()) { + if (std::optional<unsigned> Idx = GO->getInRangeIndex()) { Code = bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX; Record.push_back((*Idx << 1) | GO->isInBounds()); } else if (GO->isInBounds()) @@ -2981,7 +3029,7 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I, : bitc::FUNC_CODE_INST_CLEANUPPAD; pushValue(FuncletPad.getParentPad(), InstID, Vals); - unsigned NumArgOperands = FuncletPad.getNumArgOperands(); + unsigned NumArgOperands = FuncletPad.arg_size(); Vals.push_back(NumArgOperands); for (unsigned Op = 0; Op != NumArgOperands; ++Op) pushValueAndType(FuncletPad.getArgOperand(Op), InstID, Vals); @@ -3778,7 +3826,7 @@ static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream, Record.push_back(Arg.Calls.size()); for (auto &Call : Arg.Calls) { Record.push_back(Call.ParamNo); - Optional<unsigned> ValueID = GetValueID(Call.Callee); + std::optional<unsigned> ValueID = GetValueID(Call.Callee); if (!ValueID) { // If ValueID is unknown we can't drop just this call, we must drop // entire parameter. @@ -3879,20 +3927,79 @@ static void writeTypeIdCompatibleVtableSummaryRecord( } } +static void writeFunctionHeapProfileRecords( + BitstreamWriter &Stream, FunctionSummary *FS, unsigned CallsiteAbbrev, + unsigned AllocAbbrev, bool PerModule, + std::function<unsigned(const ValueInfo &VI)> GetValueID, + std::function<unsigned(unsigned)> GetStackIndex) { + SmallVector<uint64_t> Record; + + for (auto &CI : FS->callsites()) { + Record.clear(); + // Per module callsite clones should always have a single entry of + // value 0. + assert(!PerModule || (CI.Clones.size() == 1 && CI.Clones[0] == 0)); + Record.push_back(GetValueID(CI.Callee)); + if (!PerModule) { + Record.push_back(CI.StackIdIndices.size()); + Record.push_back(CI.Clones.size()); + } + for (auto Id : CI.StackIdIndices) + Record.push_back(GetStackIndex(Id)); + if (!PerModule) { + for (auto V : CI.Clones) + Record.push_back(V); + } + Stream.EmitRecord(PerModule ? bitc::FS_PERMODULE_CALLSITE_INFO + : bitc::FS_COMBINED_CALLSITE_INFO, + Record, CallsiteAbbrev); + } + + for (auto &AI : FS->allocs()) { + Record.clear(); + // Per module alloc versions should always have a single entry of + // value 0. + assert(!PerModule || (AI.Versions.size() == 1 && AI.Versions[0] == 0)); + if (!PerModule) { + Record.push_back(AI.MIBs.size()); + Record.push_back(AI.Versions.size()); + } + for (auto &MIB : AI.MIBs) { + Record.push_back((uint8_t)MIB.AllocType); + Record.push_back(MIB.StackIdIndices.size()); + for (auto Id : MIB.StackIdIndices) + Record.push_back(GetStackIndex(Id)); + } + if (!PerModule) { + for (auto V : AI.Versions) + Record.push_back(V); + } + Stream.EmitRecord(PerModule ? bitc::FS_PERMODULE_ALLOC_INFO + : bitc::FS_COMBINED_ALLOC_INFO, + Record, AllocAbbrev); + } +} + // Helper to emit a single function summary record. void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord( SmallVector<uint64_t, 64> &NameVals, GlobalValueSummary *Summary, unsigned ValueID, unsigned FSCallsAbbrev, unsigned FSCallsProfileAbbrev, - const Function &F) { + unsigned CallsiteAbbrev, unsigned AllocAbbrev, const Function &F) { NameVals.push_back(ValueID); FunctionSummary *FS = cast<FunctionSummary>(Summary); writeFunctionTypeMetadataRecords( - Stream, FS, [&](const ValueInfo &VI) -> Optional<unsigned> { + Stream, FS, [&](const ValueInfo &VI) -> std::optional<unsigned> { return {VE.getValueID(VI.getValue())}; }); + writeFunctionHeapProfileRecords( + Stream, FS, CallsiteAbbrev, AllocAbbrev, + /*PerModule*/ true, + /*GetValueId*/ [&](const ValueInfo &VI) { return getValueId(VI); }, + /*GetStackIndex*/ [&](unsigned I) { return I; }); + auto SpecialRefCnts = FS->specialRefCounts(); NameVals.push_back(getEncodedGVSummaryFlags(FS->flags())); NameVals.push_back(FS->instCount()); @@ -4004,6 +4111,16 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() { ArrayRef<uint64_t>{GVI.second, GVI.first}); } + if (!Index->stackIds().empty()) { + auto StackIdAbbv = std::make_shared<BitCodeAbbrev>(); + StackIdAbbv->Add(BitCodeAbbrevOp(bitc::FS_STACK_IDS)); + // numids x stackid + StackIdAbbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + StackIdAbbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + unsigned StackIdAbbvId = Stream.EmitAbbrev(std::move(StackIdAbbv)); + Stream.EmitRecord(bitc::FS_STACK_IDS, Index->stackIds(), StackIdAbbvId); + } + // Abbrev for FS_PERMODULE_PROFILE. auto Abbv = std::make_shared<BitCodeAbbrev>(); Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_PROFILE)); @@ -4075,6 +4192,21 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() { Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); unsigned TypeIdCompatibleVtableAbbrev = Stream.EmitAbbrev(std::move(Abbv)); + Abbv = std::make_shared<BitCodeAbbrev>(); + Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_CALLSITE_INFO)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid + // n x stackidindex + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + unsigned CallsiteAbbrev = Stream.EmitAbbrev(std::move(Abbv)); + + Abbv = std::make_shared<BitCodeAbbrev>(); + Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_ALLOC_INFO)); + // n x (alloc type, numstackids, numstackids x stackidindex) + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + unsigned AllocAbbrev = Stream.EmitAbbrev(std::move(Abbv)); + SmallVector<uint64_t, 64> NameVals; // Iterate over the list of functions instead of the Index to // ensure the ordering is stable. @@ -4093,7 +4225,8 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() { } auto *Summary = VI.getSummaryList()[0].get(); writePerModuleFunctionSummaryRecord(NameVals, Summary, VE.getValueID(&F), - FSCallsAbbrev, FSCallsProfileAbbrev, F); + FSCallsAbbrev, FSCallsProfileAbbrev, + CallsiteAbbrev, AllocAbbrev, F); } // Capture references from GlobalVariable initializers, which are outside @@ -4135,7 +4268,7 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() { /// Emit the combined summary section into the combined index file. void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { - Stream.EnterSubblock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID, 3); + Stream.EnterSubblock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID, 4); Stream.EmitRecord( bitc::FS_VERSION, ArrayRef<uint64_t>{ModuleSummaryIndex::BitcodeSummaryVersion}); @@ -4148,6 +4281,21 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { ArrayRef<uint64_t>{GVI.second, GVI.first}); } + if (!StackIdIndices.empty()) { + auto StackIdAbbv = std::make_shared<BitCodeAbbrev>(); + StackIdAbbv->Add(BitCodeAbbrevOp(bitc::FS_STACK_IDS)); + // numids x stackid + StackIdAbbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + StackIdAbbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + unsigned StackIdAbbvId = Stream.EmitAbbrev(std::move(StackIdAbbv)); + // Write the stack ids used by this index, which will be a subset of those in + // the full index in the case of distributed indexes. + std::vector<uint64_t> StackIds; + for (auto &I : StackIdIndices) + StackIds.push_back(Index.getStackIdAtIndex(I)); + Stream.EmitRecord(bitc::FS_STACK_IDS, StackIds, StackIdAbbvId); + } + // Abbrev for FS_COMBINED. auto Abbv = std::make_shared<BitCodeAbbrev>(); Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED)); @@ -4201,6 +4349,26 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid unsigned FSAliasAbbrev = Stream.EmitAbbrev(std::move(Abbv)); + Abbv = std::make_shared<BitCodeAbbrev>(); + Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED_CALLSITE_INFO)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numstackindices + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numver + // numstackindices x stackidindex, numver x version + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + unsigned CallsiteAbbrev = Stream.EmitAbbrev(std::move(Abbv)); + + Abbv = std::make_shared<BitCodeAbbrev>(); + Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED_ALLOC_INFO)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // nummib + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numver + // nummib x (alloc type, numstackids, numstackids x stackidindex), + // numver x version + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + unsigned AllocAbbrev = Stream.EmitAbbrev(std::move(Abbv)); + // The aliases are emitted as a post-pass, and will point to the value // id of the aliasee. Save them in a vector for post-processing. SmallVector<AliasSummary *, 64> Aliases; @@ -4276,7 +4444,9 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { return; } - auto GetValueId = [&](const ValueInfo &VI) -> Optional<unsigned> { + auto GetValueId = [&](const ValueInfo &VI) -> std::optional<unsigned> { + if (!VI) + return std::nullopt; return getValueId(VI.getGUID()); }; @@ -4284,6 +4454,27 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { writeFunctionTypeMetadataRecords(Stream, FS, GetValueId); getReferencedTypeIds(FS, ReferencedTypeIds); + writeFunctionHeapProfileRecords( + Stream, FS, CallsiteAbbrev, AllocAbbrev, + /*PerModule*/ false, + /*GetValueId*/ [&](const ValueInfo &VI) -> unsigned { + std::optional<unsigned> ValueID = GetValueId(VI); + // This can happen in shared index files for distributed ThinLTO if + // the callee function summary is not included. Record 0 which we + // will have to deal with conservatively when doing any kind of + // validation in the ThinLTO backends. + if (!ValueID) + return 0; + return *ValueID; + }, + /*GetStackIndex*/ [&](unsigned I) { + // Get the corresponding index into the list of StackIdIndices + // actually being written for this combined index (which may be a + // subset in the case of distributed indexes). + auto Lower = llvm::lower_bound(StackIdIndices, I); + return std::distance(StackIdIndices.begin(), Lower); + }); + NameVals.push_back(*ValueId); NameVals.push_back(Index.getModuleId(FS->modulePath())); NameVals.push_back(getEncodedGVSummaryFlags(FS->flags())); @@ -4323,7 +4514,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { for (auto &EI : FS->calls()) { // If this GUID doesn't have a value id, it doesn't have a function // summary and we don't need to record any calls to it. - Optional<unsigned> CallValueId = GetValueId(EI.first); + std::optional<unsigned> CallValueId = GetValueId(EI.first); if (!CallValueId) continue; NameVals.push_back(*CallValueId); diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/llvm/lib/Bitcode/Writer/ValueEnumerator.h index 6c3f6d4ff61e..4b45503595f6 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.h +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.h @@ -201,12 +201,12 @@ public: /// Get the MDString metadata for this block. ArrayRef<const Metadata *> getMDStrings() const { - return makeArrayRef(MDs).slice(NumModuleMDs, NumMDStrings); + return ArrayRef(MDs).slice(NumModuleMDs, NumMDStrings); } /// Get the non-MDString metadata for this block. ArrayRef<const Metadata *> getNonMDStrings() const { - return makeArrayRef(MDs).slice(NumModuleMDs).slice(NumMDStrings); + return ArrayRef(MDs).slice(NumModuleMDs).slice(NumMDStrings); } const TypeList &getTypes() const { return Types; } |