18bcb0991SDimitry Andric //===- BitstreamRemarkSerializer.cpp --------------------------------------===// 28bcb0991SDimitry Andric // 38bcb0991SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 48bcb0991SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 58bcb0991SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68bcb0991SDimitry Andric // 78bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 88bcb0991SDimitry Andric // 98bcb0991SDimitry Andric // This file provides the implementation of the LLVM bitstream remark serializer 108bcb0991SDimitry Andric // using LLVM's bitstream writer. 118bcb0991SDimitry Andric // 128bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 138bcb0991SDimitry Andric 148bcb0991SDimitry Andric #include "llvm/Remarks/BitstreamRemarkSerializer.h" 158bcb0991SDimitry Andric 168bcb0991SDimitry Andric using namespace llvm; 178bcb0991SDimitry Andric using namespace llvm::remarks; 188bcb0991SDimitry Andric 198bcb0991SDimitry Andric BitstreamRemarkSerializerHelper::BitstreamRemarkSerializerHelper( 208bcb0991SDimitry Andric BitstreamRemarkContainerType ContainerType) 21*04eeddc0SDimitry Andric : Bitstream(Encoded), ContainerType(ContainerType) {} 228bcb0991SDimitry Andric 238bcb0991SDimitry Andric static void push(SmallVectorImpl<uint64_t> &R, StringRef Str) { 24fe6060f1SDimitry Andric append_range(R, Str); 258bcb0991SDimitry Andric } 268bcb0991SDimitry Andric 278bcb0991SDimitry Andric static void setRecordName(unsigned RecordID, BitstreamWriter &Bitstream, 288bcb0991SDimitry Andric SmallVectorImpl<uint64_t> &R, StringRef Str) { 298bcb0991SDimitry Andric R.clear(); 308bcb0991SDimitry Andric R.push_back(RecordID); 318bcb0991SDimitry Andric push(R, Str); 328bcb0991SDimitry Andric Bitstream.EmitRecord(bitc::BLOCKINFO_CODE_SETRECORDNAME, R); 338bcb0991SDimitry Andric } 348bcb0991SDimitry Andric 358bcb0991SDimitry Andric static void initBlock(unsigned BlockID, BitstreamWriter &Bitstream, 368bcb0991SDimitry Andric SmallVectorImpl<uint64_t> &R, StringRef Str) { 378bcb0991SDimitry Andric R.clear(); 388bcb0991SDimitry Andric R.push_back(BlockID); 398bcb0991SDimitry Andric Bitstream.EmitRecord(bitc::BLOCKINFO_CODE_SETBID, R); 408bcb0991SDimitry Andric 418bcb0991SDimitry Andric R.clear(); 428bcb0991SDimitry Andric push(R, Str); 438bcb0991SDimitry Andric Bitstream.EmitRecord(bitc::BLOCKINFO_CODE_BLOCKNAME, R); 448bcb0991SDimitry Andric } 458bcb0991SDimitry Andric 468bcb0991SDimitry Andric void BitstreamRemarkSerializerHelper::setupMetaBlockInfo() { 478bcb0991SDimitry Andric // Setup the metadata block. 488bcb0991SDimitry Andric initBlock(META_BLOCK_ID, Bitstream, R, MetaBlockName); 498bcb0991SDimitry Andric 508bcb0991SDimitry Andric // The container information. 518bcb0991SDimitry Andric setRecordName(RECORD_META_CONTAINER_INFO, Bitstream, R, 528bcb0991SDimitry Andric MetaContainerInfoName); 538bcb0991SDimitry Andric 548bcb0991SDimitry Andric auto Abbrev = std::make_shared<BitCodeAbbrev>(); 558bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(RECORD_META_CONTAINER_INFO)); 568bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Version. 578bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Type. 588bcb0991SDimitry Andric RecordMetaContainerInfoAbbrevID = 598bcb0991SDimitry Andric Bitstream.EmitBlockInfoAbbrev(META_BLOCK_ID, Abbrev); 608bcb0991SDimitry Andric } 618bcb0991SDimitry Andric 628bcb0991SDimitry Andric void BitstreamRemarkSerializerHelper::setupMetaRemarkVersion() { 638bcb0991SDimitry Andric setRecordName(RECORD_META_REMARK_VERSION, Bitstream, R, 648bcb0991SDimitry Andric MetaRemarkVersionName); 658bcb0991SDimitry Andric 668bcb0991SDimitry Andric auto Abbrev = std::make_shared<BitCodeAbbrev>(); 678bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(RECORD_META_REMARK_VERSION)); 688bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Version. 698bcb0991SDimitry Andric RecordMetaRemarkVersionAbbrevID = 708bcb0991SDimitry Andric Bitstream.EmitBlockInfoAbbrev(META_BLOCK_ID, Abbrev); 718bcb0991SDimitry Andric } 728bcb0991SDimitry Andric 738bcb0991SDimitry Andric void BitstreamRemarkSerializerHelper::emitMetaRemarkVersion( 748bcb0991SDimitry Andric uint64_t RemarkVersion) { 758bcb0991SDimitry Andric // The remark version is emitted only if we emit remarks. 768bcb0991SDimitry Andric R.clear(); 778bcb0991SDimitry Andric R.push_back(RECORD_META_REMARK_VERSION); 788bcb0991SDimitry Andric R.push_back(RemarkVersion); 798bcb0991SDimitry Andric Bitstream.EmitRecordWithAbbrev(RecordMetaRemarkVersionAbbrevID, R); 808bcb0991SDimitry Andric } 818bcb0991SDimitry Andric 828bcb0991SDimitry Andric void BitstreamRemarkSerializerHelper::setupMetaStrTab() { 838bcb0991SDimitry Andric setRecordName(RECORD_META_STRTAB, Bitstream, R, MetaStrTabName); 848bcb0991SDimitry Andric 858bcb0991SDimitry Andric auto Abbrev = std::make_shared<BitCodeAbbrev>(); 868bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(RECORD_META_STRTAB)); 878bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Raw table. 888bcb0991SDimitry Andric RecordMetaStrTabAbbrevID = 898bcb0991SDimitry Andric Bitstream.EmitBlockInfoAbbrev(META_BLOCK_ID, Abbrev); 908bcb0991SDimitry Andric } 918bcb0991SDimitry Andric 928bcb0991SDimitry Andric void BitstreamRemarkSerializerHelper::emitMetaStrTab( 938bcb0991SDimitry Andric const StringTable &StrTab) { 948bcb0991SDimitry Andric // The string table is not emitted if we emit remarks separately. 958bcb0991SDimitry Andric R.clear(); 968bcb0991SDimitry Andric R.push_back(RECORD_META_STRTAB); 978bcb0991SDimitry Andric 988bcb0991SDimitry Andric // Serialize to a blob. 998bcb0991SDimitry Andric std::string Buf; 1008bcb0991SDimitry Andric raw_string_ostream OS(Buf); 1018bcb0991SDimitry Andric StrTab.serialize(OS); 1028bcb0991SDimitry Andric StringRef Blob = OS.str(); 1038bcb0991SDimitry Andric Bitstream.EmitRecordWithBlob(RecordMetaStrTabAbbrevID, R, Blob); 1048bcb0991SDimitry Andric } 1058bcb0991SDimitry Andric 1068bcb0991SDimitry Andric void BitstreamRemarkSerializerHelper::setupMetaExternalFile() { 1078bcb0991SDimitry Andric setRecordName(RECORD_META_EXTERNAL_FILE, Bitstream, R, MetaExternalFileName); 1088bcb0991SDimitry Andric 1098bcb0991SDimitry Andric auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1108bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(RECORD_META_EXTERNAL_FILE)); 1118bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Filename. 1128bcb0991SDimitry Andric RecordMetaExternalFileAbbrevID = 1138bcb0991SDimitry Andric Bitstream.EmitBlockInfoAbbrev(META_BLOCK_ID, Abbrev); 1148bcb0991SDimitry Andric } 1158bcb0991SDimitry Andric 1168bcb0991SDimitry Andric void BitstreamRemarkSerializerHelper::emitMetaExternalFile(StringRef Filename) { 1178bcb0991SDimitry Andric // The external file is emitted only if we emit the separate metadata. 1188bcb0991SDimitry Andric R.clear(); 1198bcb0991SDimitry Andric R.push_back(RECORD_META_EXTERNAL_FILE); 1208bcb0991SDimitry Andric Bitstream.EmitRecordWithBlob(RecordMetaExternalFileAbbrevID, R, Filename); 1218bcb0991SDimitry Andric } 1228bcb0991SDimitry Andric 1238bcb0991SDimitry Andric void BitstreamRemarkSerializerHelper::setupRemarkBlockInfo() { 1248bcb0991SDimitry Andric // Setup the remark block. 1258bcb0991SDimitry Andric initBlock(REMARK_BLOCK_ID, Bitstream, R, RemarkBlockName); 1268bcb0991SDimitry Andric 1278bcb0991SDimitry Andric // The header of a remark. 1288bcb0991SDimitry Andric { 1298bcb0991SDimitry Andric setRecordName(RECORD_REMARK_HEADER, Bitstream, R, RemarkHeaderName); 1308bcb0991SDimitry Andric 1318bcb0991SDimitry Andric auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1328bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(RECORD_REMARK_HEADER)); 1338bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Type 1348bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Remark Name 1358bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Pass name 1368bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Function name 1378bcb0991SDimitry Andric RecordRemarkHeaderAbbrevID = 1388bcb0991SDimitry Andric Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev); 1398bcb0991SDimitry Andric } 1408bcb0991SDimitry Andric 1418bcb0991SDimitry Andric // The location of a remark. 1428bcb0991SDimitry Andric { 1438bcb0991SDimitry Andric setRecordName(RECORD_REMARK_DEBUG_LOC, Bitstream, R, RemarkDebugLocName); 1448bcb0991SDimitry Andric 1458bcb0991SDimitry Andric auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1468bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(RECORD_REMARK_DEBUG_LOC)); 1478bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // File 1488bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Line 1498bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Column 1508bcb0991SDimitry Andric RecordRemarkDebugLocAbbrevID = 1518bcb0991SDimitry Andric Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev); 1528bcb0991SDimitry Andric } 1538bcb0991SDimitry Andric 1548bcb0991SDimitry Andric // The hotness of a remark. 1558bcb0991SDimitry Andric { 1568bcb0991SDimitry Andric setRecordName(RECORD_REMARK_HOTNESS, Bitstream, R, RemarkHotnessName); 1578bcb0991SDimitry Andric 1588bcb0991SDimitry Andric auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1598bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(RECORD_REMARK_HOTNESS)); 1608bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Hotness 1618bcb0991SDimitry Andric RecordRemarkHotnessAbbrevID = 1628bcb0991SDimitry Andric Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev); 1638bcb0991SDimitry Andric } 1648bcb0991SDimitry Andric 1658bcb0991SDimitry Andric // An argument entry with a debug location attached. 1668bcb0991SDimitry Andric { 1678bcb0991SDimitry Andric setRecordName(RECORD_REMARK_ARG_WITH_DEBUGLOC, Bitstream, R, 1688bcb0991SDimitry Andric RemarkArgWithDebugLocName); 1698bcb0991SDimitry Andric 1708bcb0991SDimitry Andric auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1718bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(RECORD_REMARK_ARG_WITH_DEBUGLOC)); 1728bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Key 1738bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Value 1748bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // File 1758bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Line 1768bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Column 1778bcb0991SDimitry Andric RecordRemarkArgWithDebugLocAbbrevID = 1788bcb0991SDimitry Andric Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev); 1798bcb0991SDimitry Andric } 1808bcb0991SDimitry Andric 1818bcb0991SDimitry Andric // An argument entry with no debug location attached. 1828bcb0991SDimitry Andric { 1838bcb0991SDimitry Andric setRecordName(RECORD_REMARK_ARG_WITHOUT_DEBUGLOC, Bitstream, R, 1848bcb0991SDimitry Andric RemarkArgWithoutDebugLocName); 1858bcb0991SDimitry Andric 1868bcb0991SDimitry Andric auto Abbrev = std::make_shared<BitCodeAbbrev>(); 1878bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(RECORD_REMARK_ARG_WITHOUT_DEBUGLOC)); 1888bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Key 1898bcb0991SDimitry Andric Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Value 1908bcb0991SDimitry Andric RecordRemarkArgWithoutDebugLocAbbrevID = 1918bcb0991SDimitry Andric Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev); 1928bcb0991SDimitry Andric } 1938bcb0991SDimitry Andric } 1948bcb0991SDimitry Andric 1958bcb0991SDimitry Andric void BitstreamRemarkSerializerHelper::setupBlockInfo() { 1968bcb0991SDimitry Andric // Emit magic number. 1978bcb0991SDimitry Andric for (const char C : ContainerMagic) 1988bcb0991SDimitry Andric Bitstream.Emit(static_cast<unsigned>(C), 8); 1998bcb0991SDimitry Andric 2008bcb0991SDimitry Andric Bitstream.EnterBlockInfoBlock(); 2018bcb0991SDimitry Andric 2028bcb0991SDimitry Andric // Setup the main metadata. Depending on the container type, we'll setup the 2038bcb0991SDimitry Andric // required records next. 2048bcb0991SDimitry Andric setupMetaBlockInfo(); 2058bcb0991SDimitry Andric 2068bcb0991SDimitry Andric switch (ContainerType) { 2078bcb0991SDimitry Andric case BitstreamRemarkContainerType::SeparateRemarksMeta: 2088bcb0991SDimitry Andric // Needs a string table that the separate remark file is using. 2098bcb0991SDimitry Andric setupMetaStrTab(); 2108bcb0991SDimitry Andric // Needs to know where the external remarks file is. 2118bcb0991SDimitry Andric setupMetaExternalFile(); 2128bcb0991SDimitry Andric break; 2138bcb0991SDimitry Andric case BitstreamRemarkContainerType::SeparateRemarksFile: 2148bcb0991SDimitry Andric // Contains remarks: emit the version. 2158bcb0991SDimitry Andric setupMetaRemarkVersion(); 2168bcb0991SDimitry Andric // Contains remarks: emit the remark abbrevs. 2178bcb0991SDimitry Andric setupRemarkBlockInfo(); 2188bcb0991SDimitry Andric break; 2198bcb0991SDimitry Andric case BitstreamRemarkContainerType::Standalone: 2208bcb0991SDimitry Andric // Contains remarks: emit the version. 2218bcb0991SDimitry Andric setupMetaRemarkVersion(); 2228bcb0991SDimitry Andric // Needs a string table. 2238bcb0991SDimitry Andric setupMetaStrTab(); 2248bcb0991SDimitry Andric // Contains remarks: emit the remark abbrevs. 2258bcb0991SDimitry Andric setupRemarkBlockInfo(); 2268bcb0991SDimitry Andric break; 2278bcb0991SDimitry Andric } 2288bcb0991SDimitry Andric 2298bcb0991SDimitry Andric Bitstream.ExitBlock(); 2308bcb0991SDimitry Andric } 2318bcb0991SDimitry Andric 2328bcb0991SDimitry Andric void BitstreamRemarkSerializerHelper::emitMetaBlock( 2338bcb0991SDimitry Andric uint64_t ContainerVersion, Optional<uint64_t> RemarkVersion, 2348bcb0991SDimitry Andric Optional<const StringTable *> StrTab, Optional<StringRef> Filename) { 2358bcb0991SDimitry Andric // Emit the meta block 2368bcb0991SDimitry Andric Bitstream.EnterSubblock(META_BLOCK_ID, 3); 2378bcb0991SDimitry Andric 2388bcb0991SDimitry Andric // The container version and type. 2398bcb0991SDimitry Andric R.clear(); 2408bcb0991SDimitry Andric R.push_back(RECORD_META_CONTAINER_INFO); 2418bcb0991SDimitry Andric R.push_back(ContainerVersion); 2428bcb0991SDimitry Andric R.push_back(static_cast<uint64_t>(ContainerType)); 2438bcb0991SDimitry Andric Bitstream.EmitRecordWithAbbrev(RecordMetaContainerInfoAbbrevID, R); 2448bcb0991SDimitry Andric 2458bcb0991SDimitry Andric switch (ContainerType) { 2468bcb0991SDimitry Andric case BitstreamRemarkContainerType::SeparateRemarksMeta: 2478bcb0991SDimitry Andric assert(StrTab != None && *StrTab != nullptr); 2488bcb0991SDimitry Andric emitMetaStrTab(**StrTab); 2498bcb0991SDimitry Andric assert(Filename != None); 2508bcb0991SDimitry Andric emitMetaExternalFile(*Filename); 2518bcb0991SDimitry Andric break; 2528bcb0991SDimitry Andric case BitstreamRemarkContainerType::SeparateRemarksFile: 2538bcb0991SDimitry Andric assert(RemarkVersion != None); 2548bcb0991SDimitry Andric emitMetaRemarkVersion(*RemarkVersion); 2558bcb0991SDimitry Andric break; 2568bcb0991SDimitry Andric case BitstreamRemarkContainerType::Standalone: 2578bcb0991SDimitry Andric assert(RemarkVersion != None); 2588bcb0991SDimitry Andric emitMetaRemarkVersion(*RemarkVersion); 2598bcb0991SDimitry Andric assert(StrTab != None && *StrTab != nullptr); 2608bcb0991SDimitry Andric emitMetaStrTab(**StrTab); 2618bcb0991SDimitry Andric break; 2628bcb0991SDimitry Andric } 2638bcb0991SDimitry Andric 2648bcb0991SDimitry Andric Bitstream.ExitBlock(); 2658bcb0991SDimitry Andric } 2668bcb0991SDimitry Andric 2678bcb0991SDimitry Andric void BitstreamRemarkSerializerHelper::emitRemarkBlock(const Remark &Remark, 2688bcb0991SDimitry Andric StringTable &StrTab) { 2698bcb0991SDimitry Andric Bitstream.EnterSubblock(REMARK_BLOCK_ID, 4); 2708bcb0991SDimitry Andric 2718bcb0991SDimitry Andric R.clear(); 2728bcb0991SDimitry Andric R.push_back(RECORD_REMARK_HEADER); 2738bcb0991SDimitry Andric R.push_back(static_cast<uint64_t>(Remark.RemarkType)); 2748bcb0991SDimitry Andric R.push_back(StrTab.add(Remark.RemarkName).first); 2758bcb0991SDimitry Andric R.push_back(StrTab.add(Remark.PassName).first); 2768bcb0991SDimitry Andric R.push_back(StrTab.add(Remark.FunctionName).first); 2778bcb0991SDimitry Andric Bitstream.EmitRecordWithAbbrev(RecordRemarkHeaderAbbrevID, R); 2788bcb0991SDimitry Andric 2798bcb0991SDimitry Andric if (const Optional<RemarkLocation> &Loc = Remark.Loc) { 2808bcb0991SDimitry Andric R.clear(); 2818bcb0991SDimitry Andric R.push_back(RECORD_REMARK_DEBUG_LOC); 2828bcb0991SDimitry Andric R.push_back(StrTab.add(Loc->SourceFilePath).first); 2838bcb0991SDimitry Andric R.push_back(Loc->SourceLine); 2848bcb0991SDimitry Andric R.push_back(Loc->SourceColumn); 2858bcb0991SDimitry Andric Bitstream.EmitRecordWithAbbrev(RecordRemarkDebugLocAbbrevID, R); 2868bcb0991SDimitry Andric } 2878bcb0991SDimitry Andric 2888bcb0991SDimitry Andric if (Optional<uint64_t> Hotness = Remark.Hotness) { 2898bcb0991SDimitry Andric R.clear(); 2908bcb0991SDimitry Andric R.push_back(RECORD_REMARK_HOTNESS); 2918bcb0991SDimitry Andric R.push_back(*Hotness); 2928bcb0991SDimitry Andric Bitstream.EmitRecordWithAbbrev(RecordRemarkHotnessAbbrevID, R); 2938bcb0991SDimitry Andric } 2948bcb0991SDimitry Andric 2958bcb0991SDimitry Andric for (const Argument &Arg : Remark.Args) { 2968bcb0991SDimitry Andric R.clear(); 2978bcb0991SDimitry Andric unsigned Key = StrTab.add(Arg.Key).first; 2988bcb0991SDimitry Andric unsigned Val = StrTab.add(Arg.Val).first; 2998bcb0991SDimitry Andric bool HasDebugLoc = Arg.Loc != None; 3008bcb0991SDimitry Andric R.push_back(HasDebugLoc ? RECORD_REMARK_ARG_WITH_DEBUGLOC 3018bcb0991SDimitry Andric : RECORD_REMARK_ARG_WITHOUT_DEBUGLOC); 3028bcb0991SDimitry Andric R.push_back(Key); 3038bcb0991SDimitry Andric R.push_back(Val); 3048bcb0991SDimitry Andric if (HasDebugLoc) { 3058bcb0991SDimitry Andric R.push_back(StrTab.add(Arg.Loc->SourceFilePath).first); 3068bcb0991SDimitry Andric R.push_back(Arg.Loc->SourceLine); 3078bcb0991SDimitry Andric R.push_back(Arg.Loc->SourceColumn); 3088bcb0991SDimitry Andric } 3098bcb0991SDimitry Andric Bitstream.EmitRecordWithAbbrev(HasDebugLoc 3108bcb0991SDimitry Andric ? RecordRemarkArgWithDebugLocAbbrevID 3118bcb0991SDimitry Andric : RecordRemarkArgWithoutDebugLocAbbrevID, 3128bcb0991SDimitry Andric R); 3138bcb0991SDimitry Andric } 3148bcb0991SDimitry Andric Bitstream.ExitBlock(); 3158bcb0991SDimitry Andric } 3168bcb0991SDimitry Andric 3178bcb0991SDimitry Andric void BitstreamRemarkSerializerHelper::flushToStream(raw_ostream &OS) { 3188bcb0991SDimitry Andric OS.write(Encoded.data(), Encoded.size()); 3198bcb0991SDimitry Andric Encoded.clear(); 3208bcb0991SDimitry Andric } 3218bcb0991SDimitry Andric 3228bcb0991SDimitry Andric StringRef BitstreamRemarkSerializerHelper::getBuffer() { 3238bcb0991SDimitry Andric return StringRef(Encoded.data(), Encoded.size()); 3248bcb0991SDimitry Andric } 3258bcb0991SDimitry Andric 3268bcb0991SDimitry Andric BitstreamRemarkSerializer::BitstreamRemarkSerializer(raw_ostream &OS, 3278bcb0991SDimitry Andric SerializerMode Mode) 3288bcb0991SDimitry Andric : RemarkSerializer(Format::Bitstream, OS, Mode), 3298bcb0991SDimitry Andric Helper(BitstreamRemarkContainerType::SeparateRemarksFile) { 3308bcb0991SDimitry Andric assert(Mode == SerializerMode::Separate && 3318bcb0991SDimitry Andric "For SerializerMode::Standalone, a pre-filled string table needs to " 3328bcb0991SDimitry Andric "be provided."); 3338bcb0991SDimitry Andric // We always use a string table with bitstream. 3348bcb0991SDimitry Andric StrTab.emplace(); 3358bcb0991SDimitry Andric } 3368bcb0991SDimitry Andric 3378bcb0991SDimitry Andric BitstreamRemarkSerializer::BitstreamRemarkSerializer(raw_ostream &OS, 3388bcb0991SDimitry Andric SerializerMode Mode, 3398bcb0991SDimitry Andric StringTable StrTabIn) 3408bcb0991SDimitry Andric : RemarkSerializer(Format::Bitstream, OS, Mode), 3418bcb0991SDimitry Andric Helper(Mode == SerializerMode::Separate 3428bcb0991SDimitry Andric ? BitstreamRemarkContainerType::SeparateRemarksFile 3438bcb0991SDimitry Andric : BitstreamRemarkContainerType::Standalone) { 3448bcb0991SDimitry Andric StrTab = std::move(StrTabIn); 3458bcb0991SDimitry Andric } 3468bcb0991SDimitry Andric 3478bcb0991SDimitry Andric void BitstreamRemarkSerializer::emit(const Remark &Remark) { 3488bcb0991SDimitry Andric if (!DidSetUp) { 3498bcb0991SDimitry Andric // Emit the metadata that is embedded in the remark file. 3508bcb0991SDimitry Andric // If we're in standalone mode, serialize the string table as well. 3518bcb0991SDimitry Andric bool IsStandalone = 3528bcb0991SDimitry Andric Helper.ContainerType == BitstreamRemarkContainerType::Standalone; 3538bcb0991SDimitry Andric BitstreamMetaSerializer MetaSerializer( 3548bcb0991SDimitry Andric OS, Helper, 3558bcb0991SDimitry Andric IsStandalone ? &*StrTab : Optional<const StringTable *>(None)); 3568bcb0991SDimitry Andric MetaSerializer.emit(); 3578bcb0991SDimitry Andric DidSetUp = true; 3588bcb0991SDimitry Andric } 3598bcb0991SDimitry Andric 3608bcb0991SDimitry Andric assert(DidSetUp && 3618bcb0991SDimitry Andric "The Block info block and the meta block were not emitted yet."); 3628bcb0991SDimitry Andric Helper.emitRemarkBlock(Remark, *StrTab); 3638bcb0991SDimitry Andric 3648bcb0991SDimitry Andric Helper.flushToStream(OS); 3658bcb0991SDimitry Andric } 3668bcb0991SDimitry Andric 3678bcb0991SDimitry Andric std::unique_ptr<MetaSerializer> BitstreamRemarkSerializer::metaSerializer( 3688bcb0991SDimitry Andric raw_ostream &OS, Optional<StringRef> ExternalFilename) { 3698bcb0991SDimitry Andric assert(Helper.ContainerType != 3708bcb0991SDimitry Andric BitstreamRemarkContainerType::SeparateRemarksMeta); 3718bcb0991SDimitry Andric bool IsStandalone = 3728bcb0991SDimitry Andric Helper.ContainerType == BitstreamRemarkContainerType::Standalone; 3738bcb0991SDimitry Andric return std::make_unique<BitstreamMetaSerializer>( 3748bcb0991SDimitry Andric OS, 3758bcb0991SDimitry Andric IsStandalone ? BitstreamRemarkContainerType::Standalone 3768bcb0991SDimitry Andric : BitstreamRemarkContainerType::SeparateRemarksMeta, 3778bcb0991SDimitry Andric &*StrTab, ExternalFilename); 3788bcb0991SDimitry Andric } 3798bcb0991SDimitry Andric 3808bcb0991SDimitry Andric void BitstreamMetaSerializer::emit() { 3818bcb0991SDimitry Andric Helper->setupBlockInfo(); 3828bcb0991SDimitry Andric Helper->emitMetaBlock(CurrentContainerVersion, CurrentRemarkVersion, StrTab, 3838bcb0991SDimitry Andric ExternalFilename); 3848bcb0991SDimitry Andric Helper->flushToStream(OS); 3858bcb0991SDimitry Andric } 386