[llvm] [llvm-remarkutil] Add an instruction-mix tool (PR #140598)
Jon Roelofs via llvm-commits
llvm-commits at lists.llvm.org
Tue May 20 16:13:17 PDT 2025
https://github.com/jroelofs updated https://github.com/llvm/llvm-project/pull/140598
>From e0dce31ff74e3265cb8ea12a71ecbdbce72357f5 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Mon, 19 May 2025 12:18:12 -0700
Subject: [PATCH 1/4] [llvm-remarkutil] Add an instruction-mix tool
The new tool constructs a histogram of instruction frequencies, optionally
filtered by function name via a regex. It can display in either a
human-readable table format, or machine-readable CSV.
---
.../Inputs/instruction-mix.yaml | 27 ++++
.../llvm-remarkutil/broken-yaml-remark.test | 1 +
.../tools/llvm-remarkutil/empty-file.test | 5 +
.../llvm-remarkutil/instruction-mix.test | 22 +++
llvm/tools/llvm-remarkutil/CMakeLists.txt | 1 +
.../llvm-remarkutil/RemarkInstructionMix.cpp | 125 ++++++++++++++++++
6 files changed, 181 insertions(+)
create mode 100644 llvm/test/tools/llvm-remarkutil/Inputs/instruction-mix.yaml
create mode 100644 llvm/test/tools/llvm-remarkutil/instruction-mix.test
create mode 100644 llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
diff --git a/llvm/test/tools/llvm-remarkutil/Inputs/instruction-mix.yaml b/llvm/test/tools/llvm-remarkutil/Inputs/instruction-mix.yaml
new file mode 100644
index 0000000000000..f798454d317fa
--- /dev/null
+++ b/llvm/test/tools/llvm-remarkutil/Inputs/instruction-mix.yaml
@@ -0,0 +1,27 @@
+--- !Analysis
+Pass: asm-printer
+Name: InstructionMix
+Function: home
+Args:
+ - INST_nop: '1'
+ - INST_add: '3'
+ - INST_mul: '5'
+...
+--- !Analysis
+Pass: asm-printer
+Name: InstructionMix
+Function: homeowner
+Args:
+ - INST_nop: '2'
+ - INST_add: '4'
+ - INST_mul: '6'
+...
+--- !Analysis
+Pass: asm-printer
+Name: InstructionMix
+Function: meow
+Args:
+ - INST_nop: '7'
+ - INST_add: '8'
+ - INST_mul: '9'
+...
diff --git a/llvm/test/tools/llvm-remarkutil/broken-yaml-remark.test b/llvm/test/tools/llvm-remarkutil/broken-yaml-remark.test
index 0f06506603363..464d0b80c4ad0 100644
--- a/llvm/test/tools/llvm-remarkutil/broken-yaml-remark.test
+++ b/llvm/test/tools/llvm-remarkutil/broken-yaml-remark.test
@@ -1,5 +1,6 @@
RUN: not llvm-remarkutil yaml2bitstream %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
RUN: not llvm-remarkutil instruction-count --parser=yaml %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
+RUN: not llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
RUN: not llvm-remarkutil annotation-count --parser=yaml --annotation-type=remark %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
RUN: not llvm-remarkutil count --parser=yaml %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
diff --git a/llvm/test/tools/llvm-remarkutil/empty-file.test b/llvm/test/tools/llvm-remarkutil/empty-file.test
index abbf8e02cfa30..bdc5fcf87f7bf 100644
--- a/llvm/test/tools/llvm-remarkutil/empty-file.test
+++ b/llvm/test/tools/llvm-remarkutil/empty-file.test
@@ -1,9 +1,11 @@
RUN: not llvm-remarkutil yaml2bitstream %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --check-prefix=YAMLPARSER
RUN: not llvm-remarkutil instruction-count --parser=yaml %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --check-prefix=YAMLPARSER
+RUN: not llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --check-prefix=YAMLPARSER
RUN: not llvm-remarkutil annotation-count --parser=yaml --annotation-type=remark %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --check-prefix=YAMLPARSER
RUN: not llvm-remarkutil count --parser=yaml %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --check-prefix=YAMLPARSER
RUN: llvm-remarkutil bitstream2yaml %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=BITSTREAM2YAML
RUN: llvm-remarkutil instruction-count --parser=bitstream %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=SIZEBITSTREAM
+RUN: llvm-remarkutil instruction-mix --parser=bitstream %p/Inputs/empty-file --report_style=csv -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=MIXBITSTREAM
RUN: llvm-remarkutil annotation-count --parser=bitstream --annotation-type=remark %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=ANNOTATIONBITSTREAM
RUN: llvm-remarkutil count --parser=bitstream %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=COUNTBITSTREAM
@@ -20,3 +22,6 @@ RUN: llvm-remarkutil count --parser=bitstream %p/Inputs/empty-file -o - 2>&1 | F
; COUNTBITSTREAM-LABEL: Source,Count
; COUNTBITSTREAM-EMPTY:
+
+; MIXBITSTREAM-LABEL: Instruction,Count
+; MIXBITSTREAM-EMPTY:
diff --git a/llvm/test/tools/llvm-remarkutil/instruction-mix.test b/llvm/test/tools/llvm-remarkutil/instruction-mix.test
new file mode 100644
index 0000000000000..8abb760ca37f9
--- /dev/null
+++ b/llvm/test/tools/llvm-remarkutil/instruction-mix.test
@@ -0,0 +1,22 @@
+RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml | FileCheck %s
+RUN: llvm-remarkutil yaml2bitstream %p/Inputs/instruction-mix.yaml | llvm-remarkutil instruction-mix --parser=bitstream | FileCheck %s
+RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --report_style=human | FileCheck %s
+RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --report_style=csv | FileCheck %s --check-prefix=CSV
+RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --filter=meow | FileCheck %s --check-prefix=MEOW
+
+; CHECK-LABEL: Instruction Count
+; CHECK-NEXT: ----------- -----
+; CHECK-NEXT: mul 20
+; CHECK-NEXT: add 15
+; CHECK-NEXT: nop 10
+
+; CSV-LABEL: Instruction,Count
+; CSV-NEXT: mul,20
+; CSV-NEXT: add,15
+; CSV-NEXT: nop,10
+
+; MEOW: Instruction Count
+; MEOW-NEXT: ----------- -----
+; MEOW-NEXT: mul 15
+; MEOW-NEXT: add 12
+; MEOW-NEXT: nop 9
\ No newline at end of file
diff --git a/llvm/tools/llvm-remarkutil/CMakeLists.txt b/llvm/tools/llvm-remarkutil/CMakeLists.txt
index 48aeb9397cda1..ed398ad272024 100644
--- a/llvm/tools/llvm-remarkutil/CMakeLists.txt
+++ b/llvm/tools/llvm-remarkutil/CMakeLists.txt
@@ -8,6 +8,7 @@ add_llvm_tool(llvm-remarkutil
RemarkConvert.cpp
RemarkCount.cpp
RemarkCounter.cpp
+ RemarkInstructionMix.cpp
RemarkSizeDiff.cpp
RemarkUtil.cpp
RemarkUtilHelpers.cpp
diff --git a/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp b/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
new file mode 100644
index 0000000000000..e4373640a75ee
--- /dev/null
+++ b/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
@@ -0,0 +1,125 @@
+
+#include "RemarkUtilHelpers.h"
+#include "RemarkUtilRegistry.h"
+
+#include "llvm/Support/Format.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/Regex.h"
+
+#include <numeric>
+
+using namespace llvm;
+using namespace remarks;
+using namespace llvm::remarkutil;
+
+namespace instructionmix {
+
+static cl::SubCommand
+ InstructionMix("instruction-mix",
+ "Instruction Mix (requires asm-printer remarks)");
+
+static cl::opt<std::string>
+ FunctionFilter("filter", cl::sub(InstructionMix), cl::init(".*"),
+ cl::value_desc("filter_regex"),
+ cl::desc("regex to filter functions with"));
+
+enum ReportStyleOptions { human_output, csv_output };
+static cl::opt<ReportStyleOptions> ReportStyle(
+ "report_style", cl::sub(InstructionMix),
+ cl::init(ReportStyleOptions::human_output),
+ cl::desc("Choose the report output format:"),
+ cl::values(clEnumValN(human_output, "human", "Human-readable format"),
+ clEnumValN(csv_output, "csv", "CSV format")));
+
+INPUT_FORMAT_COMMAND_LINE_OPTIONS(InstructionMix)
+INPUT_OUTPUT_COMMAND_LINE_OPTIONS(InstructionMix)
+DEBUG_LOC_INFO_COMMAND_LINE_OPTIONS(InstructionMix)
+
+static Error tryInstructionMix() {
+ auto MaybeOF =
+ getOutputFileWithFlags(OutputFileName, sys::fs::OF_TextWithCRLF);
+ if (!MaybeOF)
+ return MaybeOF.takeError();
+
+ auto OF = std::move(*MaybeOF);
+ auto MaybeBuf = getInputMemoryBuffer(InputFileName);
+ if (!MaybeBuf)
+ return MaybeBuf.takeError();
+ auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer());
+ if (!MaybeParser)
+ return MaybeParser.takeError();
+
+ Regex Filter(FunctionFilter);
+
+ // Collect the histogram of instruction counts.
+ std::unordered_map<std::string, unsigned> Histogram;
+ auto &Parser = **MaybeParser;
+ auto MaybeRemark = Parser.next();
+ for (; MaybeRemark; MaybeRemark = Parser.next()) {
+ auto &Remark = **MaybeRemark;
+ if (Remark.RemarkName != "InstructionMix")
+ continue;
+ if (!Filter.match(Remark.FunctionName))
+ continue;
+ for (auto &Arg : Remark.Args) {
+ StringRef Key = Arg.Key;
+ if (!Key.consume_front("INST_"))
+ continue;
+ unsigned Val = 0;
+ bool ParseError = Arg.Val.getAsInteger(10, Val);
+ assert(!ParseError);
+ (void)ParseError;
+ Histogram[std::string(Key)] += Val;
+ }
+ }
+
+ // Sort it.
+ using MixEntry = std::pair<std::string, unsigned>;
+ llvm::SmallVector<MixEntry> Mix(Histogram.begin(), Histogram.end());
+ std::sort(Mix.begin(), Mix.end(), [](const auto &LHS, const auto &RHS) {
+ return LHS.second > RHS.second;
+ });
+
+ // Print the results.
+ switch (ReportStyle) {
+ case human_output: {
+ formatted_raw_ostream FOS(OF->os());
+ size_t MaxMnemonic =
+ std::accumulate(Mix.begin(), Mix.end(), StringRef("Instruction").size(),
+ [](size_t MaxMnemonic, const MixEntry &Elt) {
+ return std::max(MaxMnemonic, Elt.first.length());
+ });
+ unsigned MaxValue = std::accumulate(
+ Mix.begin(), Mix.end(), 0, [](unsigned MaxValue, const MixEntry &Elt) {
+ return std::max(MaxValue, Elt.second);
+ });
+ unsigned ValueWidth = log10(MaxValue) + 1;
+ FOS << "Instruction";
+ FOS.PadToColumn(MaxMnemonic + 1) << "Count\n";
+ FOS << "-----------";
+ FOS.PadToColumn(MaxMnemonic + 1) << "-----\n";
+ for (const auto &[Inst, Count] : Mix) {
+ FOS << Inst;
+ FOS.PadToColumn(MaxMnemonic + 1)
+ << " " << format_decimal(Count, ValueWidth) << "\n";
+ }
+ } break;
+ case csv_output: {
+ OF->os() << "Instruction,Count\n";
+ for (const auto &[Inst, Count] : Mix)
+ OF->os() << Inst << "," << Count << "\n";
+ } break;
+ }
+
+ auto E = MaybeRemark.takeError();
+ if (!E.isA<EndOfFileError>())
+ return E;
+ consumeError(std::move(E));
+ OF->keep();
+ return Error::success();
+}
+
+static CommandRegistration InstructionMixReg(&InstructionMix,
+ tryInstructionMix);
+
+} // namespace instructionmix
\ No newline at end of file
>From 27be6e191a578067cc2efca0806d8f14f5590955 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Tue, 20 May 2025 15:10:16 -0700
Subject: [PATCH 2/4] drop debugloc cl opts
---
llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp b/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
index e4373640a75ee..5a00d0f896576 100644
--- a/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
+++ b/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
@@ -33,7 +33,6 @@ static cl::opt<ReportStyleOptions> ReportStyle(
INPUT_FORMAT_COMMAND_LINE_OPTIONS(InstructionMix)
INPUT_OUTPUT_COMMAND_LINE_OPTIONS(InstructionMix)
-DEBUG_LOC_INFO_COMMAND_LINE_OPTIONS(InstructionMix)
static Error tryInstructionMix() {
auto MaybeOF =
>From dc263e1bf7c1c36cacb223bfae0a0e13e76bbd46 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Tue, 20 May 2025 15:23:57 -0700
Subject: [PATCH 3/4] Add regex error handling.
---
.../test/tools/llvm-remarkutil/instruction-mix.test | 7 +++++--
llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp | 13 +++++++++----
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/llvm/test/tools/llvm-remarkutil/instruction-mix.test b/llvm/test/tools/llvm-remarkutil/instruction-mix.test
index 8abb760ca37f9..e281366ef6781 100644
--- a/llvm/test/tools/llvm-remarkutil/instruction-mix.test
+++ b/llvm/test/tools/llvm-remarkutil/instruction-mix.test
@@ -2,7 +2,8 @@ RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yam
RUN: llvm-remarkutil yaml2bitstream %p/Inputs/instruction-mix.yaml | llvm-remarkutil instruction-mix --parser=bitstream | FileCheck %s
RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --report_style=human | FileCheck %s
RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --report_style=csv | FileCheck %s --check-prefix=CSV
-RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --filter=meow | FileCheck %s --check-prefix=MEOW
+RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --rfilter=meow | FileCheck %s --check-prefix=MEOW
+RUN: not llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --rfilter=* 2>&1 | FileCheck %s --check-prefix=ERROR
; CHECK-LABEL: Instruction Count
; CHECK-NEXT: ----------- -----
@@ -19,4 +20,6 @@ RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yam
; MEOW-NEXT: ----------- -----
; MEOW-NEXT: mul 15
; MEOW-NEXT: add 12
-; MEOW-NEXT: nop 9
\ No newline at end of file
+; MEOW-NEXT: nop 9
+
+; ERROR: error: invalid argument '--rfilter=*': repetition-operator operand invalid
\ No newline at end of file
diff --git a/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp b/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
index 5a00d0f896576..146569246af67 100644
--- a/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
+++ b/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
@@ -19,9 +19,10 @@ static cl::SubCommand
"Instruction Mix (requires asm-printer remarks)");
static cl::opt<std::string>
- FunctionFilter("filter", cl::sub(InstructionMix), cl::init(".*"),
- cl::value_desc("filter_regex"),
- cl::desc("regex to filter functions with"));
+ FunctionFilterRE("rfilter", cl::sub(InstructionMix), cl::init(".*"),
+ cl::ValueOptional,
+ cl::desc("Optional function name to filter collection by "
+ "(accepts regular expressions)"));
enum ReportStyleOptions { human_output, csv_output };
static cl::opt<ReportStyleOptions> ReportStyle(
@@ -48,7 +49,11 @@ static Error tryInstructionMix() {
if (!MaybeParser)
return MaybeParser.takeError();
- Regex Filter(FunctionFilter);
+ Regex Filter(FunctionFilterRE);
+ std::string Error;
+ if (!Filter.isValid(Error))
+ return createStringError(make_error_code(std::errc::invalid_argument),
+ Twine("invalid argument '--rfilter=") + FunctionFilterRE + "': " + Error);
// Collect the histogram of instruction counts.
std::unordered_map<std::string, unsigned> Histogram;
>From 72cb5d066731b0a80801cb052f8398623ec2d677 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Tue, 20 May 2025 16:11:37 -0700
Subject: [PATCH 4/4] Use FilterMatcher, and move it to RemarkUtilHelpers.h
---
.../llvm-remarkutil/instruction-mix.test | 19 +++++++----
llvm/tools/llvm-remarkutil/RemarkCounter.cpp | 30 ++++++++---------
llvm/tools/llvm-remarkutil/RemarkCounter.h | 29 ++--------------
.../llvm-remarkutil/RemarkInstructionMix.cpp | 23 +++++++++----
.../tools/llvm-remarkutil/RemarkUtilHelpers.h | 33 +++++++++++++++++++
5 files changed, 80 insertions(+), 54 deletions(-)
diff --git a/llvm/test/tools/llvm-remarkutil/instruction-mix.test b/llvm/test/tools/llvm-remarkutil/instruction-mix.test
index e281366ef6781..b556a9b500fbd 100644
--- a/llvm/test/tools/llvm-remarkutil/instruction-mix.test
+++ b/llvm/test/tools/llvm-remarkutil/instruction-mix.test
@@ -2,7 +2,8 @@ RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yam
RUN: llvm-remarkutil yaml2bitstream %p/Inputs/instruction-mix.yaml | llvm-remarkutil instruction-mix --parser=bitstream | FileCheck %s
RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --report_style=human | FileCheck %s
RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --report_style=csv | FileCheck %s --check-prefix=CSV
-RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --rfilter=meow | FileCheck %s --check-prefix=MEOW
+RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --rfilter=meow | FileCheck %s --check-prefix=MEOW-RE
+RUN: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --filter=meow | FileCheck %s --check-prefix=MEOW-EXACT
RUN: not llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --rfilter=* 2>&1 | FileCheck %s --check-prefix=ERROR
; CHECK-LABEL: Instruction Count
@@ -16,10 +17,16 @@ RUN: not llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix
; CSV-NEXT: add,15
; CSV-NEXT: nop,10
-; MEOW: Instruction Count
-; MEOW-NEXT: ----------- -----
-; MEOW-NEXT: mul 15
-; MEOW-NEXT: add 12
-; MEOW-NEXT: nop 9
+; MEOW-RE: Instruction Count
+; MEOW-RE-NEXT: ----------- -----
+; MEOW-RE-NEXT: mul 15
+; MEOW-RE-NEXT: add 12
+; MEOW-RE-NEXT: nop 9
+
+; MEOW-EXACT: Instruction Count
+; MEOW-EXACT-NEXT: ----------- -----
+; MEOW-EXACT-NEXT: mul 9
+; MEOW-EXACT-NEXT: add 8
+; MEOW-EXACT-NEXT: nop 7
; ERROR: error: invalid argument '--rfilter=*': repetition-operator operand invalid
\ No newline at end of file
diff --git a/llvm/tools/llvm-remarkutil/RemarkCounter.cpp b/llvm/tools/llvm-remarkutil/RemarkCounter.cpp
index 2d9432e41d9c0..c6d97efe5e2f8 100644
--- a/llvm/tools/llvm-remarkutil/RemarkCounter.cpp
+++ b/llvm/tools/llvm-remarkutil/RemarkCounter.cpp
@@ -112,14 +112,14 @@ static unsigned getValForKey(StringRef Key, const Remark &Remark) {
}
Error Filters::regexArgumentsValid() {
- if (RemarkNameFilter && RemarkNameFilter->IsRegex)
- if (auto E = checkRegex(RemarkNameFilter->FilterRE))
+ if (RemarkNameFilter)
+ if (auto E = RemarkNameFilter->isValid())
return E;
- if (PassNameFilter && PassNameFilter->IsRegex)
- if (auto E = checkRegex(PassNameFilter->FilterRE))
+ if (PassNameFilter)
+ if (auto E = PassNameFilter->isValid())
return E;
- if (ArgFilter && ArgFilter->IsRegex)
- if (auto E = checkRegex(ArgFilter->FilterRE))
+ if (ArgFilter)
+ if (auto E = ArgFilter->isValid())
return E;
return Error::success();
}
@@ -254,19 +254,19 @@ Expected<Filters> getRemarkFilter() {
std::optional<FilterMatcher> RemarkArgFilter;
std::optional<Type> RemarkType;
if (!RemarkNameOpt.empty())
- RemarkNameFilter = {RemarkNameOpt, false};
+ RemarkNameFilter = {RemarkNameOpt, "remark-name", false};
else if (!RemarkNameOptRE.empty())
- RemarkNameFilter = {RemarkNameOptRE, true};
+ RemarkNameFilter = {RemarkNameOptRE, "rremark-name", true};
if (!PassNameOpt.empty())
- PassNameFilter = {PassNameOpt, false};
+ PassNameFilter = {PassNameOpt, "pass-name", false};
else if (!PassNameOptRE.empty())
- PassNameFilter = {PassNameOptRE, true};
+ PassNameFilter = {PassNameOptRE, "rpass-name", true};
if (RemarkTypeOpt != Type::Failure)
RemarkType = RemarkTypeOpt;
if (!RemarkFilterArgByOpt.empty())
- RemarkArgFilter = {RemarkFilterArgByOpt, false};
+ RemarkArgFilter = {RemarkFilterArgByOpt, "filter-arg-by", false};
else if (!RemarkArgFilterOptRE.empty())
- RemarkArgFilter = {RemarkArgFilterOptRE, true};
+ RemarkArgFilter = {RemarkArgFilterOptRE, "rfilter-arg-by", true};
// Create RemarkFilter.
return Filters::createRemarkFilter(std::move(RemarkNameFilter),
std::move(PassNameFilter),
@@ -313,12 +313,12 @@ static Error collectRemarks() {
SmallVector<FilterMatcher, 4> ArgumentsVector;
if (!Keys.empty()) {
for (auto &Key : Keys)
- ArgumentsVector.push_back({Key, false});
+ ArgumentsVector.push_back({Key, "count-by", false});
} else if (!RKeys.empty())
for (auto Key : RKeys)
- ArgumentsVector.push_back({Key, true});
+ ArgumentsVector.push_back({Key, "count-by", true});
else
- ArgumentsVector.push_back({".*", true});
+ ArgumentsVector.push_back({".*", "count-by", true});
Expected<ArgumentCounter> AC = ArgumentCounter::createArgumentCounter(
GroupByOpt, ArgumentsVector, Buffer, Filter);
diff --git a/llvm/tools/llvm-remarkutil/RemarkCounter.h b/llvm/tools/llvm-remarkutil/RemarkCounter.h
index 34d5bff774055..db71123238d0c 100644
--- a/llvm/tools/llvm-remarkutil/RemarkCounter.h
+++ b/llvm/tools/llvm-remarkutil/RemarkCounter.h
@@ -45,26 +45,6 @@ inline std::string groupByToStr(GroupBy GroupBy) {
}
}
-/// Filter object which can be either a string or a regex to match with the
-/// remark properties.
-struct FilterMatcher {
- Regex FilterRE;
- std::string FilterStr;
- bool IsRegex;
- FilterMatcher(std::string Filter, bool IsRegex) : IsRegex(IsRegex) {
- if (IsRegex)
- FilterRE = Regex(Filter);
- else
- FilterStr = Filter;
- }
-
- bool match(StringRef StringToMatch) const {
- if (IsRegex)
- return FilterRE.match(StringToMatch);
- return FilterStr == StringToMatch.trim().str();
- }
-};
-
/// Filter out remarks based on remark properties based on name, pass name,
/// argument and type.
struct Filters {
@@ -160,12 +140,9 @@ struct ArgumentCounter : Counter {
StringRef Buffer, Filters &Filter) {
ArgumentCounter AC;
AC.Group = Group;
- for (auto &Arg : Arguments) {
- if (Arg.IsRegex) {
- if (auto E = checkRegex(Arg.FilterRE))
- return std::move(E);
- }
- }
+ for (auto &Arg : Arguments)
+ if (auto E = Arg.isValid())
+ return E;
if (auto E = AC.getAllMatchingArgumentsInRemark(Buffer, Arguments, Filter))
return std::move(E);
return AC;
diff --git a/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp b/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
index 146569246af67..e1d6f13f0f581 100644
--- a/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
+++ b/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
@@ -19,8 +19,11 @@ static cl::SubCommand
"Instruction Mix (requires asm-printer remarks)");
static cl::opt<std::string>
- FunctionFilterRE("rfilter", cl::sub(InstructionMix), cl::init(".*"),
- cl::ValueOptional,
+ FunctionFilter("filter", cl::sub(InstructionMix), cl::ValueOptional,
+ cl::desc("Optional function name to filter collection by"));
+
+static cl::opt<std::string>
+ FunctionFilterRE("rfilter", cl::sub(InstructionMix), cl::ValueOptional,
cl::desc("Optional function name to filter collection by "
"(accepts regular expressions)"));
@@ -35,6 +38,14 @@ static cl::opt<ReportStyleOptions> ReportStyle(
INPUT_FORMAT_COMMAND_LINE_OPTIONS(InstructionMix)
INPUT_OUTPUT_COMMAND_LINE_OPTIONS(InstructionMix)
+static FilterMatcher getRemarkFilter() {
+ if (FunctionFilter.getNumOccurrences())
+ return {FunctionFilter, "filter", false};
+ if (FunctionFilterRE.getNumOccurrences())
+ return {FunctionFilterRE, "rfilter", true};
+ return {".*", "<implicit>", true};
+}
+
static Error tryInstructionMix() {
auto MaybeOF =
getOutputFileWithFlags(OutputFileName, sys::fs::OF_TextWithCRLF);
@@ -49,11 +60,9 @@ static Error tryInstructionMix() {
if (!MaybeParser)
return MaybeParser.takeError();
- Regex Filter(FunctionFilterRE);
- std::string Error;
- if (!Filter.isValid(Error))
- return createStringError(make_error_code(std::errc::invalid_argument),
- Twine("invalid argument '--rfilter=") + FunctionFilterRE + "': " + Error);
+ FilterMatcher Filter = getRemarkFilter();
+ if (auto E = Filter.isValid())
+ return E;
// Collect the histogram of instruction counts.
std::unordered_map<std::string, unsigned> Histogram;
diff --git a/llvm/tools/llvm-remarkutil/RemarkUtilHelpers.h b/llvm/tools/llvm-remarkutil/RemarkUtilHelpers.h
index 5d2335224d4c2..a1bebd130c654 100644
--- a/llvm/tools/llvm-remarkutil/RemarkUtilHelpers.h
+++ b/llvm/tools/llvm-remarkutil/RemarkUtilHelpers.h
@@ -18,6 +18,7 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Regex.h"
#include "llvm/Support/ToolOutputFile.h"
// Keep input + output help + names consistent across the various modes via a
@@ -55,5 +56,37 @@ Expected<std::unique_ptr<ToolOutputFile>>
getOutputFileWithFlags(StringRef OutputFileName, sys::fs::OpenFlags Flags);
Expected<std::unique_ptr<ToolOutputFile>>
getOutputFileForRemarks(StringRef OutputFileName, Format OutputFormat);
+
+/// Filter object which can be either a string or a regex to match with the
+/// remark properties.
+class FilterMatcher {
+ Regex FilterRE;
+ std::string FilterStr;
+ std::string Argument;
+ bool IsRegex;
+
+public:
+ FilterMatcher(StringRef Filter, StringRef Argument, bool IsRegex)
+ : FilterRE(Filter), FilterStr(Filter), Argument(Argument),
+ IsRegex(IsRegex) {}
+
+ bool match(StringRef StringToMatch) const {
+ if (IsRegex)
+ return FilterRE.match(StringToMatch);
+ return FilterStr == StringToMatch.trim().str();
+ }
+
+ Error isValid() const {
+ if (!IsRegex)
+ return Error::success();
+ std::string Error;
+ if (FilterRE.isValid(Error))
+ return Error::success();
+ return createStringError(make_error_code(std::errc::invalid_argument),
+ "invalid argument '--" + Argument + "=" +
+ FilterStr + "': " + Error);
+ }
+};
+
} // namespace remarks
} // namespace llvm
More information about the llvm-commits
mailing list