Skip to content

Commit c5cc9ef

Browse files
committed
[Remarks] Simplify the creation of remark serializers
Introduce two new functions to create a serializer, and add support for more combinations to the YAMLStrTabSerializer. llvm-svn: 366919
1 parent 419f1a4 commit c5cc9ef

File tree

8 files changed

+134
-26
lines changed

8 files changed

+134
-26
lines changed

llvm/include/llvm/Remarks/RemarkSerializer.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ struct Serializer {
3636
virtual void emit(const Remark &Remark) = 0;
3737
};
3838

39+
/// Create a remark serializer.
40+
Expected<std::unique_ptr<Serializer>>
41+
createRemarkSerializer(Format RemarksFormat, raw_ostream &OS);
42+
43+
/// Create a remark serializer that uses a pre-filled string table.
44+
Expected<std::unique_ptr<Serializer>>
45+
createRemarkSerializer(Format RemarksFormat, raw_ostream &OS,
46+
remarks::StringTable StrTab);
47+
3948
} // end namespace remarks
4049
} // end namespace llvm
4150

llvm/include/llvm/Remarks/YAMLRemarkSerializer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ struct YAMLStrTabSerializer : public YAMLSerializer {
4848
// Having a string table set up enables the serializer to use it.
4949
StrTab.emplace();
5050
}
51+
YAMLStrTabSerializer(raw_ostream &OS, StringTable StrTabIn)
52+
: YAMLSerializer(OS) {
53+
StrTab = std::move(StrTabIn);
54+
}
5155
};
5256

5357
} // end namespace remarks

llvm/lib/IR/RemarkStreamer.cpp

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "llvm/IR/Function.h"
1717
#include "llvm/IR/GlobalValue.h"
1818
#include "llvm/Remarks/RemarkFormat.h"
19-
#include "llvm/Remarks/YAMLRemarkSerializer.h"
19+
#include "llvm/Remarks/RemarkSerializer.h"
2020

2121
using namespace llvm;
2222

@@ -107,20 +107,6 @@ char RemarkSetupFileError::ID = 0;
107107
char RemarkSetupPatternError::ID = 0;
108108
char RemarkSetupFormatError::ID = 0;
109109

110-
static std::unique_ptr<remarks::Serializer>
111-
formatToSerializer(remarks::Format RemarksFormat, raw_ostream &OS) {
112-
switch (RemarksFormat) {
113-
case remarks::Format::Unknown:
114-
llvm_unreachable("Unknown remark serializer format.");
115-
return nullptr;
116-
case remarks::Format::YAML:
117-
return llvm::make_unique<remarks::YAMLSerializer>(OS);
118-
case remarks::Format::YAMLStrTab:
119-
return llvm::make_unique<remarks::YAMLStrTabSerializer>(OS);
120-
};
121-
llvm_unreachable("Unknown remarks::Format enum");
122-
}
123-
124110
Expected<std::unique_ptr<ToolOutputFile>>
125111
llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
126112
StringRef RemarksPasses, StringRef RemarksFormat,
@@ -147,8 +133,13 @@ llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
147133
if (Error E = Format.takeError())
148134
return make_error<RemarkSetupFormatError>(std::move(E));
149135

136+
Expected<std::unique_ptr<remarks::Serializer>> Serializer =
137+
remarks::createRemarkSerializer(*Format, RemarksFile->os());
138+
if (Error E = Serializer.takeError())
139+
return make_error<RemarkSetupFormatError>(std::move(E));
140+
150141
Context.setRemarkStreamer(llvm::make_unique<RemarkStreamer>(
151-
RemarksFilename, formatToSerializer(*Format, RemarksFile->os())));
142+
RemarksFilename, std::move(*Serializer)));
152143

153144
if (!RemarksPasses.empty())
154145
if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses))

