diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 61 | ||||
-rw-r--r-- | llvm/lib/Remarks/YAMLRemarkSerializer.cpp | 65 |
2 files changed, 78 insertions, 48 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 1d22ea8f294..cc85cb940e6 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1349,60 +1349,25 @@ void AsmPrinter::emitRemarksSection(Module &M) { RemarkStreamer *RS = M.getContext().getRemarkStreamer(); if (!RS) return; - const remarks::RemarkSerializer &RemarkSerializer = RS->getSerializer(); + remarks::RemarkSerializer &RemarkSerializer = RS->getSerializer(); + + StringRef FilenameRef = RS->getFilename(); + SmallString<128> Filename = FilenameRef; + sys::fs::make_absolute(Filename); + assert(!Filename.empty() && "The filename can't be empty."); + + std::string Buf; + raw_string_ostream OS(Buf); + std::unique_ptr<remarks::MetaSerializer> MetaSerializer = + RemarkSerializer.metaSerializer(OS, StringRef(Filename)); + MetaSerializer->emit(); // Switch to the right section: .remarks/__remarks. MCSection *RemarksSection = OutContext.getObjectFileInfo()->getRemarksSection(); OutStreamer->SwitchSection(RemarksSection); - // Emit the magic number. - OutStreamer->EmitBytes(remarks::Magic); - // Explicitly emit a '\0'. - OutStreamer->EmitIntValue(/*Value=*/0, /*Size=*/1); - - // Emit the version number: little-endian uint64_t. - // The version number is located at the offset 0x0 in the section. - std::array<char, 8> Version; - support::endian::write64le(Version.data(), remarks::Version); - OutStreamer->EmitBinaryData(StringRef(Version.data(), Version.size())); - - // Emit the string table in the section. - // Note: we need to use the streamer here to emit it in the section. We can't - // just use the serialize function with a raw_ostream because of the way - // MCStreamers work. - uint64_t StrTabSize = - RemarkSerializer.StrTab ? RemarkSerializer.StrTab->SerializedSize : 0; - // Emit the total size of the string table (the size itself excluded): - // little-endian uint64_t. - // The total size is located after the version number. - // Note: even if no string table is used, emit 0. - std::array<char, 8> StrTabSizeBuf; - support::endian::write64le(StrTabSizeBuf.data(), StrTabSize); - OutStreamer->EmitBinaryData( - StringRef(StrTabSizeBuf.data(), StrTabSizeBuf.size())); - - if (const Optional<remarks::StringTable> &StrTab = RemarkSerializer.StrTab) { - std::vector<StringRef> StrTabStrings = StrTab->serialize(); - // Emit a list of null-terminated strings. - // Note: the order is important here: the ID used in the remarks corresponds - // to the position of the string in the section. - for (StringRef Str : StrTabStrings) { - OutStreamer->EmitBytes(Str); - // Explicitly emit a '\0'. - OutStreamer->EmitIntValue(/*Value=*/0, /*Size=*/1); - } - } - - // Emit the null-terminated absolute path to the remark file. - // The path is located at the offset 0x4 in the section. - StringRef FilenameRef = RS->getFilename(); - SmallString<128> Filename = FilenameRef; - sys::fs::make_absolute(Filename); - assert(!Filename.empty() && "The filename can't be empty."); - OutStreamer->EmitBytes(Filename); - // Explicitly emit a '\0'. - OutStreamer->EmitIntValue(/*Value=*/0, /*Size=*/1); + OutStreamer->EmitBinaryData(OS.str()); } bool AsmPrinter::doFinalization(Module &M) { diff --git a/llvm/lib/Remarks/YAMLRemarkSerializer.cpp b/llvm/lib/Remarks/YAMLRemarkSerializer.cpp index c8a4ffe01d9..725ac15d7ea 100644 --- a/llvm/lib/Remarks/YAMLRemarkSerializer.cpp +++ b/llvm/lib/Remarks/YAMLRemarkSerializer.cpp @@ -158,3 +158,68 @@ void YAMLRemarkSerializer::emit(const Remark &Remark) { auto R = const_cast<remarks::Remark *>(&Remark); YAMLOutput << R; } + +std::unique_ptr<MetaSerializer> +YAMLRemarkSerializer::metaSerializer(raw_ostream &OS, + Optional<StringRef> ExternalFilename) { + return llvm::make_unique<YAMLMetaSerializer>(OS, ExternalFilename); +} + +std::unique_ptr<MetaSerializer> YAMLStrTabRemarkSerializer::metaSerializer( + raw_ostream &OS, Optional<StringRef> ExternalFilename) { + assert(StrTab); + return llvm::make_unique<YAMLStrTabMetaSerializer>(OS, ExternalFilename, + std::move(*StrTab)); +} + +static void emitMagic(raw_ostream &OS) { + // Emit the magic number. + OS << remarks::Magic; + // Explicitly emit a '\0'. + OS.write('\0'); +} + +static void emitVersion(raw_ostream &OS) { + // Emit the version number: little-endian uint64_t. + std::array<char, 8> Version; + support::endian::write64le(Version.data(), remarks::Version); + OS.write(Version.data(), Version.size()); +} + +static void emitStrTab(raw_ostream &OS, const Optional<StringTable> &StrTab) { + // Emit the string table in the section. + uint64_t StrTabSize = StrTab ? StrTab->SerializedSize : 0; + // Emit the total size of the string table (the size itself excluded): + // little-endian uint64_t. + // Note: even if no string table is used, emit 0. + std::array<char, 8> StrTabSizeBuf; + support::endian::write64le(StrTabSizeBuf.data(), StrTabSize); + OS.write(StrTabSizeBuf.data(), StrTabSizeBuf.size()); + if (StrTab) + StrTab->serialize(OS); +} + +static void emitExternalFile(raw_ostream &OS, StringRef Filename) { + // Emit the null-terminated absolute path to the remark file. + SmallString<128> FilenameBuf = Filename; + sys::fs::make_absolute(FilenameBuf); + assert(!FilenameBuf.empty() && "The filename can't be empty."); + OS.write(FilenameBuf.data(), FilenameBuf.size()); + OS.write('\0'); +} + +void YAMLMetaSerializer::emit() { + emitMagic(OS); + emitVersion(OS); + emitStrTab(OS, None); + if (ExternalFilename) + emitExternalFile(OS, *ExternalFilename); +} + +void YAMLStrTabMetaSerializer::emit() { + emitMagic(OS); + emitVersion(OS); + emitStrTab(OS, std::move(StrTab)); + if (ExternalFilename) + emitExternalFile(OS, *ExternalFilename); +} |