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