184e80979SFrancis Visoiu Mistrih //===- BitstreamRemarkSerializer.cpp --------------------------------------===//
284e80979SFrancis Visoiu Mistrih //
384e80979SFrancis Visoiu Mistrih // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
484e80979SFrancis Visoiu Mistrih // See https://llvm.org/LICENSE.txt for license information.
584e80979SFrancis Visoiu Mistrih // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
684e80979SFrancis Visoiu Mistrih //
784e80979SFrancis Visoiu Mistrih //===----------------------------------------------------------------------===//
884e80979SFrancis Visoiu Mistrih //
984e80979SFrancis Visoiu Mistrih // This file provides the implementation of the LLVM bitstream remark serializer
1084e80979SFrancis Visoiu Mistrih // using LLVM's bitstream writer.
1184e80979SFrancis Visoiu Mistrih //
1284e80979SFrancis Visoiu Mistrih //===----------------------------------------------------------------------===//
1384e80979SFrancis Visoiu Mistrih 
1484e80979SFrancis Visoiu Mistrih #include "llvm/Remarks/BitstreamRemarkSerializer.h"
15*ed98c1b3Sserge-sans-paille #include "llvm/Remarks/Remark.h"
1684e80979SFrancis Visoiu Mistrih 
1784e80979SFrancis Visoiu Mistrih using namespace llvm;
1884e80979SFrancis Visoiu Mistrih using namespace llvm::remarks;
1984e80979SFrancis Visoiu Mistrih 
BitstreamRemarkSerializerHelper(BitstreamRemarkContainerType ContainerType)2084e80979SFrancis Visoiu Mistrih BitstreamRemarkSerializerHelper::BitstreamRemarkSerializerHelper(
2184e80979SFrancis Visoiu Mistrih     BitstreamRemarkContainerType ContainerType)
22b932bdf5SKazu Hirata     : Bitstream(Encoded), ContainerType(ContainerType) {}
2384e80979SFrancis Visoiu Mistrih 
push(SmallVectorImpl<uint64_t> & R,StringRef Str)2484e80979SFrancis Visoiu Mistrih static void push(SmallVectorImpl<uint64_t> &R, StringRef Str) {
250da15ea5SKazu Hirata   append_range(R, Str);
2684e80979SFrancis Visoiu Mistrih }
2784e80979SFrancis Visoiu Mistrih 
setRecordName(unsigned RecordID,BitstreamWriter & Bitstream,SmallVectorImpl<uint64_t> & R,StringRef Str)2884e80979SFrancis Visoiu Mistrih static void setRecordName(unsigned RecordID, BitstreamWriter &Bitstream,
2984e80979SFrancis Visoiu Mistrih                           SmallVectorImpl<uint64_t> &R, StringRef Str) {
3084e80979SFrancis Visoiu Mistrih   R.clear();
3184e80979SFrancis Visoiu Mistrih   R.push_back(RecordID);
3284e80979SFrancis Visoiu Mistrih   push(R, Str);
3384e80979SFrancis Visoiu Mistrih   Bitstream.EmitRecord(bitc::BLOCKINFO_CODE_SETRECORDNAME, R);
3484e80979SFrancis Visoiu Mistrih }
3584e80979SFrancis Visoiu Mistrih 
initBlock(unsigned BlockID,BitstreamWriter & Bitstream,SmallVectorImpl<uint64_t> & R,StringRef Str)3684e80979SFrancis Visoiu Mistrih static void initBlock(unsigned BlockID, BitstreamWriter &Bitstream,
3784e80979SFrancis Visoiu Mistrih                       SmallVectorImpl<uint64_t> &R, StringRef Str) {
3884e80979SFrancis Visoiu Mistrih   R.clear();
3984e80979SFrancis Visoiu Mistrih   R.push_back(BlockID);
4084e80979SFrancis Visoiu Mistrih   Bitstream.EmitRecord(bitc::BLOCKINFO_CODE_SETBID, R);
4184e80979SFrancis Visoiu Mistrih 
4284e80979SFrancis Visoiu Mistrih   R.clear();
4384e80979SFrancis Visoiu Mistrih   push(R, Str);
4484e80979SFrancis Visoiu Mistrih   Bitstream.EmitRecord(bitc::BLOCKINFO_CODE_BLOCKNAME, R);
4584e80979SFrancis Visoiu Mistrih }
4684e80979SFrancis Visoiu Mistrih 
setupMetaBlockInfo()4784e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializerHelper::setupMetaBlockInfo() {
4884e80979SFrancis Visoiu Mistrih   // Setup the metadata block.
4984e80979SFrancis Visoiu Mistrih   initBlock(META_BLOCK_ID, Bitstream, R, MetaBlockName);
5084e80979SFrancis Visoiu Mistrih 
5184e80979SFrancis Visoiu Mistrih   // The container information.
5284e80979SFrancis Visoiu Mistrih   setRecordName(RECORD_META_CONTAINER_INFO, Bitstream, R,
5384e80979SFrancis Visoiu Mistrih                 MetaContainerInfoName);
5484e80979SFrancis Visoiu Mistrih 
5584e80979SFrancis Visoiu Mistrih   auto Abbrev = std::make_shared<BitCodeAbbrev>();
5684e80979SFrancis Visoiu Mistrih   Abbrev->Add(BitCodeAbbrevOp(RECORD_META_CONTAINER_INFO));
5784e80979SFrancis Visoiu Mistrih   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Version.
5884e80979SFrancis Visoiu Mistrih   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));  // Type.
5984e80979SFrancis Visoiu Mistrih   RecordMetaContainerInfoAbbrevID =
6084e80979SFrancis Visoiu Mistrih       Bitstream.EmitBlockInfoAbbrev(META_BLOCK_ID, Abbrev);
6184e80979SFrancis Visoiu Mistrih }
6284e80979SFrancis Visoiu Mistrih 
setupMetaRemarkVersion()6384e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializerHelper::setupMetaRemarkVersion() {
6484e80979SFrancis Visoiu Mistrih   setRecordName(RECORD_META_REMARK_VERSION, Bitstream, R,
6584e80979SFrancis Visoiu Mistrih                 MetaRemarkVersionName);
6684e80979SFrancis Visoiu Mistrih 
6784e80979SFrancis Visoiu Mistrih   auto Abbrev = std::make_shared<BitCodeAbbrev>();
6884e80979SFrancis Visoiu Mistrih   Abbrev->Add(BitCodeAbbrevOp(RECORD_META_REMARK_VERSION));
6984e80979SFrancis Visoiu Mistrih   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Version.
7084e80979SFrancis Visoiu Mistrih   RecordMetaRemarkVersionAbbrevID =
7184e80979SFrancis Visoiu Mistrih       Bitstream.EmitBlockInfoAbbrev(META_BLOCK_ID, Abbrev);
7284e80979SFrancis Visoiu Mistrih }
7384e80979SFrancis Visoiu Mistrih 
emitMetaRemarkVersion(uint64_t RemarkVersion)7484e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializerHelper::emitMetaRemarkVersion(
7584e80979SFrancis Visoiu Mistrih     uint64_t RemarkVersion) {
7684e80979SFrancis Visoiu Mistrih   // The remark version is emitted only if we emit remarks.
7784e80979SFrancis Visoiu Mistrih   R.clear();
7884e80979SFrancis Visoiu Mistrih   R.push_back(RECORD_META_REMARK_VERSION);
7984e80979SFrancis Visoiu Mistrih   R.push_back(RemarkVersion);
8084e80979SFrancis Visoiu Mistrih   Bitstream.EmitRecordWithAbbrev(RecordMetaRemarkVersionAbbrevID, R);
8184e80979SFrancis Visoiu Mistrih }
8284e80979SFrancis Visoiu Mistrih 
setupMetaStrTab()8384e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializerHelper::setupMetaStrTab() {
8484e80979SFrancis Visoiu Mistrih   setRecordName(RECORD_META_STRTAB, Bitstream, R, MetaStrTabName);
8584e80979SFrancis Visoiu Mistrih 
8684e80979SFrancis Visoiu Mistrih   auto Abbrev = std::make_shared<BitCodeAbbrev>();
8784e80979SFrancis Visoiu Mistrih   Abbrev->Add(BitCodeAbbrevOp(RECORD_META_STRTAB));
8884e80979SFrancis Visoiu Mistrih   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Raw table.
8984e80979SFrancis Visoiu Mistrih   RecordMetaStrTabAbbrevID =
9084e80979SFrancis Visoiu Mistrih       Bitstream.EmitBlockInfoAbbrev(META_BLOCK_ID, Abbrev);
9184e80979SFrancis Visoiu Mistrih }
9284e80979SFrancis Visoiu Mistrih 
emitMetaStrTab(const StringTable & StrTab)9384e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializerHelper::emitMetaStrTab(
9484e80979SFrancis Visoiu Mistrih     const StringTable &StrTab) {
9584e80979SFrancis Visoiu Mistrih   // The string table is not emitted if we emit remarks separately.
9684e80979SFrancis Visoiu Mistrih   R.clear();
9784e80979SFrancis Visoiu Mistrih   R.push_back(RECORD_META_STRTAB);
9884e80979SFrancis Visoiu Mistrih 
9984e80979SFrancis Visoiu Mistrih   // Serialize to a blob.
10084e80979SFrancis Visoiu Mistrih   std::string Buf;
10184e80979SFrancis Visoiu Mistrih   raw_string_ostream OS(Buf);
10284e80979SFrancis Visoiu Mistrih   StrTab.serialize(OS);
10384e80979SFrancis Visoiu Mistrih   StringRef Blob = OS.str();
10484e80979SFrancis Visoiu Mistrih   Bitstream.EmitRecordWithBlob(RecordMetaStrTabAbbrevID, R, Blob);
10584e80979SFrancis Visoiu Mistrih }
10684e80979SFrancis Visoiu Mistrih 
setupMetaExternalFile()10784e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializerHelper::setupMetaExternalFile() {
10884e80979SFrancis Visoiu Mistrih   setRecordName(RECORD_META_EXTERNAL_FILE, Bitstream, R, MetaExternalFileName);
10984e80979SFrancis Visoiu Mistrih 
11084e80979SFrancis Visoiu Mistrih   auto Abbrev = std::make_shared<BitCodeAbbrev>();
11184e80979SFrancis Visoiu Mistrih   Abbrev->Add(BitCodeAbbrevOp(RECORD_META_EXTERNAL_FILE));
11284e80979SFrancis Visoiu Mistrih   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Filename.
11384e80979SFrancis Visoiu Mistrih   RecordMetaExternalFileAbbrevID =
11484e80979SFrancis Visoiu Mistrih       Bitstream.EmitBlockInfoAbbrev(META_BLOCK_ID, Abbrev);
11584e80979SFrancis Visoiu Mistrih }
11684e80979SFrancis Visoiu Mistrih 
emitMetaExternalFile(StringRef Filename)11784e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializerHelper::emitMetaExternalFile(StringRef Filename) {
11884e80979SFrancis Visoiu Mistrih   // The external file is emitted only if we emit the separate metadata.
11984e80979SFrancis Visoiu Mistrih   R.clear();
12084e80979SFrancis Visoiu Mistrih   R.push_back(RECORD_META_EXTERNAL_FILE);
12184e80979SFrancis Visoiu Mistrih   Bitstream.EmitRecordWithBlob(RecordMetaExternalFileAbbrevID, R, Filename);
12284e80979SFrancis Visoiu Mistrih }
12384e80979SFrancis Visoiu Mistrih 
setupRemarkBlockInfo()12484e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializerHelper::setupRemarkBlockInfo() {
12584e80979SFrancis Visoiu Mistrih   // Setup the remark block.
12684e80979SFrancis Visoiu Mistrih   initBlock(REMARK_BLOCK_ID, Bitstream, R, RemarkBlockName);
12784e80979SFrancis Visoiu Mistrih 
12884e80979SFrancis Visoiu Mistrih   // The header of a remark.
12984e80979SFrancis Visoiu Mistrih   {
13084e80979SFrancis Visoiu Mistrih     setRecordName(RECORD_REMARK_HEADER, Bitstream, R, RemarkHeaderName);
13184e80979SFrancis Visoiu Mistrih 
13284e80979SFrancis Visoiu Mistrih     auto Abbrev = std::make_shared<BitCodeAbbrev>();
13384e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(RECORD_REMARK_HEADER));
13484e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Type
13584e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Remark Name
13684e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Pass name
13784e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // Function name
13884e80979SFrancis Visoiu Mistrih     RecordRemarkHeaderAbbrevID =
13984e80979SFrancis Visoiu Mistrih         Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev);
14084e80979SFrancis Visoiu Mistrih   }
14184e80979SFrancis Visoiu Mistrih 
14284e80979SFrancis Visoiu Mistrih   // The location of a remark.
14384e80979SFrancis Visoiu Mistrih   {
14484e80979SFrancis Visoiu Mistrih     setRecordName(RECORD_REMARK_DEBUG_LOC, Bitstream, R, RemarkDebugLocName);
14584e80979SFrancis Visoiu Mistrih 
14684e80979SFrancis Visoiu Mistrih     auto Abbrev = std::make_shared<BitCodeAbbrev>();
14784e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(RECORD_REMARK_DEBUG_LOC));
14884e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7));    // File
14984e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Line
15084e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Column
15184e80979SFrancis Visoiu Mistrih     RecordRemarkDebugLocAbbrevID =
15284e80979SFrancis Visoiu Mistrih         Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev);
15384e80979SFrancis Visoiu Mistrih   }
15484e80979SFrancis Visoiu Mistrih 
15584e80979SFrancis Visoiu Mistrih   // The hotness of a remark.
15684e80979SFrancis Visoiu Mistrih   {
15784e80979SFrancis Visoiu Mistrih     setRecordName(RECORD_REMARK_HOTNESS, Bitstream, R, RemarkHotnessName);
15884e80979SFrancis Visoiu Mistrih 
15984e80979SFrancis Visoiu Mistrih     auto Abbrev = std::make_shared<BitCodeAbbrev>();
16084e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(RECORD_REMARK_HOTNESS));
16184e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Hotness
16284e80979SFrancis Visoiu Mistrih     RecordRemarkHotnessAbbrevID =
16384e80979SFrancis Visoiu Mistrih         Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev);
16484e80979SFrancis Visoiu Mistrih   }
16584e80979SFrancis Visoiu Mistrih 
16684e80979SFrancis Visoiu Mistrih   // An argument entry with a debug location attached.
16784e80979SFrancis Visoiu Mistrih   {
16884e80979SFrancis Visoiu Mistrih     setRecordName(RECORD_REMARK_ARG_WITH_DEBUGLOC, Bitstream, R,
16984e80979SFrancis Visoiu Mistrih                   RemarkArgWithDebugLocName);
17084e80979SFrancis Visoiu Mistrih 
17184e80979SFrancis Visoiu Mistrih     auto Abbrev = std::make_shared<BitCodeAbbrev>();
17284e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(RECORD_REMARK_ARG_WITH_DEBUGLOC));
17384e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7));    // Key
17484e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7));    // Value
17584e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7));    // File
17684e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Line
17784e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Column
17884e80979SFrancis Visoiu Mistrih     RecordRemarkArgWithDebugLocAbbrevID =
17984e80979SFrancis Visoiu Mistrih         Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev);
18084e80979SFrancis Visoiu Mistrih   }
18184e80979SFrancis Visoiu Mistrih 
18284e80979SFrancis Visoiu Mistrih   // An argument entry with no debug location attached.
18384e80979SFrancis Visoiu Mistrih   {
18484e80979SFrancis Visoiu Mistrih     setRecordName(RECORD_REMARK_ARG_WITHOUT_DEBUGLOC, Bitstream, R,
18584e80979SFrancis Visoiu Mistrih                   RemarkArgWithoutDebugLocName);
18684e80979SFrancis Visoiu Mistrih 
18784e80979SFrancis Visoiu Mistrih     auto Abbrev = std::make_shared<BitCodeAbbrev>();
18884e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(RECORD_REMARK_ARG_WITHOUT_DEBUGLOC));
18984e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Key
19084e80979SFrancis Visoiu Mistrih     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Value
19184e80979SFrancis Visoiu Mistrih     RecordRemarkArgWithoutDebugLocAbbrevID =
19284e80979SFrancis Visoiu Mistrih         Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev);
19384e80979SFrancis Visoiu Mistrih   }
19484e80979SFrancis Visoiu Mistrih }
19584e80979SFrancis Visoiu Mistrih 
setupBlockInfo()19684e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializerHelper::setupBlockInfo() {
19784e80979SFrancis Visoiu Mistrih   // Emit magic number.
19884e80979SFrancis Visoiu Mistrih   for (const char C : ContainerMagic)
19984e80979SFrancis Visoiu Mistrih     Bitstream.Emit(static_cast<unsigned>(C), 8);
20084e80979SFrancis Visoiu Mistrih 
20184e80979SFrancis Visoiu Mistrih   Bitstream.EnterBlockInfoBlock();
20284e80979SFrancis Visoiu Mistrih 
20384e80979SFrancis Visoiu Mistrih   // Setup the main metadata. Depending on the container type, we'll setup the
20484e80979SFrancis Visoiu Mistrih   // required records next.
20584e80979SFrancis Visoiu Mistrih   setupMetaBlockInfo();
20684e80979SFrancis Visoiu Mistrih 
20784e80979SFrancis Visoiu Mistrih   switch (ContainerType) {
20884e80979SFrancis Visoiu Mistrih   case BitstreamRemarkContainerType::SeparateRemarksMeta:
20984e80979SFrancis Visoiu Mistrih     // Needs a string table that the separate remark file is using.
21084e80979SFrancis Visoiu Mistrih     setupMetaStrTab();
21184e80979SFrancis Visoiu Mistrih     // Needs to know where the external remarks file is.
21284e80979SFrancis Visoiu Mistrih     setupMetaExternalFile();
21384e80979SFrancis Visoiu Mistrih     break;
21484e80979SFrancis Visoiu Mistrih   case BitstreamRemarkContainerType::SeparateRemarksFile:
21584e80979SFrancis Visoiu Mistrih     // Contains remarks: emit the version.
21684e80979SFrancis Visoiu Mistrih     setupMetaRemarkVersion();
21784e80979SFrancis Visoiu Mistrih     // Contains remarks: emit the remark abbrevs.
21884e80979SFrancis Visoiu Mistrih     setupRemarkBlockInfo();
21984e80979SFrancis Visoiu Mistrih     break;
22084e80979SFrancis Visoiu Mistrih   case BitstreamRemarkContainerType::Standalone:
22184e80979SFrancis Visoiu Mistrih     // Contains remarks: emit the version.
22284e80979SFrancis Visoiu Mistrih     setupMetaRemarkVersion();
22384e80979SFrancis Visoiu Mistrih     // Needs a string table.
22484e80979SFrancis Visoiu Mistrih     setupMetaStrTab();
22584e80979SFrancis Visoiu Mistrih     // Contains remarks: emit the remark abbrevs.
22684e80979SFrancis Visoiu Mistrih     setupRemarkBlockInfo();
22784e80979SFrancis Visoiu Mistrih     break;
22884e80979SFrancis Visoiu Mistrih   }
22984e80979SFrancis Visoiu Mistrih 
23084e80979SFrancis Visoiu Mistrih   Bitstream.ExitBlock();
23184e80979SFrancis Visoiu Mistrih }
23284e80979SFrancis Visoiu Mistrih 
emitMetaBlock(uint64_t ContainerVersion,Optional<uint64_t> RemarkVersion,Optional<const StringTable * > StrTab,Optional<StringRef> Filename)23384e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializerHelper::emitMetaBlock(
23484e80979SFrancis Visoiu Mistrih     uint64_t ContainerVersion, Optional<uint64_t> RemarkVersion,
23584e80979SFrancis Visoiu Mistrih     Optional<const StringTable *> StrTab, Optional<StringRef> Filename) {
23684e80979SFrancis Visoiu Mistrih   // Emit the meta block
23784e80979SFrancis Visoiu Mistrih   Bitstream.EnterSubblock(META_BLOCK_ID, 3);
23884e80979SFrancis Visoiu Mistrih 
23984e80979SFrancis Visoiu Mistrih   // The container version and type.
24084e80979SFrancis Visoiu Mistrih   R.clear();
24184e80979SFrancis Visoiu Mistrih   R.push_back(RECORD_META_CONTAINER_INFO);
24284e80979SFrancis Visoiu Mistrih   R.push_back(ContainerVersion);
24384e80979SFrancis Visoiu Mistrih   R.push_back(static_cast<uint64_t>(ContainerType));
24484e80979SFrancis Visoiu Mistrih   Bitstream.EmitRecordWithAbbrev(RecordMetaContainerInfoAbbrevID, R);
24584e80979SFrancis Visoiu Mistrih 
24684e80979SFrancis Visoiu Mistrih   switch (ContainerType) {
24784e80979SFrancis Visoiu Mistrih   case BitstreamRemarkContainerType::SeparateRemarksMeta:
24884e80979SFrancis Visoiu Mistrih     assert(StrTab != None && *StrTab != nullptr);
24984e80979SFrancis Visoiu Mistrih     emitMetaStrTab(**StrTab);
25084e80979SFrancis Visoiu Mistrih     assert(Filename != None);
25184e80979SFrancis Visoiu Mistrih     emitMetaExternalFile(*Filename);
25284e80979SFrancis Visoiu Mistrih     break;
25384e80979SFrancis Visoiu Mistrih   case BitstreamRemarkContainerType::SeparateRemarksFile:
25484e80979SFrancis Visoiu Mistrih     assert(RemarkVersion != None);
25584e80979SFrancis Visoiu Mistrih     emitMetaRemarkVersion(*RemarkVersion);
25684e80979SFrancis Visoiu Mistrih     break;
25784e80979SFrancis Visoiu Mistrih   case BitstreamRemarkContainerType::Standalone:
25884e80979SFrancis Visoiu Mistrih     assert(RemarkVersion != None);
25984e80979SFrancis Visoiu Mistrih     emitMetaRemarkVersion(*RemarkVersion);
26084e80979SFrancis Visoiu Mistrih     assert(StrTab != None && *StrTab != nullptr);
26184e80979SFrancis Visoiu Mistrih     emitMetaStrTab(**StrTab);
26284e80979SFrancis Visoiu Mistrih     break;
26384e80979SFrancis Visoiu Mistrih   }
26484e80979SFrancis Visoiu Mistrih 
26584e80979SFrancis Visoiu Mistrih   Bitstream.ExitBlock();
26684e80979SFrancis Visoiu Mistrih }
26784e80979SFrancis Visoiu Mistrih 
emitRemarkBlock(const Remark & Remark,StringTable & StrTab)26884e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializerHelper::emitRemarkBlock(const Remark &Remark,
26984e80979SFrancis Visoiu Mistrih                                                       StringTable &StrTab) {
27084e80979SFrancis Visoiu Mistrih   Bitstream.EnterSubblock(REMARK_BLOCK_ID, 4);
27184e80979SFrancis Visoiu Mistrih 
27284e80979SFrancis Visoiu Mistrih   R.clear();
27384e80979SFrancis Visoiu Mistrih   R.push_back(RECORD_REMARK_HEADER);
27484e80979SFrancis Visoiu Mistrih   R.push_back(static_cast<uint64_t>(Remark.RemarkType));
27584e80979SFrancis Visoiu Mistrih   R.push_back(StrTab.add(Remark.RemarkName).first);
27684e80979SFrancis Visoiu Mistrih   R.push_back(StrTab.add(Remark.PassName).first);
27784e80979SFrancis Visoiu Mistrih   R.push_back(StrTab.add(Remark.FunctionName).first);
27884e80979SFrancis Visoiu Mistrih   Bitstream.EmitRecordWithAbbrev(RecordRemarkHeaderAbbrevID, R);
27984e80979SFrancis Visoiu Mistrih 
28084e80979SFrancis Visoiu Mistrih   if (const Optional<RemarkLocation> &Loc = Remark.Loc) {
28184e80979SFrancis Visoiu Mistrih     R.clear();
28284e80979SFrancis Visoiu Mistrih     R.push_back(RECORD_REMARK_DEBUG_LOC);
28384e80979SFrancis Visoiu Mistrih     R.push_back(StrTab.add(Loc->SourceFilePath).first);
28484e80979SFrancis Visoiu Mistrih     R.push_back(Loc->SourceLine);
28584e80979SFrancis Visoiu Mistrih     R.push_back(Loc->SourceColumn);
28684e80979SFrancis Visoiu Mistrih     Bitstream.EmitRecordWithAbbrev(RecordRemarkDebugLocAbbrevID, R);
28784e80979SFrancis Visoiu Mistrih   }
28884e80979SFrancis Visoiu Mistrih 
28984e80979SFrancis Visoiu Mistrih   if (Optional<uint64_t> Hotness = Remark.Hotness) {
29084e80979SFrancis Visoiu Mistrih     R.clear();
29184e80979SFrancis Visoiu Mistrih     R.push_back(RECORD_REMARK_HOTNESS);
29284e80979SFrancis Visoiu Mistrih     R.push_back(*Hotness);
29384e80979SFrancis Visoiu Mistrih     Bitstream.EmitRecordWithAbbrev(RecordRemarkHotnessAbbrevID, R);
29484e80979SFrancis Visoiu Mistrih   }
29584e80979SFrancis Visoiu Mistrih 
29684e80979SFrancis Visoiu Mistrih   for (const Argument &Arg : Remark.Args) {
29784e80979SFrancis Visoiu Mistrih     R.clear();
29884e80979SFrancis Visoiu Mistrih     unsigned Key = StrTab.add(Arg.Key).first;
29984e80979SFrancis Visoiu Mistrih     unsigned Val = StrTab.add(Arg.Val).first;
30084e80979SFrancis Visoiu Mistrih     bool HasDebugLoc = Arg.Loc != None;
30184e80979SFrancis Visoiu Mistrih     R.push_back(HasDebugLoc ? RECORD_REMARK_ARG_WITH_DEBUGLOC
30284e80979SFrancis Visoiu Mistrih                             : RECORD_REMARK_ARG_WITHOUT_DEBUGLOC);
30384e80979SFrancis Visoiu Mistrih     R.push_back(Key);
30484e80979SFrancis Visoiu Mistrih     R.push_back(Val);
30584e80979SFrancis Visoiu Mistrih     if (HasDebugLoc) {
30684e80979SFrancis Visoiu Mistrih       R.push_back(StrTab.add(Arg.Loc->SourceFilePath).first);
30784e80979SFrancis Visoiu Mistrih       R.push_back(Arg.Loc->SourceLine);
30884e80979SFrancis Visoiu Mistrih       R.push_back(Arg.Loc->SourceColumn);
30984e80979SFrancis Visoiu Mistrih     }
31084e80979SFrancis Visoiu Mistrih     Bitstream.EmitRecordWithAbbrev(HasDebugLoc
31184e80979SFrancis Visoiu Mistrih                                        ? RecordRemarkArgWithDebugLocAbbrevID
31284e80979SFrancis Visoiu Mistrih                                        : RecordRemarkArgWithoutDebugLocAbbrevID,
31384e80979SFrancis Visoiu Mistrih                                    R);
31484e80979SFrancis Visoiu Mistrih   }
31584e80979SFrancis Visoiu Mistrih   Bitstream.ExitBlock();
31684e80979SFrancis Visoiu Mistrih }
31784e80979SFrancis Visoiu Mistrih 
flushToStream(raw_ostream & OS)31884e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializerHelper::flushToStream(raw_ostream &OS) {
31984e80979SFrancis Visoiu Mistrih   OS.write(Encoded.data(), Encoded.size());
32084e80979SFrancis Visoiu Mistrih   Encoded.clear();
32184e80979SFrancis Visoiu Mistrih }
32284e80979SFrancis Visoiu Mistrih 
getBuffer()32384e80979SFrancis Visoiu Mistrih StringRef BitstreamRemarkSerializerHelper::getBuffer() {
32484e80979SFrancis Visoiu Mistrih   return StringRef(Encoded.data(), Encoded.size());
32584e80979SFrancis Visoiu Mistrih }
32684e80979SFrancis Visoiu Mistrih 
BitstreamRemarkSerializer(raw_ostream & OS,SerializerMode Mode)32784e80979SFrancis Visoiu Mistrih BitstreamRemarkSerializer::BitstreamRemarkSerializer(raw_ostream &OS,
32884e80979SFrancis Visoiu Mistrih                                                      SerializerMode Mode)
32977383d83SFrancis Visoiu Mistrih     : RemarkSerializer(Format::Bitstream, OS, Mode),
33084e80979SFrancis Visoiu Mistrih       Helper(BitstreamRemarkContainerType::SeparateRemarksFile) {
33184e80979SFrancis Visoiu Mistrih   assert(Mode == SerializerMode::Separate &&
33284e80979SFrancis Visoiu Mistrih          "For SerializerMode::Standalone, a pre-filled string table needs to "
33384e80979SFrancis Visoiu Mistrih          "be provided.");
33484e80979SFrancis Visoiu Mistrih   // We always use a string table with bitstream.
33584e80979SFrancis Visoiu Mistrih   StrTab.emplace();
33684e80979SFrancis Visoiu Mistrih }
33784e80979SFrancis Visoiu Mistrih 
BitstreamRemarkSerializer(raw_ostream & OS,SerializerMode Mode,StringTable StrTabIn)33884e80979SFrancis Visoiu Mistrih BitstreamRemarkSerializer::BitstreamRemarkSerializer(raw_ostream &OS,
33984e80979SFrancis Visoiu Mistrih                                                      SerializerMode Mode,
34084e80979SFrancis Visoiu Mistrih                                                      StringTable StrTabIn)
34177383d83SFrancis Visoiu Mistrih     : RemarkSerializer(Format::Bitstream, OS, Mode),
34284e80979SFrancis Visoiu Mistrih       Helper(Mode == SerializerMode::Separate
34384e80979SFrancis Visoiu Mistrih                  ? BitstreamRemarkContainerType::SeparateRemarksFile
34484e80979SFrancis Visoiu Mistrih                  : BitstreamRemarkContainerType::Standalone) {
34584e80979SFrancis Visoiu Mistrih   StrTab = std::move(StrTabIn);
34684e80979SFrancis Visoiu Mistrih }
34784e80979SFrancis Visoiu Mistrih 
emit(const Remark & Remark)34884e80979SFrancis Visoiu Mistrih void BitstreamRemarkSerializer::emit(const Remark &Remark) {
34984e80979SFrancis Visoiu Mistrih   if (!DidSetUp) {
35084e80979SFrancis Visoiu Mistrih     // Emit the metadata that is embedded in the remark file.
35184e80979SFrancis Visoiu Mistrih     // If we're in standalone mode, serialize the string table as well.
35284e80979SFrancis Visoiu Mistrih     bool IsStandalone =
35384e80979SFrancis Visoiu Mistrih         Helper.ContainerType == BitstreamRemarkContainerType::Standalone;
35484e80979SFrancis Visoiu Mistrih     BitstreamMetaSerializer MetaSerializer(
35584e80979SFrancis Visoiu Mistrih         OS, Helper,
35684e80979SFrancis Visoiu Mistrih         IsStandalone ? &*StrTab : Optional<const StringTable *>(None));
35784e80979SFrancis Visoiu Mistrih     MetaSerializer.emit();
35884e80979SFrancis Visoiu Mistrih     DidSetUp = true;
35984e80979SFrancis Visoiu Mistrih   }
36084e80979SFrancis Visoiu Mistrih 
36184e80979SFrancis Visoiu Mistrih   assert(DidSetUp &&
36284e80979SFrancis Visoiu Mistrih          "The Block info block and the meta block were not emitted yet.");
36384e80979SFrancis Visoiu Mistrih   Helper.emitRemarkBlock(Remark, *StrTab);
36484e80979SFrancis Visoiu Mistrih 
36584e80979SFrancis Visoiu Mistrih   Helper.flushToStream(OS);
36684e80979SFrancis Visoiu Mistrih }
36784e80979SFrancis Visoiu Mistrih 
metaSerializer(raw_ostream & OS,Optional<StringRef> ExternalFilename)36884e80979SFrancis Visoiu Mistrih std::unique_ptr<MetaSerializer> BitstreamRemarkSerializer::metaSerializer(
36984e80979SFrancis Visoiu Mistrih     raw_ostream &OS, Optional<StringRef> ExternalFilename) {
37084e80979SFrancis Visoiu Mistrih   assert(Helper.ContainerType !=
37184e80979SFrancis Visoiu Mistrih          BitstreamRemarkContainerType::SeparateRemarksMeta);
37284e80979SFrancis Visoiu Mistrih   bool IsStandalone =
37384e80979SFrancis Visoiu Mistrih       Helper.ContainerType == BitstreamRemarkContainerType::Standalone;
3740eaee545SJonas Devlieghere   return std::make_unique<BitstreamMetaSerializer>(
37584e80979SFrancis Visoiu Mistrih       OS,
37684e80979SFrancis Visoiu Mistrih       IsStandalone ? BitstreamRemarkContainerType::Standalone
37784e80979SFrancis Visoiu Mistrih                    : BitstreamRemarkContainerType::SeparateRemarksMeta,
37884e80979SFrancis Visoiu Mistrih       &*StrTab, ExternalFilename);
37984e80979SFrancis Visoiu Mistrih }
38084e80979SFrancis Visoiu Mistrih 
emit()38184e80979SFrancis Visoiu Mistrih void BitstreamMetaSerializer::emit() {
38284e80979SFrancis Visoiu Mistrih   Helper->setupBlockInfo();
38384e80979SFrancis Visoiu Mistrih   Helper->emitMetaBlock(CurrentContainerVersion, CurrentRemarkVersion, StrTab,
38484e80979SFrancis Visoiu Mistrih                         ExternalFilename);
38584e80979SFrancis Visoiu Mistrih   Helper->flushToStream(OS);
38684e80979SFrancis Visoiu Mistrih }
387