Recommit "Add an option to print out annotation remark count."

Add missing new line for `llvm/docs/CommandGuide/llvm-remarkutil.rst`

This reverts commit 0f7fcb4c670fbef2c25b835fdfdd29598c6c13ae.
This commit is contained in:
Zain Jaffal 2023-04-07 23:42:39 +01:00
parent 0f7fcb4c67
commit db01cf7b7c
9 changed files with 138 additions and 7 deletions

View File

@ -20,7 +20,7 @@ Subcommands
* :ref:`bitstream2yaml_subcommand` - Reserialize bitstream remarks to YAML.
* :ref:`yaml2bitstream_subcommand` - Reserialize YAML remarks to bitstream.
* :ref:`instruction-count_subcommand` - Output function instruction counts.
* :ref:`annotation-count_subcommand` - Output remark type count from annotation remarks.
.. _bitstream2yaml_subcommand:
bitstream2yaml
@ -72,3 +72,24 @@ CSV format is as follows:
::
Function,InstructionCount
foo,123
annotation-count
~~~~~~~~~~~~~~~~~
.. program:: llvm-remarkutil annotation-count
USAGE: :program:`llvm-remarkutil` annotation-count <input file> --parser=<bitstream|yaml> --annotation-type=<type> -o <output file>
Summary
^^^^^^^
Outputs a count for annotation-type `<type>` remark for every function. The count expresses
the number of remark checks inserted at the function.
Annotation count remarks require AnnotationRemarksPass remarks.
CSV format is as follows:
::
Function,Count
foo,123

View File

@ -0,0 +1,27 @@
--- !Analysis
Pass: annotation-remarks
Name: AnnotationSummary
Function: func1
Args:
- String: 'Annotated '
- count: '1'
- String: ' instructions with '
- type: remark
--- !Analysis
Pass: annotation-remarks
Name: AnnotationSummary
Function: func2
Args:
- String: 'Annotated '
- count: '2'
- String: ' instructions with '
- type: remark
--- !Analysis
Pass: annotation-remarks
Name: AnnotationSummary
Function: func3
Args:
- String: 'Annotated '
- count: '3'
- String: ' instructions with '
- type: remark

View File

@ -0,0 +1,7 @@
RUN: llvm-remarkutil annotation-count --parser=yaml --annotation-type=remark %p/Inputs/annotation-count.yaml | FileCheck %s
RUN: llvm-remarkutil yaml2bitstream %p/Inputs/annotation-count.yaml | llvm-remarkutil annotation-count --parser=bitstream --annotation-type=remark | FileCheck %s
; CHECK-LABEL: Function,Count
; CHECK: func1,1
; CHECK: func2,2
; CHECK: func3,3

View File

@ -1,3 +1,4 @@
RUN: not llvm-remarkutil bitstream2yaml %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
RUN: not llvm-remarkutil instruction-count --parser=bitstream %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
RUN: not llvm-remarkutil annotation-count --parser=bitstream --annotation-type=remark %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
CHECK: error: Unknown magic number: expecting RMRK, got --- .

View File

@ -1,3 +1,4 @@
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 annotation-count --parser=yaml --annotation-type=remark %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s
CHECK: error: Type, Pass, Name or Function missing

View File

@ -1,7 +1,9 @@
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 annotation-count --parser=yaml --annotation-type=remark %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 annotation-count --parser=bitstream --annotation-type=remark %p/Inputs/empty-file -o - 2>&1 | FileCheck %s --allow-empty --check-prefix=ANNOTATIONBITSTREAM
; YAMLPARSER: error: document root is not of mapping type.
@ -9,4 +11,7 @@ RUN: llvm-remarkutil instruction-count --parser=bitstream %p/Inputs/empty-file -
; BITSTREAM2YAML-NOT: error
; SIZEBITSTREAM-LABEL: Function,InstructionCount
; SIZEBITSTREAM-EMPTY
; SIZEBITSTREAM-EMPTY:
; ANNOTATIONBITSTREAM-LABEL: Function,Count
; ANNOTATIONBITSTREAM-EMPTY:

View File

@ -0,0 +1,5 @@
RUN: llvm-remarkutil annotation-count --parser=yaml --annotation-type=remark %p/Inputs/made-up-fake-remarks.yaml | FileCheck %s
RUN: llvm-remarkutil yaml2bitstream %p/Inputs/made-up-fake-remarks.yaml | llvm-remarkutil annotation-count --parser=bitstream --annotation-type=remark | FileCheck %s
; CHECK-LABEL: Function,Count
; CHECK-EMPTY:

View File

