From: Francis Visoiu Mistrih Date: Wed, 24 Jul 2019 16:36:35 +0000 (+0000) Subject: [Remarks] Simplify the creation of remark serializers X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0294e50fe5c4ff12cf05571b59232673f033d345;p=llvm [Remarks] Simplify the creation of remark serializers Introduce two new functions to create a serializer, and add support for more combinations to the YAMLStrTabSerializer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366919 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Remarks/RemarkSerializer.h b/include/llvm/Remarks/RemarkSerializer.h index bcf63814b5b..cf12a9af7c8 100644 --- a/include/llvm/Remarks/RemarkSerializer.h +++ b/include/llvm/Remarks/RemarkSerializer.h @@ -36,6 +36,15 @@ struct Serializer { virtual void emit(const Remark &Remark) = 0; }; +/// Create a remark serializer. +Expected> +createRemarkSerializer(Format RemarksFormat, raw_ostream &OS); + +/// Create a remark serializer that uses a pre-filled string table. +Expected> +createRemarkSerializer(Format RemarksFormat, raw_ostream &OS, + remarks::StringTable StrTab); + } // end namespace remarks } // end namespace llvm diff --git a/include/llvm/Remarks/YAMLRemarkSerializer.h b/include/llvm/Remarks/YAMLRemarkSerializer.h index 9bb5c6e83ed..0d8d39cfdbc 100644 --- a/include/llvm/Remarks/YAMLRemarkSerializer.h +++ b/include/llvm/Remarks/YAMLRemarkSerializer.h @@ -48,6 +48,10 @@ struct YAMLStrTabSerializer : public YAMLSerializer { // Having a string table set up enables the serializer to use it. StrTab.emplace(); } + YAMLStrTabSerializer(raw_ostream &OS, StringTable StrTabIn) + : YAMLSerializer(OS) { + StrTab = std::move(StrTabIn); + } }; } // end namespace remarks diff --git a/lib/IR/RemarkStreamer.cpp b/lib/IR/RemarkStreamer.cpp index cb2eeeb8616..2c01c8a0c5e 100644 --- a/lib/IR/RemarkStreamer.cpp +++ b/lib/IR/RemarkStreamer.cpp @@ -16,7 +16,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/GlobalValue.h" #include "llvm/Remarks/RemarkFormat.h" -#include "llvm/Remarks/YAMLRemarkSerializer.h" +#include "llvm/Remarks/RemarkSerializer.h" using namespace llvm; @@ -107,20 +107,6 @@ char RemarkSetupFileError::ID = 0; char RemarkSetupPatternError::ID = 0; char RemarkSetupFormatError::ID = 0; -static std::unique_ptr -formatToSerializer(remarks::Format RemarksFormat, raw_ostream &OS) { - switch (RemarksFormat) { - case remarks::Format::Unknown: - llvm_unreachable("Unknown remark serializer format."); - return nullptr; - case remarks::Format::YAML: - return llvm::make_unique(OS); - case remarks::Format::YAMLStrTab: - return llvm::make_unique(OS); - }; - llvm_unreachable("Unknown remarks::Format enum"); -} - Expected> llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, @@ -147,8 +133,13 @@ llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, if (Error E = Format.takeError()) return make_error(std::move(E)); + Expected> Serializer = + remarks::createRemarkSerializer(*Format, RemarksFile->os()); + if (Error E = Serializer.takeError()) + return make_error(std::move(E)); + Context.setRemarkStreamer(llvm::make_unique( - RemarksFilename, formatToSerializer(*Format, RemarksFile->os()))); + RemarksFilename, std::move(*Serializer))); if (!RemarksPasses.empty()) if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) diff --git a/lib/Remarks/CMakeLists.txt b/lib/Remarks/CMakeLists.txt index 06ddbab6de5..fff7367f1f7 100644 --- a/lib/Remarks/CMakeLists.txt +++ b/lib/Remarks/CMakeLists.txt @@ -2,6 +2,7 @@ add_llvm_library(LLVMRemarks Remark.cpp RemarkFormat.cpp RemarkParser.cpp + RemarkSerializer.cpp RemarkStringTable.cpp YAMLRemarkParser.cpp YAMLRemarkSerializer.cpp diff --git a/lib/Remarks/RemarkFormat.cpp b/lib/Remarks/RemarkFormat.cpp index 4e9ada63188..8dcf3e19345 100644 --- a/lib/Remarks/RemarkFormat.cpp +++ b/lib/Remarks/RemarkFormat.cpp @@ -24,7 +24,7 @@ Expected llvm::remarks::parseFormat(StringRef FormatStr) { if (Result == Format::Unknown) return createStringError(std::make_error_code(std::errc::invalid_argument), - "Unknown remark serializer format: '%s'", + "Unknown remark format: '%s'", FormatStr.data()); return Result; diff --git a/lib/Remarks/RemarkSerializer.cpp b/lib/Remarks/RemarkSerializer.cpp new file mode 100644 index 00000000000..b1cfd098134 --- /dev/null +++ b/lib/Remarks/RemarkSerializer.cpp @@ -0,0 +1,48 @@ +//===- RemarkSerializer.cpp -----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides tools for serializing remarks. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Remarks/RemarkSerializer.h" +#include "llvm/Remarks/YAMLRemarkSerializer.h" + +using namespace llvm; +using namespace llvm::remarks; + +Expected> +remarks::createRemarkSerializer(Format RemarksFormat, raw_ostream &OS) { + switch (RemarksFormat) { + case Format::Unknown: + return createStringError(std::errc::invalid_argument, + "Unknown remark serializer format."); + case Format::YAML: + return llvm::make_unique(OS); + case Format::YAMLStrTab: + return llvm::make_unique(OS); + } + llvm_unreachable("Unknown remarks::Format enum"); +} + +Expected> +remarks::createRemarkSerializer(Format RemarksFormat, raw_ostream &OS, + remarks::StringTable StrTab) { + switch (RemarksFormat) { + case Format::Unknown: + return createStringError(std::errc::invalid_argument, + "Unknown remark serializer format."); + case Format::YAML: + return createStringError(std::errc::invalid_argument, + "Unable to use a string table with the yaml " + "format. Use 'yaml-strtab' instead."); + case Format::YAMLStrTab: + return llvm::make_unique(OS, std::move(StrTab)); + } + llvm_unreachable("Unknown remarks::Format enum"); +} diff --git a/tools/llvm-opt-report/OptReport.cpp b/tools/llvm-opt-report/OptReport.cpp index 5662c9fbd7b..297b798dc9d 100644 --- a/tools/llvm-opt-report/OptReport.cpp +++ b/tools/llvm-opt-report/OptReport.cpp @@ -15,6 +15,7 @@ #include "llvm-c/Remarks.h" #include "llvm/Demangle/Demangle.h" +#include "llvm/Remarks/RemarkFormat.h" #include "llvm/Remarks/RemarkParser.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" @@ -27,14 +28,12 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" #include "llvm/Support/WithColor.h" -#include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" #include #include #include using namespace llvm; -using namespace llvm::yaml; // Mark all our options with this category, everything else (except for -version // and -help) will be hidden. @@ -61,6 +60,11 @@ static cl::opt NoDemangle("no-demangle", cl::desc("Don't demangle function names"), cl::init(false), cl::cat(OptReportCategory)); +static cl::opt ParserFormat("format", + cl::desc("The format of the remarks."), + cl::init("yaml"), + cl::cat(OptReportCategory)); + namespace { // For each location in the source file, the common per-transformation state // collected. @@ -150,8 +154,17 @@ static bool readLocationInfo(LocationInfoTy &LocationInfo) { return false; } + Expected Format = remarks::parseFormat(ParserFormat); + if (!Format) { + handleAllErrors(Format.takeError(), [&](const ErrorInfoBase &PE) { + PE.log(WithColor::error()); + WithColor::error() << '\n'; + }); + return false; + } + Expected> MaybeParser = - remarks::createRemarkParser(remarks::Format::YAML, (*Buf)->getBuffer()); + remarks::createRemarkParser(*Format, (*Buf)->getBuffer()); if (!MaybeParser) { handleAllErrors(MaybeParser.takeError(), [&](const ErrorInfoBase &PE) { PE.log(WithColor::error()); diff --git a/unittests/Remarks/YAMLRemarksSerializerTest.cpp b/unittests/Remarks/YAMLRemarksSerializerTest.cpp index 629811a8ba1..e1340b4f2e0 100644 --- a/unittests/Remarks/YAMLRemarksSerializerTest.cpp +++ b/unittests/Remarks/YAMLRemarksSerializerTest.cpp @@ -8,21 +8,32 @@ #include "llvm/Remarks/Remark.h" #include "llvm/Remarks/YAMLRemarkSerializer.h" +#include "llvm/Support/Error.h" #include "gtest/gtest.h" using namespace llvm; -static void check(const remarks::Remark &R, StringRef Expected, - Optional ExpectedStrTab = None) { +static void check(const remarks::Remark &R, StringRef ExpectedR, + Optional ExpectedStrTab = None, + Optional StrTab = None) { std::string Buf; raw_string_ostream OS(Buf); bool UseStrTab = ExpectedStrTab.hasValue(); - std::unique_ptr S = - UseStrTab ? llvm::make_unique(OS) - : llvm::make_unique(OS); + Expected> MaybeS = [&] { + if (UseStrTab) { + if (StrTab) + return createRemarkSerializer(remarks::Format::YAMLStrTab, OS, + std::move(*StrTab)); + else + return createRemarkSerializer(remarks::Format::YAMLStrTab, OS); + } else + return createRemarkSerializer(remarks::Format::YAML, OS); + }(); + EXPECT_FALSE(errorToBool(MaybeS.takeError())); + std::unique_ptr S = std::move(*MaybeS); S->emit(R); - EXPECT_EQ(OS.str(), Expected); + EXPECT_EQ(OS.str(), ExpectedR); if (ExpectedStrTab) { Buf.clear(); EXPECT_TRUE(S->StrTab); @@ -88,3 +99,34 @@ TEST(YAMLRemarks, SerializerRemarkStrTab) { "...\n", StringRef("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45)); } + +TEST(YAMLRemarks, SerializerRemarkParsedStrTab) { + StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45); + remarks::Remark R; + R.RemarkType = remarks::Type::Missed; + R.PassName = "pass"; + R.RemarkName = "name"; + R.FunctionName = "func"; + R.Loc = remarks::RemarkLocation{"path", 3, 4}; + R.Hotness = 5; + R.Args.emplace_back(); + R.Args.back().Key = "key"; + R.Args.back().Val = "value"; + R.Args.emplace_back(); + R.Args.back().Key = "keydebug"; + R.Args.back().Val = "valuedebug"; + R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7}; + check(R, + "--- !Missed\n" + "Pass: 0\n" + "Name: 1\n" + "DebugLoc: { File: 3, Line: 3, Column: 4 }\n" + "Function: 2\n" + "Hotness: 5\n" + "Args:\n" + " - key: 4\n" + " - keydebug: 5\n" + " DebugLoc: { File: 6, Line: 6, Column: 7 }\n" + "...\n", + StrTab, remarks::StringTable(remarks::ParsedStringTable(StrTab))); +}