diff options
| author | Francis Visoiu Mistrih <francisvm@yahoo.com> | 2019-07-23 20:42:46 +0000 |
|---|---|---|
| committer | Francis Visoiu Mistrih <francisvm@yahoo.com> | 2019-07-23 20:42:46 +0000 |
| commit | c5b5cc4575452463360a16c80e1fce25e7e06d31 (patch) | |
| tree | c64566e7104697f2b13f9e57bbf0ff2110516d4f /llvm | |
| parent | 70795c1e3a7fd1172ba31954da02b75db71af388 (diff) | |
| download | bcm5719-llvm-c5b5cc4575452463360a16c80e1fce25e7e06d31.tar.gz bcm5719-llvm-c5b5cc4575452463360a16c80e1fce25e7e06d31.zip | |
[Remarks] Introduce a new format: yaml-strtab
This exposes better support to use a string table with a format through
an actual new remark::Format, called yaml-strtab.
This can now be used with -fsave-optimization-record=yaml-strtab.
llvm-svn: 366849
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/docs/Remarks.rst | 29 | ||||
| -rw-r--r-- | llvm/include/llvm/Remarks/RemarkFormat.h | 2 | ||||
| -rw-r--r-- | llvm/include/llvm/Remarks/RemarkParser.h | 5 | ||||
| -rw-r--r-- | llvm/include/llvm/Remarks/RemarkSerializer.h | 3 | ||||
| -rw-r--r-- | llvm/include/llvm/Remarks/YAMLRemarkSerializer.h | 13 | ||||
| -rw-r--r-- | llvm/lib/IR/RemarkStreamer.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Remarks/RemarkFormat.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/Remarks/RemarkParser.cpp | 28 | ||||
| -rw-r--r-- | llvm/lib/Remarks/YAMLRemarkParser.cpp | 46 | ||||
| -rw-r--r-- | llvm/lib/Remarks/YAMLRemarkParser.h | 22 | ||||
| -rw-r--r-- | llvm/lib/Remarks/YAMLRemarkSerializer.cpp | 11 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/remarks-section.ll | 2 | ||||
| -rw-r--r-- | llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp | 4 | ||||
| -rw-r--r-- | llvm/unittests/Remarks/YAMLRemarksSerializerTest.cpp | 15 |
14 files changed, 134 insertions, 51 deletions
diff --git a/llvm/docs/Remarks.rst b/llvm/docs/Remarks.rst index e3d088d777d..56465476d01 100644 --- a/llvm/docs/Remarks.rst +++ b/llvm/docs/Remarks.rst @@ -112,6 +112,7 @@ following options: Supported formats: * :ref:`yaml <yamlremarks>` (default) + * :ref:`yaml-strtab <yamlstrtabremarks>` ``Content configuration`` @@ -191,12 +192,40 @@ fields are required: * ``<arg-line>`` * ``<arg-column>`` +.. _yamlstrtabremarks: + +YAML with a string table +------------------------ + +The YAML serialization supports the usage of a string table by using the +``yaml-strtab`` format. + +This format replaces strings in the YAML output with integers representing the +index in the string table that can be provided separately through metadata. + +The following entries can take advantage of the string table while respecting +YAML rules: + +* ``<pass>`` +* ``<name>`` +* ``<function>`` +* ``<file>`` +* ``<value>`` +* ``<arg-file>`` + +Currently, none of the tools in :ref:`the opt-viewer directory <optviewer>` +support this format. + +.. _optviewer: + opt-viewer ========== The ``opt-viewer`` directory contains a collection of tools that visualize and summarize serialized remarks. +The tools only support the ``yaml`` format. + .. _optviewerpy: opt-viewer.py diff --git a/llvm/include/llvm/Remarks/RemarkFormat.h b/llvm/include/llvm/Remarks/RemarkFormat.h index e167d99d251..87f5fa24a45 100644 --- a/llvm/include/llvm/Remarks/RemarkFormat.h +++ b/llvm/include/llvm/Remarks/RemarkFormat.h @@ -22,7 +22,7 @@ namespace remarks { constexpr StringRef Magic("REMARKS", 7); /// The format used for serializing/deserializing remarks. -enum class Format { Unknown, YAML }; +enum class Format { Unknown, YAML, YAMLStrTab }; /// Parse and validate a string for the remark format. Expected<Format> parseFormat(StringRef FormatStr); diff --git a/llvm/include/llvm/Remarks/RemarkParser.h b/llvm/include/llvm/Remarks/RemarkParser.h index 671e1abe5ec..eb827d130fa 100644 --- a/llvm/include/llvm/Remarks/RemarkParser.h +++ b/llvm/include/llvm/Remarks/RemarkParser.h @@ -67,9 +67,12 @@ struct ParsedStringTable { ParsedStringTable(StringRef Buffer); }; +Expected<std::unique_ptr<Parser>> createRemarkParser(Format ParserFormat, + StringRef Buf); + Expected<std::unique_ptr<Parser>> createRemarkParser(Format ParserFormat, StringRef Buf, - Optional<const ParsedStringTable *> StrTab = None); + const ParsedStringTable &StrTab); } // end namespace remarks } // end namespace llvm diff --git a/llvm/include/llvm/Remarks/RemarkSerializer.h b/llvm/include/llvm/Remarks/RemarkSerializer.h index 3eddac41cb0..bcf63814b5b 100644 --- a/llvm/include/llvm/Remarks/RemarkSerializer.h +++ b/llvm/include/llvm/Remarks/RemarkSerializer.h @@ -36,9 +36,6 @@ struct Serializer { virtual void emit(const Remark &Remark) = 0; }; -/// Wether the serializer should use a string table while emitting. -enum class UseStringTable { No, Yes }; - } // end namespace remarks } // end namespace llvm diff --git a/llvm/include/llvm/Remarks/YAMLRemarkSerializer.h b/llvm/include/llvm/Remarks/YAMLRemarkSerializer.h index 5b817321ce9..9bb5c6e83ed 100644 --- a/llvm/include/llvm/Remarks/YAMLRemarkSerializer.h +++ b/llvm/include/llvm/Remarks/YAMLRemarkSerializer.h @@ -34,13 +34,22 @@ struct YAMLSerializer : public Serializer { /// The YAML streamer. yaml::Output YAMLOutput; - YAMLSerializer(raw_ostream &OS, - UseStringTable UseStringTable = remarks::UseStringTable::No); + YAMLSerializer(raw_ostream &OS); /// Emit a remark to the stream. void emit(const Remark &Remark) override; }; +/// Serialize the remarks to YAML using a string table. An remark entry looks +/// like the regular YAML remark but instead of string entries it's using +/// numbers that map to an index in the string table. +struct YAMLStrTabSerializer : public YAMLSerializer { + YAMLStrTabSerializer(raw_ostream &OS) : YAMLSerializer(OS) { + // Having a string table set up enables the serializer to use it. + StrTab.emplace(); + } +}; + } // end namespace remarks } // end namespace llvm diff --git a/llvm/lib/IR/RemarkStreamer.cpp b/llvm/lib/IR/RemarkStreamer.cpp index 9470f3ea4f9..c71487dbd3b 100644 --- a/llvm/lib/IR/RemarkStreamer.cpp +++ b/llvm/lib/IR/RemarkStreamer.cpp @@ -110,11 +110,13 @@ char RemarkSetupFormatError::ID = 0; static std::unique_ptr<remarks::Serializer> formatToSerializer(remarks::Format RemarksFormat, raw_ostream &OS) { switch (RemarksFormat) { - default: + case remarks::Format::Unknown: llvm_unreachable("Unknown remark serializer format."); return nullptr; case remarks::Format::YAML: return llvm::make_unique<remarks::YAMLSerializer>(OS); + case remarks::Format::YAMLStrTab: + return llvm::make_unique<remarks::YAMLStrTabSerializer>(OS); }; } diff --git a/llvm/lib/Remarks/RemarkFormat.cpp b/llvm/lib/Remarks/RemarkFormat.cpp index bcd0f753ff6..4e9ada63188 100644 --- a/llvm/lib/Remarks/RemarkFormat.cpp +++ b/llvm/lib/Remarks/RemarkFormat.cpp @@ -19,6 +19,7 @@ using namespace llvm::remarks; Expected<Format> llvm::remarks::parseFormat(StringRef FormatStr) { auto Result = StringSwitch<Format>(FormatStr) .Cases("", "yaml", Format::YAML) + .Cases("", "yaml-strtab", Format::YAMLStrTab) .Default(Format::Unknown); if (Result == Format::Unknown) diff --git a/llvm/lib/Remarks/RemarkParser.cpp b/llvm/lib/Remarks/RemarkParser.cpp index f67464073bd..96a4b42e813 100644 --- a/llvm/lib/Remarks/RemarkParser.cpp +++ b/llvm/lib/Remarks/RemarkParser.cpp @@ -48,16 +48,34 @@ Expected<StringRef> ParsedStringTable::operator[](size_t Index) const { } Expected<std::unique_ptr<Parser>> +llvm::remarks::createRemarkParser(Format ParserFormat, StringRef Buf) { + switch (ParserFormat) { + case Format::YAML: + return llvm::make_unique<YAMLRemarkParser>(Buf); + case Format::YAMLStrTab: + return createStringError( + std::make_error_code(std::errc::invalid_argument), + "The YAML with string table format requires a parsed string table."); + case Format::Unknown: + return createStringError(std::make_error_code(std::errc::invalid_argument), + "Unknown remark parser format."); + } +} + +Expected<std::unique_ptr<Parser>> llvm::remarks::createRemarkParser(Format ParserFormat, StringRef Buf, - Optional<const ParsedStringTable *> StrTab) { + const ParsedStringTable &StrTab) { switch (ParserFormat) { case Format::YAML: - return llvm::make_unique<YAMLRemarkParser>(Buf, StrTab); + return createStringError(std::make_error_code(std::errc::invalid_argument), + "The YAML format can't be used with a string " + "table. Use yaml-strtab instead."); + case Format::YAMLStrTab: + return llvm::make_unique<YAMLStrTabRemarkParser>(Buf, StrTab); case Format::Unknown: return createStringError(std::make_error_code(std::errc::invalid_argument), "Unknown remark parser format."); } - llvm_unreachable("unknown format"); } // Wrapper that holds the state needed to interact with the C API. @@ -67,7 +85,9 @@ struct CParser { CParser(Format ParserFormat, StringRef Buf, Optional<const ParsedStringTable *> StrTab = None) - : TheParser(cantFail(createRemarkParser(ParserFormat, Buf, StrTab))) {} + : TheParser(cantFail(StrTab + ? createRemarkParser(ParserFormat, Buf, **StrTab) + : createRemarkParser(ParserFormat, Buf))) {} void handleError(Error E) { Err.emplace(toString(std::move(E))); } bool hasError() const { return Err.hasValue(); } diff --git a/llvm/lib/Remarks/YAMLRemarkParser.cpp b/llvm/lib/Remarks/YAMLRemarkParser.cpp index ed78b7ba5d9..3cbb4932e0a 100644 --- a/llvm/lib/Remarks/YAMLRemarkParser.cpp +++ b/llvm/lib/Remarks/YAMLRemarkParser.cpp @@ -54,6 +54,9 @@ static SourceMgr setupSM(std::string &LastErrorMessage) { return SM; } +YAMLRemarkParser::YAMLRemarkParser(StringRef Buf) + : YAMLRemarkParser(Buf, None) {} + YAMLRemarkParser::YAMLRemarkParser(StringRef Buf, Optional<const ParsedStringTable *> StrTab) : Parser{Format::YAML}, StrTab(StrTab), LastErrorMessage(), @@ -179,22 +182,7 @@ Expected<StringRef> YAMLRemarkParser::parseStr(yaml::KeyValueNode &Node) { auto *Value = dyn_cast<yaml::ScalarNode>(Node.getValue()); if (!Value) return error("expected a value of scalar type.", Node); - StringRef Result; - if (!StrTab) { - Result = Value->getRawValue(); - } else { - // If we have a string table, parse it as an unsigned. - unsigned StrID = 0; - if (Expected<unsigned> MaybeStrID = parseUnsigned(Node)) - StrID = *MaybeStrID; - else - return MaybeStrID.takeError(); - - if (Expected<StringRef> Str = (**StrTab)[StrID]) - Result = *Str; - else - return Str.takeError(); - } + StringRef Result = Value->getRawValue(); if (Result.front() == '\'') Result = Result.drop_front(); @@ -325,3 +313,29 @@ Expected<std::unique_ptr<Remark>> YAMLRemarkParser::next() { return std::move(*MaybeResult); } + +Expected<StringRef> YAMLStrTabRemarkParser::parseStr(yaml::KeyValueNode &Node) { + auto *Value = dyn_cast<yaml::ScalarNode>(Node.getValue()); + if (!Value) + return error("expected a value of scalar type.", Node); + StringRef Result; + // If we have a string table, parse it as an unsigned. + unsigned StrID = 0; + if (Expected<unsigned> MaybeStrID = parseUnsigned(Node)) + StrID = *MaybeStrID; + else + return MaybeStrID.takeError(); + + if (Expected<StringRef> Str = (**StrTab)[StrID]) + Result = *Str; + else + return Str.takeError(); + + if (Result.front() == '\'') + Result = Result.drop_front(); + + if (Result.back() == '\'') + Result = Result.drop_back(); + + return Result; +} diff --git a/llvm/lib/Remarks/YAMLRemarkParser.h b/llvm/lib/Remarks/YAMLRemarkParser.h index cea76e63e75..82a86fa780a 100644 --- a/llvm/lib/Remarks/YAMLRemarkParser.h +++ b/llvm/lib/Remarks/YAMLRemarkParser.h @@ -59,8 +59,7 @@ struct YAMLRemarkParser : public Parser { /// Iterator in the YAML stream. yaml::document_iterator YAMLIt; - YAMLRemarkParser(StringRef Buf, - Optional<const ParsedStringTable *> StrTab = None); + YAMLRemarkParser(StringRef Buf); Expected<std::unique_ptr<Remark>> next() override; @@ -68,7 +67,8 @@ struct YAMLRemarkParser : public Parser { return P->ParserFormat == Format::YAML; } -private: +protected: + YAMLRemarkParser(StringRef Buf, Optional<const ParsedStringTable *> StrTab); /// Create a YAMLParseError error from an existing error generated by the YAML /// parser. /// If there is no error, this returns Success. @@ -82,7 +82,7 @@ private: /// Parse one key to a string. Expected<StringRef> parseKey(yaml::KeyValueNode &Node); /// Parse one value to a string. - Expected<StringRef> parseStr(yaml::KeyValueNode &Node); + virtual Expected<StringRef> parseStr(yaml::KeyValueNode &Node); /// Parse one value to an unsigned. Expected<unsigned> parseUnsigned(yaml::KeyValueNode &Node); /// Parse a debug location. @@ -90,6 +90,20 @@ private: /// Parse an argument. Expected<Argument> parseArg(yaml::Node &Node); }; + +/// YAML with a string table to Remark parser. +struct YAMLStrTabRemarkParser : public YAMLRemarkParser { + YAMLStrTabRemarkParser(StringRef Buf, const ParsedStringTable &StrTab) + : YAMLRemarkParser(Buf, &StrTab) {} + + static bool classof(const Parser *P) { + return P->ParserFormat == Format::YAMLStrTab; + } + +protected: + /// Parse one value to a string. + Expected<StringRef> parseStr(yaml::KeyValueNode &Node) override; +}; } // end namespace remarks } // end namespace llvm diff --git a/llvm/lib/Remarks/YAMLRemarkSerializer.cpp b/llvm/lib/Remarks/YAMLRemarkSerializer.cpp index e4379748248..1297fbc9843 100644 --- a/llvm/lib/Remarks/YAMLRemarkSerializer.cpp +++ b/llvm/lib/Remarks/YAMLRemarkSerializer.cpp @@ -17,10 +17,6 @@ using namespace llvm; using namespace llvm::remarks; -cl::opt<bool> RemarksYAMLStringTable( - "remarks-yaml-string-table", cl::init(false), cl::Hidden, - cl::desc("Enable the usage of a string table with YAML remarks.")); - // Use the same keys whether we use a string table or not (respectively, T is an // unsigned or a StringRef). template <typename T> @@ -153,11 +149,8 @@ template <> struct MappingTraits<Argument> { LLVM_YAML_IS_SEQUENCE_VECTOR(Argument) -YAMLSerializer::YAMLSerializer(raw_ostream &OS, UseStringTable UseStringTable) - : Serializer(OS), YAMLOutput(OS, reinterpret_cast<void *>(this)) { - if (UseStringTable == remarks::UseStringTable::Yes || RemarksYAMLStringTable) - StrTab.emplace(); -} +YAMLSerializer::YAMLSerializer(raw_ostream &OS) + : Serializer(OS), YAMLOutput(OS, reinterpret_cast<void *>(this)) {} void YAMLSerializer::emit(const Remark &Remark) { // Again, YAMLTraits expect a non-const object for inputting, but we're not diff --git a/llvm/test/CodeGen/X86/remarks-section.ll b/llvm/test/CodeGen/X86/remarks-section.ll index 6d7957a1625..3ff2fb2b9b1 100644 --- a/llvm/test/CodeGen/X86/remarks-section.ll +++ b/llvm/test/CodeGen/X86/remarks-section.ll @@ -1,6 +1,6 @@ ; RUN: llc < %s -mtriple=x86_64-linux -remarks-section -pass-remarks-output=%/t.yaml | FileCheck -DPATH=%/t.yaml %s ; RUN: llc < %s -mtriple=x86_64-darwin -remarks-section -pass-remarks-output=%/t.yaml | FileCheck --check-prefix=CHECK-DARWIN -DPATH=%/t.yaml %s -; RUN: llc < %s -mtriple=x86_64-darwin -remarks-section -remarks-yaml-string-table -pass-remarks-output=%/t.yaml | FileCheck --check-prefix=CHECK-DARWIN-STRTAB -DPATH=%/t.yaml %s +; RUN: llc < %s -mtriple=x86_64-darwin --pass-remarks-format=yaml-strtab -remarks-section -pass-remarks-output=%/t.yaml | FileCheck --check-prefix=CHECK-DARWIN-STRTAB -DPATH=%/t.yaml %s ; CHECK-LABEL: func1: diff --git a/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp b/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp index 8b79dfd814f..84d1371457b 100644 --- a/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp +++ b/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp @@ -526,7 +526,7 @@ TEST(YAMLRemarks, ContentsStrTab) { remarks::ParsedStringTable StrTab(StrTabBuf); Expected<std::unique_ptr<remarks::Parser>> MaybeParser = - remarks::createRemarkParser(remarks::Format::YAML, Buf, &StrTab); + remarks::createRemarkParser(remarks::Format::YAMLStrTab, Buf, StrTab); EXPECT_FALSE(errorToBool(MaybeParser.takeError())); EXPECT_TRUE(*MaybeParser != nullptr); @@ -601,7 +601,7 @@ TEST(YAMLRemarks, ParsingBadStringTableIndex) { remarks::ParsedStringTable StrTab(StrTabBuf); Expected<std::unique_ptr<remarks::Parser>> MaybeParser = - remarks::createRemarkParser(remarks::Format::YAML, Buf, &StrTab); + remarks::createRemarkParser(remarks::Format::YAMLStrTab, Buf, StrTab); EXPECT_FALSE(errorToBool(MaybeParser.takeError())); EXPECT_TRUE(*MaybeParser != nullptr); diff --git a/llvm/unittests/Remarks/YAMLRemarksSerializerTest.cpp b/llvm/unittests/Remarks/YAMLRemarksSerializerTest.cpp index c5f222f0f8d..629811a8ba1 100644 --- a/llvm/unittests/Remarks/YAMLRemarksSerializerTest.cpp +++ b/llvm/unittests/Remarks/YAMLRemarksSerializerTest.cpp @@ -16,16 +16,17 @@ static void check(const remarks::Remark &R, StringRef Expected, Optional<StringRef> ExpectedStrTab = None) { std::string Buf; raw_string_ostream OS(Buf); - remarks::UseStringTable UseStrTab = ExpectedStrTab.hasValue() - ? remarks::UseStringTable::Yes - : remarks::UseStringTable::No; - remarks::YAMLSerializer S(OS, UseStrTab); - S.emit(R); + bool UseStrTab = ExpectedStrTab.hasValue(); + std::unique_ptr<remarks::Serializer> S = + UseStrTab ? llvm::make_unique<remarks::YAMLStrTabSerializer>(OS) + : llvm::make_unique<remarks::YAMLSerializer>(OS); + + S->emit(R); EXPECT_EQ(OS.str(), Expected); if (ExpectedStrTab) { Buf.clear(); - EXPECT_TRUE(S.StrTab); - S.StrTab->serialize(OS); + EXPECT_TRUE(S->StrTab); + S->StrTab->serialize(OS); EXPECT_EQ(OS.str(), *ExpectedStrTab); } } |

