summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp61
-rw-r--r--llvm/lib/Remarks/YAMLRemarkSerializer.cpp65
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);
+}
OpenPOWER on IntegriCloud