llvm/lib/Remarks/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ add_llvm_library(LLVMRemarks
22
Remark.cpp
33
RemarkFormat.cpp
44
RemarkParser.cpp
5+
RemarkSerializer.cpp
56
RemarkStringTable.cpp
67
YAMLRemarkParser.cpp
78
YAMLRemarkSerializer.cpp

llvm/lib/Remarks/RemarkFormat.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Expected<Format> llvm::remarks::parseFormat(StringRef FormatStr) {
2424

2525
if (Result == Format::Unknown)
2626
return createStringError(std::make_error_code(std::errc::invalid_argument),
27-
"Unknown remark serializer format: '%s'",
27+
"Unknown remark format: '%s'",
2828
FormatStr.data());
2929

3030
return Result;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===- RemarkSerializer.cpp -----------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file provides tools for serializing remarks.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "llvm/Remarks/RemarkSerializer.h"
14+
#include "llvm/Remarks/YAMLRemarkSerializer.h"
15+
16+
using namespace llvm;
17+
using namespace llvm::remarks;
18+
19+
Expected<std::unique_ptr<Serializer>>
20+
remarks::createRemarkSerializer(Format RemarksFormat, raw_ostream &OS) {
21+
switch (RemarksFormat) {
22+
case Format::Unknown:
23+
return createStringError(std::errc::invalid_argument,
24+
"Unknown remark serializer format.");
25+
case Format::YAML:
26+
return llvm::make_unique<YAMLSerializer>(OS);
27+
case Format::YAMLStrTab:
28+
return llvm::make_unique<YAMLStrTabSerializer>(OS);
29+
}
30+
llvm_unreachable("Unknown remarks::Format enum");
31+
}
32+
33+
Expected<std::unique_ptr<Serializer>>
34+
remarks::createRemarkSerializer(Format RemarksFormat, raw_ostream &OS,
35+
remarks::StringTable StrTab) {
36+
switch (RemarksFormat) {
37+
case Format::Unknown:
38+
return createStringError(std::errc::invalid_argument,
39+
"Unknown remark serializer format.");
40+
case Format::YAML:
41+
return createStringError(std::errc::invalid_argument,
42+
"Unable to use a string table with the yaml "
43+
"format. Use 'yaml-strtab' instead.");
44+
case Format::YAMLStrTab:
45+
return llvm::make_unique<YAMLStrTabSerializer>(OS, std::move(StrTab));
46+
}
47+
llvm_unreachable("Unknown remarks::Format enum");
48+
}

llvm/tools/llvm-opt-report/OptReport.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "llvm-c/Remarks.h"
1717
#include "llvm/Demangle/Demangle.h"
18+
#include "llvm/Remarks/RemarkFormat.h"
1819
#include "llvm/Remarks/RemarkParser.h"
1920
#include "llvm/Support/CommandLine.h"
2021
#include "llvm/Support/Error.h"
@@ -27,14 +28,12 @@
2728
#include "llvm/Support/Path.h"
2829
#include "llvm/Support/Program.h"
2930
#include "llvm/Support/WithColor.h"
30-
#include "llvm/Support/YAMLTraits.h"
3131
#include "llvm/Support/raw_ostream.h"
3232
#include <cstdlib>
3333
#include <map>
3434
#include <set>
3535

3636
using namespace llvm;
37-
using namespace llvm::yaml;
3837

3938
// Mark all our options with this category, everything else (except for -version
4039
// and -help) will be hidden.
@@ -61,6 +60,11 @@ static cl::opt<bool>
6160
NoDemangle("no-demangle", cl::desc("Don't demangle function names"),
6261
cl::init(false), cl::cat(OptReportCategory));
6362

63+
static cl::opt<std::string> ParserFormat("format",
64+
cl::desc("The format of the remarks."),
65+
cl::init("yaml"),
66+
cl::cat(OptReportCategory));
67+
6468
namespace {
6569
// For each location in the source file, the common per-transformation state
6670
// collected.
@@ -150,8 +154,17 @@ static bool readLocationInfo(LocationInfoTy &LocationInfo) {
150154
return false;
151155
}
152156

157+
Expected<remarks::Format> Format = remarks::parseFormat(ParserFormat);
158+
if (!Format) {
159+
handleAllErrors(Format.takeError(), [&](const ErrorInfoBase &PE) {
160+
PE.log(WithColor::error());
161+
WithColor::error() << '\n';
162+
});
163+
return false;
164+
}
165+
153166
Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
154-
remarks::createRemarkParser(remarks::Format::YAML, (*Buf)->getBuffer());
167+
remarks::createRemarkParser(*Format, (*Buf)->getBuffer());
155168
if (!MaybeParser) {
156169
handleAllErrors(MaybeParser.takeError(), [&](const ErrorInfoBase &PE) {
157170
PE.log(WithColor::error());

llvm/unittests/Remarks/YAMLRemarksSerializerTest.cpp

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,32 @@
88

99
#include "llvm/Remarks/Remark.h"
1010
#include "llvm/Remarks/YAMLRemarkSerializer.h"
11+
#include "llvm/Support/Error.h"
1112
#include "gtest/gtest.h"
1213

1314
using namespace llvm;
1415

15-
static void check(const remarks::Remark &R, StringRef Expected,
16-
Optional<StringRef> ExpectedStrTab = None) {
16+
static void check(const remarks::Remark &R, StringRef ExpectedR,
17+
Optional<StringRef> ExpectedStrTab = None,
18+
Optional<remarks::StringTable> StrTab = None) {
1719
std::string Buf;
1820
raw_string_ostream OS(Buf);
1921
bool UseStrTab = ExpectedStrTab.hasValue();
20-
std::unique_ptr<remarks::Serializer> S =
21-
UseStrTab ? llvm::make_unique<remarks::YAMLStrTabSerializer>(OS)
22-
: llvm::make_unique<remarks::YAMLSerializer>(OS);
22+
Expected<std::unique_ptr<remarks::Serializer>> MaybeS = [&] {
23+
if (UseStrTab) {
24+
if (StrTab)
25+
return createRemarkSerializer(remarks::Format::YAMLStrTab, OS,
26+
std::move(*StrTab));
27+
else
28+
return createRemarkSerializer(remarks::Format::YAMLStrTab, OS);
29+
} else
30+
return createRemarkSerializer(remarks::Format::YAML, OS);
31+
}();
32+
EXPECT_FALSE(errorToBool(MaybeS.takeError()));
33+
std::unique_ptr<remarks::Serializer> S = std::move(*MaybeS);
2334

2435
S->emit(R);
25-
EXPECT_EQ(OS.str(), Expected);
36+
EXPECT_EQ(OS.str(), ExpectedR);
2637
if (ExpectedStrTab) {
2738
Buf.clear();
2839
EXPECT_TRUE(S->StrTab);
@@ -88,3 +99,34 @@ TEST(YAMLRemarks, SerializerRemarkStrTab) {
8899
"...\n",
89100
StringRef("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45));
90101
}
102+
103+
TEST(YAMLRemarks, SerializerRemarkParsedStrTab) {
104+
StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
105+
remarks::Remark R;
106+
R.RemarkType = remarks::Type::Missed;
107+
R.PassName = "pass";
108+
R.RemarkName = "name";
109+
R.FunctionName = "func";
110+
R.Loc = remarks::RemarkLocation{"path", 3, 4};
111+
R.Hotness = 5;
112+
R.Args.emplace_back();
113+
R.Args.back().Key = "key";
114+
R.Args.back().Val = "value";
115+
R.Args.emplace_back();
116+
R.Args.back().Key = "keydebug";
117+
R.Args.back().Val = "valuedebug";
118+
R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
119+
check(R,
120+
"--- !Missed\n"
121+
"Pass: 0\n"
122+
"Name: 1\n"
123+
"DebugLoc: { File: 3, Line: 3, Column: 4 }\n"
124+
"Function: 2\n"
125+
"Hotness: 5\n"
126+
"Args:\n"
127+
" - key: 4\n"
128+
" - keydebug: 5\n"
129+
" DebugLoc: { File: 6, Line: 6, Column: 7 }\n"
130+
"...\n",
131+
StrTab, remarks::StringTable(remarks::ParsedStringTable(StrTab)));
132+
}

0 commit comments

Comments
 (0)