Skip to content

Commit

Permalink
[Remarks] Introduce count subcommand for llvm-remarkutil. (#66214)
Browse files Browse the repository at this point in the history
This tool is a generic remark counter reporting count based on specified
properties. The counter can be used to count remarks individually and
filter them based on name, type and pass or count using remark
arguments.
  • Loading branch information
zjaffal committed Oct 12, 2023
1 parent ab6a66d commit 31c2cf1
Show file tree
Hide file tree
Showing 24 changed files with 914 additions and 0 deletions.
74 changes: 74 additions & 0 deletions llvm/docs/CommandGuide/llvm-remarkutil.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,80 @@ if `--use-debug-loc` is passed then the CSV will include the source path, line n
Source,Function,Count
path:line:column,foo,3

.. _count_subcommand:

count
~~~~~

..program:: llvm-remarkutil count

USAGE: :program:`llvm-remarkutil` count [*options*] <input file>

Summary
^^^^^^^

:program:`llvm-remarkutil count` counts `remarks <https://llvm.org/docs/Remarks.html>` based on specified properties.
By default the tool counts remarks based on how many occour in a source file or function or total for the generated remark file.
The tool also supports collecting count based on specific remark arguments. The specified arguments should have an integer value to be able to report a count.

The tool contains utilities to filter the remark count based on remark name, pass name, argument value and remark type.
OPTIONS
-------

.. option:: --parser=<yaml|bitstream>

Select the type of input remark parser. Required.
* ``yaml``: The tool will parse YAML remarks.
* ``bitstream``: The tool will parse bitstream remarks.

.. option:: --count-by<value>
Select option to collect remarks by.
* ``remark-name``: count how many individual remarks exist.
* ``arg``: count remarks based on specified arguments passed by --(r)args. The argument value must be a number.

.. option:: --group-by=<value>
group count of remarks by property.
* ``source``: Count will be collected per source path. Remarks with no debug location will not be counted.
* ``function``: Count is collected per function.
* ``function-with-loc``: Count is collected per function per source. Remarks with no debug location will not be counted.
* ``Total``: Report a count for the provided remark file.

.. option:: --args[=arguments]
If `count-by` is set to `arg` this flag can be used to collect from specified remark arguments represented as a comma seperated string.
The arguments must have a numeral value to be able to count remarks by

.. option:: --rargs[=arguments]
If `count-by` is set to `arg` this flag can be used to collect from specified remark arguments using regular expression.
The arguments must have a numeral value to be able to count remarks by

.. option:: --pass-name[=<string>]
Filter count by pass name.

.. option:: --rpass-name[=<string>]
Filter count by pass name using regular expressions.

.. option:: --remark-name[=<string>]
Filter count by remark name.

.. option:: --rremark-name[=<string>]
Filter count by remark name using regular expressions.

.. option:: --filter-arg-by[=<string>]
Filter count by argument value.

.. option:: --rfilter-arg-by[=<string>]
Filter count by argument value using regular expressions.

.. option:: --remark-type=<value>
Filter remarks by type with the following options.
* ``unknown``
* ``passed``
* ``missed``
* ``analysis``
* ``analysis-fp-commute``
* ``analysis-aliasing``
* ``failure``

.. _size-diff_subcommand:

size-diff
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/Remarks/Remark.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ struct Argument {

/// Implement operator<< on Argument.
void print(raw_ostream &OS) const;
/// Return the value of argument as int.
std::optional<int> getValAsInt() const;
/// Check if the argument value can be parsed as int.
bool isValInt() const;
};

// Create wrappers for C Binding types (see CBindingWrapping.h).
Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/Remarks/Remark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

#include "llvm/Remarks/Remark.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include <optional>

Expand All @@ -25,6 +26,16 @@ std::string Remark::getArgsAsMsg() const {
return OS.str();
}

/// Returns the value of a specified key parsed from StringRef.
std::optional<int> Argument::getValAsInt() const {
APInt KeyVal;
if (Val.getAsInteger(10, KeyVal))
return std::nullopt;
return KeyVal.getSExtValue();
}

bool Argument::isValInt() const { return getValAsInt().has_value(); }

void RemarkLocation::print(raw_ostream &OS) const {
OS << "{ "
<< "File: " << SourceFilePath << ", Line: " << SourceLine
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
RUN: llvm-remarkutil annotation-count --use-debug-loc --parser=yaml --annotation-type=remark %p/Inputs/annotation-count-with-dbg-loc.yaml | FileCheck %s
RUN: llvm-remarkutil yaml2bitstream %p/Inputs/annotation-count-with-dbg-loc.yaml | llvm-remarkutil annotation-count --use-debug-loc --parser=bitstream --annotation-type=remark | FileCheck %s
RUN: llvm-remarkutil count --parser=yaml --count-by=arg --group-by=function-with-loc --remark-name="AnnotationSummary" %p/Inputs/annotation-count-with-dbg-loc.yaml | FileCheck %s --check-prefix=COUNT-CHECK
RUN: llvm-remarkutil yaml2bitstream %p/Inputs/annotation-count-with-dbg-loc.yaml | llvm-remarkutil count --parser=bitstream --count-by=arg --group-by=function-with-loc --remark-name="AnnotationSummary" | FileCheck %s --check-prefix=COUNT-CHECK

; CHECK-LABEL: Source,Function,Count
; CHECK: path/to/anno.c:1:2,func1,1
; CHECK: path/to/anno2.c:1:2,func2,2
; CHECK: path/to/anno3.c:1:2,func3,3

; COUNT-CHECK-LABEL: FuctionWithDebugLoc,count
; COUNT-CHECK: path/to/anno.c:func1,1
; COUNT-CHECK: path/to/anno2.c:func2,2
; COUNT-CHECK: path/to/anno3.c:func3,3
7 changes: 7 additions & 0 deletions llvm/test/tools/llvm-remarkutil/annotation-count.test
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
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
RUN: llvm-remarkutil count --parser=yaml --count-by=arg --group-by=function --remark-name="AnnotationSummary" %p/Inputs/annotation-count.yaml | FileCheck %s --check-prefix=COUNT-CHECK
RUN: llvm-remarkutil yaml2bitstream %p/Inputs/annotation-count.yaml | llvm-remarkutil count --parser=bitstream --count-by=arg --group-by=function --remark-name="AnnotationSummary" | FileCheck %s --check-prefix=COUNT-CHECK

; CHECK-LABEL: Function,Count
; CHECK: func1,1
; CHECK: func2,2
; CHECK: func3,3

; COUNT-CHECK-LABEL: Function,count
; COUNT-CHECK: func1,1
; COUNT-CHECK: func2,2
; COUNT-CHECK: func3,3
2 changes: 2 additions & 0 deletions llvm/test/tools/llvm-remarkutil/broken-bitstream-remark.test
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
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
RUN: not llvm-remarkutil count --parser=bitstream %p/Inputs/broken-remark -o - 2>&1 | FileCheck %s

CHECK: error: Unknown magic number: expecting RMRK, got --- .
2 changes: 2 additions & 0 deletions llvm/test/tools/llvm-remarkutil/broken-yaml-remark.test
Original file line number Diff line number Diff line change
@@ -1,4 +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 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

CHECK: error: Type, Pass, Name or Function missing
43 changes: 43 additions & 0 deletions llvm/test/tools/llvm-remarkutil/count/Inputs/remark-count-by.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
--- !Analysis
Pass: generic-remarks-pass
Name: Remark
DebugLoc: { File: path/to/anno.c, Line: 1, Column: 2 }
Function: func1
Args:
- count1: '1'
- count2: '2'
- count3: '3'
- count4: '4'
- String: ' instructions with '
- type: remark
--- !Analysis
Pass: generic-remarks-pass
Name: Remark2
DebugLoc: { File: path/to/anno2.c, Line: 1, Column: 2 }
Function: func1
Args:
- count1: '1'
- count2: '2'
- count3: '3'
- String: ' instructions with '
- type: remark
--- !Analysis
Pass: generic-remarks-pass
Name: Remark3
DebugLoc: { File: path/to/anno.c, Line: 1, Column: 2 }
Function: func1
Args:
- count1: '1'
- String: ' instructions with '
- type: remark
--- !Analysis
Pass: generic-remarks-pass
Name: Remark
DebugLoc: { File: path/to/anno.c, Line: 1, Column: 2 }
Function: func2
Args:
- count1: '1'
- count2: '2'
- count3: '3'
- String: ' instructions with '
- type: remark
40 changes: 40 additions & 0 deletions llvm/test/tools/llvm-remarkutil/count/Inputs/remark-filter-by.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--- !Analysis
Pass: generic-remarks-pass
Name: Remark
DebugLoc: { File: path/to/anno2.c, Line: 1, Column: 2 }
Function: func1
Args:
- count1: '1'
- String: ' instructions with '
- type: remark
--- !Analysis
Pass: generic-remarks-pass2
Name: Remark2
DebugLoc: { File: path/to/anno2.c, Line: 1, Column: 2 }
Function: func1
Args:
- count1: '1'
- count2: '2'
- count3: '3'
- String: ' instructions with '
- type: remark
--- !Missed
Pass: generic-remarks-pass
Name: Remark3
DebugLoc: { File: path/to/anno.c, Line: 1, Column: 2 }
Function: func1
Args:
- count1: '1'
- String: ' instructions with '
- type: remark
--- !Passed
Pass: generic-remarks-pass
Name: Remark
DebugLoc: { File: path/to/anno.c, Line: 1, Column: 2 }
Function: func1
Args:
- count1: '1'
- count2: '2'
- count3: '3'
- String: ' instructions with '
- type: remark
54 changes: 54 additions & 0 deletions llvm/test/tools/llvm-remarkutil/count/Inputs/remark-group-by.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
--- !Analysis
Pass: generic-remarks-pass
Name: Remark
DebugLoc: { File: path/to/anno.c, Line: 1, Column: 2 }
Function: func1
Args:
- count: '1'
- String: ' instructions with '
- type: remark
--- !Missed
Pass: generic-remarks-pass
Name: Remark
DebugLoc: { File: path/to/anno.c, Line: 1, Column: 2 }
Function: func1
Args:
- count: '3'
- String: ' instructions with '
- type: remark
--- !Passed
Pass: generic-remarks-pass
Name: Remark
DebugLoc: { File: path/to/anno.c, Line: 1, Column: 2 }
Function: func2
Args:
- count: '3'
- String: ' instructions with '
- type: remark
--- !Analysis
Pass: generic-remarks-pass2
Name: Remark
DebugLoc: { File: path/to/anno3.c, Line: 1, Column: 2 }
Function: func1
Args:
- count: '3'
- String: ' instructions with '
- type: remark
--- !Analysis
Pass: generic-remarks-pass3
Name: Remark
DebugLoc: { File: path/to/anno.c, Line: 1, Column: 2 }
Function: func2
Args:
- count: '2'
- String: ' instructions with '
- type: remark
--- !Analysis
Pass: generic-remarks-pass4
Name: Remark
DebugLoc: { File: path/to/anno2.c, Line: 1, Column: 2 }
Function: func3
Args:
- count: '2'
- String: ' instructions with '
- type: remark
20 changes: 20 additions & 0 deletions llvm/test/tools/llvm-remarkutil/count/count-by-keys.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
RUN: llvm-remarkutil count --parser=yaml --count-by=arg --group-by=source %p/Inputs/remark-count-by.yaml | FileCheck %s
RUN: llvm-remarkutil count --parser=yaml --count-by=arg --group-by=function %p/Inputs/remark-count-by.yaml | FileCheck %s --check-prefix=CHECKFUNC
RUN: llvm-remarkutil count --parser=yaml --count-by=arg --group-by=function-with-loc %p/Inputs/remark-count-by.yaml | FileCheck %s --check-prefix=CHECKFUNCLOC
RUN: llvm-remarkutil count --parser=yaml --count-by=arg --group-by=total %p/Inputs/remark-count-by.yaml | FileCheck %s --check-prefix=CHECKTOTAL

; CHECK-LABEL: Source,count1,count2,count3,count4
; CHECK: path/to/anno.c,3,4,6,4
; CHECK: path/to/anno2.c,1,2,3,0

; CHECKFUNC-LABEL: Function,count1,count2,count3,count4
; CHECKFUNC: func1,3,4,6,4
; CHECKFUNC: func2,1,2,3,0

; CHECKFUNCLOC-LABEL: FuctionWithDebugLoc,count1,count2,count3,count4
; CHECKFUNCLOC: path/to/anno.c:func1,2,2,3,4
; CHECKFUNCLOC: path/to/anno.c:func2,1,2,3,0
; CHECKFUNCLOC: path/to/anno2.c:func1,1,2,3,0

; CHECKTOTAL-LABEL: Total,count1,count2,count3,count4
; CHECKTOTAL: Total,4,6,9,4
20 changes: 20 additions & 0 deletions llvm/test/tools/llvm-remarkutil/count/count-by-remark.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
RUN: llvm-remarkutil count --parser=yaml --count-by=remark-name --group-by=source %p/Inputs/remark-count-by.yaml | FileCheck %s
RUN: llvm-remarkutil count --parser=yaml --count-by=remark-name --group-by=function %p/Inputs/remark-count-by.yaml | FileCheck %s --check-prefix=CHECKFUNC
RUN: llvm-remarkutil count --parser=yaml --count-by=remark-name --group-by=function-with-loc %p/Inputs/remark-count-by.yaml | FileCheck %s --check-prefix=CHECKFUNCLOC
RUN: llvm-remarkutil count --parser=yaml --count-by=remark-name --group-by=total %p/Inputs/remark-count-by.yaml | FileCheck %s --check-prefix=CHECKTOTAL

; CHECK-LABEL: Source,Count
; CHECK: path/to/anno.c,3
; CHECK: path/to/anno2.c,1

; CHECKFUNC-LABEL: Function,Count
; CHECKFUNC: func1,3
; CHECKFUNC: func2,1

; CHECKFUNCLOC-LABEL: FuctionWithDebugLoc,Count
; CHECKFUNCLOC: path/to/anno.c:func1,2
; CHECKFUNCLOC: path/to/anno.c:func2,1
; CHECKFUNCLOC: path/to/anno2.c:func1,1

; CHECKTOTAL-LABEL: Total,Count
; CHECKTOTAL: Total,4
10 changes: 10 additions & 0 deletions llvm/test/tools/llvm-remarkutil/count/filter-by-pass-name.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
RUN: llvm-remarkutil count --parser=yaml --pass-name=generic-remarks-pass %p/Inputs/remark-filter-by.yaml | FileCheck %s
RUN: llvm-remarkutil count --parser=yaml --rpass-name=.* %p/Inputs/remark-filter-by.yaml | FileCheck %s --check-prefix=CHECKALL

; CHECK-LABEL: Source,Count
; CHECK: path/to/anno.c,2
; CHECK: path/to/anno2.c,1

; CHECKALL-LABEL: Source,Count
; CHECKALL: path/to/anno.c,2
; CHECKALL: path/to/anno2.c,2
10 changes: 10 additions & 0 deletions llvm/test/tools/llvm-remarkutil/count/filter-by-remark-name.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
RUN: llvm-remarkutil count --parser=yaml --remark-name=Remark %p/Inputs/remark-filter-by.yaml | FileCheck %s
RUN: llvm-remarkutil count --parser=yaml --rremark-name=R.* %p/Inputs/remark-filter-by.yaml | FileCheck %s --check-prefix=CHECKALL

; CHECK-LABEL: Source,Count
; CHECK: path/to/anno.c,1
; CHECK: path/to/anno2.c,1

; CHECKALL-LABEL: Source,Count
; CHECKALL: path/to/anno.c,2
; CHECKALL: path/to/anno2.c,2
16 changes: 16 additions & 0 deletions llvm/test/tools/llvm-remarkutil/count/filter-by-type.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
RUN: llvm-remarkutil count --parser=yaml --remark-type=missed %p/Inputs/remark-filter-by.yaml | FileCheck %s --check-prefix=MISSED
RUN: llvm-remarkutil count --parser=yaml --remark-type=passed %p/Inputs/remark-filter-by.yaml | FileCheck %s --check-prefix=PASSED
RUN: llvm-remarkutil count --parser=yaml --remark-type=analysis %p/Inputs/remark-filter-by.yaml | FileCheck %s --check-prefix=ANALYSIS
RUN: llvm-remarkutil count --parser=yaml --remark-type=unknown %p/Inputs/remark-filter-by.yaml | FileCheck %s --check-prefix=UNKNOWN

; MISSED-LABEL: Source,Count
; MISSED: path/to/anno.c,1

; PASSED-LABEL: Source,Count
; PASSED: path/to/anno.c,1

; ANALYSIS-LABEL: Source,Count
; ANALYSIS: path/to/anno2.c,2

; UNKNOWN: Source,Count
; UNKNOWN-EMPTY:
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
RUN: llvm-remarkutil count --parser=yaml --group-by=function-with-loc %p/Inputs/remark-group-by.yaml | FileCheck %s

; CHECK-LABEL: FuctionWithDebugLoc,Count
; CHECK: path/to/anno.c:func1,2
; CHECK: path/to/anno.c:func2,2
; CHECK: path/to/anno2.c:func3,1
; CHECK: path/to/anno3.c:func1,1
7 changes: 7 additions & 0 deletions llvm/test/tools/llvm-remarkutil/count/group-by-function.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

RUN: llvm-remarkutil count --parser=yaml --group-by=function %p/Inputs/remark-group-by.yaml | FileCheck %s

; CHECK-LABEL: Function,Count
; CHECK: func1,3
; CHECK: func2,2
; CHECK: func3,1

0 comments on commit 31c2cf1

Please sign in to comment.