@ -38,6 +38,10 @@ static cl::SubCommand
static cl::SubCommand InstructionCount(
"instruction-count",
"Function instruction count information (requires asm-printer remarks)");
static cl::SubCommand
AnnotationCount("annotation-count",
"Collect count information from annotation remarks (uses "
"AnnotationRemarksPass)");
} // namespace subopts
// Keep input + output help + names consistent across the various modes via a
@ -49,6 +53,14 @@ static cl::SubCommand InstructionCount(
static cl::opt<std::string> OutputFileName( \
"o", cl::init("-"), cl::cat(RemarkUtilCategory), cl::desc("Output"), \
cl::value_desc("filename"), cl::sub(SUBOPT));
// Keep Input format and names consistent accross the modes via a macro.
#define INPUT_FORMAT_COMMAND_LINE_OPTIONS(SUBOPT) \
static cl::opt<Format> InputFormat( \
"parser", cl::desc("Input remark format to parse"), \
cl::values(clEnumValN(Format::YAML, "yaml", "YAML"), \
clEnumValN(Format::Bitstream, "bitstream", "Bitstream")), \
cl::sub(SUBOPT));
namespace yaml2bitstream {
/// Remark format to parse.
static constexpr Format InputFormat = Format::YAML;
@ -66,14 +78,18 @@ INPUT_OUTPUT_COMMAND_LINE_OPTIONS(subopts::Bitstream2YAML)
} // namespace bitstream2yaml
namespace instructioncount {
static cl::opt<Format> InputFormat(
"parser", cl::desc("Input remark format to parse"),
cl::values(clEnumValN(Format::YAML, "yaml", "YAML"),
clEnumValN(Format::Bitstream, "bitstream", "Bitstream")),
cl::sub(subopts::InstructionCount));
INPUT_FORMAT_COMMAND_LINE_OPTIONS(subopts::InstructionCount)
INPUT_OUTPUT_COMMAND_LINE_OPTIONS(subopts::InstructionCount)
} // namespace instructioncount
namespace annotationcount {
INPUT_FORMAT_COMMAND_LINE_OPTIONS(subopts::AnnotationCount)
static cl::opt<std::string> AnnotationTypeToCollect(
"annotation-type", cl::desc("annotation-type remark to collect count for"),
cl::sub(subopts::AnnotationCount));
INPUT_OUTPUT_COMMAND_LINE_OPTIONS(subopts::AnnotationCount)
} // namespace annotationcount
/// \returns A MemoryBuffer for the input file on success, and an Error
/// otherwise.
static Expected<std::unique_ptr<MemoryBuffer>>
@ -254,6 +270,51 @@ static Error tryInstructionCount() {
}
} // namespace instructioncount
namespace annotationcount {
static Error tryAnnotationCount() {
// Create the output buffer.
auto MaybeOF = getOutputFileWithFlags(OutputFileName,
/*Flags = */ sys::fs::OF_TextWithCRLF);
if (!MaybeOF)
return MaybeOF.takeError();
auto OF = std::move(*MaybeOF);
// Create a parser for the user-specified input format.
auto MaybeBuf = getInputMemoryBuffer(InputFileName);
if (!MaybeBuf)
return MaybeBuf.takeError();
auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer());
if (!MaybeParser)
return MaybeParser.takeError();
// Emit CSV header.
OF->os() << "Function,Count\n";
// Parse all remarks. When we see the specified remark collect the count
// information.
auto &Parser = **MaybeParser;
auto MaybeRemark = Parser.next();
for (; MaybeRemark; MaybeRemark = Parser.next()) {
auto &Remark = **MaybeRemark;
if (Remark.RemarkName != "AnnotationSummary")
continue;
auto *RemarkNameArg = find_if(Remark.Args, [](const Argument &Arg) {
return Arg.Key == "type" && Arg.Val == AnnotationTypeToCollect;
});
if (RemarkNameArg == Remark.Args.end())
continue;
auto *CountArg = find_if(
Remark.Args, [](const Argument &Arg) { return Arg.Key == "count"; });
assert(CountArg != Remark.Args.end() &&
"Expected annotation-type remark to have a count key?");
OF->os() << Remark.FunctionName << "," << CountArg->Val << "\n";
}
auto E = MaybeRemark.takeError();
if (!E.isA<EndOfFileError>())
return E;
consumeError(std::move(E));
OF->keep();
return Error::success();
}
} // namespace annotationcount
/// Handle user-specified suboptions (e.g. yaml2bitstream, bitstream2yaml).
/// \returns An Error if the specified suboption fails or if no suboption was
/// specified. Otherwise, Error::success().
@ -264,6 +325,9 @@ static Error handleSuboptions() {
return yaml2bitstream::tryYAML2Bitstream();
if (subopts::InstructionCount)
return instructioncount::tryInstructionCount();
if (subopts::AnnotationCount)
return annotationcount::tryAnnotationCount();
return make_error<StringError>(
"Please specify a subcommand. (See -help for options)",
inconvertibleErrorCode());