-
Notifications
You must be signed in to change notification settings - Fork 14k
[llvm-remarkutil] Add an instruction-mix tool #140598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
jroelofs
merged 28 commits into
llvm:main
from
jroelofs:jroelofs/remarkutil-instruction-mix
May 29, 2025
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
e0dce31
[llvm-remarkutil] Add an instruction-mix tool
jroelofs 27be6e1
drop debugloc cl opts
jroelofs dc263e1
Add regex error handling.
jroelofs 72cb5d0
Use FilterMatcher, and move it to RemarkUtilHelpers.h
jroelofs 23daed4
Make invalid states unrepresentable
jroelofs baf3841
Add missing file header
jroelofs 237deb0
clang-format
jroelofs fb8bed1
EOL whitespace
jroelofs 8e39094
remove now-useless static member ctor
jroelofs 7e8ee10
rm dead function
jroelofs 28a34df
[llvm-remarkutil] Make invalid states un-representable in the count t…
jroelofs 294e4ca
Merge branch 'jroelofs/remarkutil-refactor' into jroelofs/remarkutil-…
jroelofs e5acd04
add tests for count error handling
jroelofs 35e8352
simplify new test
jroelofs 17bd09b
make it harder to mention the wrong arg name in an error
jroelofs c604173
rm stray whitespace
jroelofs 3a94f26
Merge branch 'jroelofs/remarkutil-refactor' into jroelofs/remarkutil-…
jroelofs a063bed
fix build after merge
jroelofs abe8f96
clang-format
jroelofs 3895801
Merge branch 'jroelofs/remarkutil-refactor' into jroelofs/remarkutil-…
jroelofs 1df5289
use std::log10 from <cmath>
jroelofs 3a8444d
createExactOrRE
jroelofs 65812f1
clang-format
jroelofs add1455
avoid UB when all remarks are filtered out
jroelofs 6267372
Merge branch 'jroelofs/remarkutil-refactor' into jroelofs/remarkutil-…
jroelofs b4e7910
review feedback
jroelofs 0c03a05
tobias is right re: lifetimes
jroelofs c28463b
Merge remote-tracking branch 'origin/main' into jroelofs/remarkutil-i…
jroelofs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
27 changes: 27 additions & 0 deletions
27
llvm/test/tools/llvm-remarkutil/Inputs/instruction-mix.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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' | ||
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
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 --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: llvm-remarkutil instruction-mix --parser=yaml %p/Inputs/instruction-mix.yaml --filter=none | FileCheck %s --check-prefix=NONE-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 | ||
; 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-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 | ||
|
||
; NONE-EXACT: Instruction Count | ||
; NONE-EXACT: ----------- ----- | ||
; NONE-NOT: {{.*}} | ||
|
||
; ERROR: error: invalid argument '--rfilter=*': repetition-operator operand invalid |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
//===- RemarkInstructionMix.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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Generic tool to extract instruction mix from asm-printer remarks. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "RemarkUtilHelpers.h" | ||
#include "RemarkUtilRegistry.h" | ||
|
||
#include "llvm/Support/Format.h" | ||
#include "llvm/Support/FormattedStream.h" | ||
#include "llvm/Support/Regex.h" | ||
|
||
#include <cmath> | ||
#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::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)")); | ||
|
||
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) | ||
|
||
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(); | ||
|
||
Expected<std::optional<FilterMatcher>> Filter = | ||
FilterMatcher::createExactOrRE(FunctionFilter, FunctionFilterRE); | ||
if (!Filter) | ||
return Filter.takeError(); | ||
|
||
// Collect the histogram of instruction counts. | ||
llvm::DenseMap<StringRef, unsigned> Histogram; | ||
auto &Parser = **MaybeParser; | ||
auto MaybeRemark = Parser.next(); | ||
for (; MaybeRemark; MaybeRemark = Parser.next()) { | ||
Remark &Remark = **MaybeRemark; | ||
if (Remark.RemarkName != "InstructionMix") | ||
continue; | ||
if (*Filter && !(*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[Key] += Val; | ||
} | ||
} | ||
|
||
// Sort it. | ||
using MixEntry = std::pair<StringRef, 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.size()); | ||
}); | ||
unsigned MaxValue = std::accumulate( | ||
Mix.begin(), Mix.end(), 1, [](unsigned MaxValue, const MixEntry &Elt) { | ||
return std::max(MaxValue, Elt.second); | ||
}); | ||
unsigned ValueWidth = std::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 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.