perf tools: Add parser generator for events parsing
Changing event parsing to use flex/bison parse generator.
The event syntax stays as it was.
grammar description:
events: events ',' event | event
event: event_def PE_MODIFIER_EVENT | event_def
event_def: event_legacy_symbol sep_dc |
event_legacy_cache sep_dc |
event_legacy_breakpoint sep_dc |
event_legacy_tracepoint sep_dc |
event_legacy_numeric sep_dc |
event_legacy_raw sep_dc
event_legacy_symbol: PE_NAME_SYM
event_legacy_cache: PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT |
PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT |
PE_NAME_CACHE_TYPE
event_legacy_raw: PE_SEP_RAW PE_VALUE
event_legacy_numeric: PE_VALUE ':' PE_VALUE
event_legacy_breakpoint: PE_SEP_BP ':' PE_VALUE ':' PE_MODIFIER_BP
event_breakpoint_type: PE_MODIFIER_BPTYPE | empty
PE_NAME_SYM: cpu-cycles|cycles |
stalled-cycles-frontend|idle-cycles-frontend |
stalled-cycles-backend|idle-cycles-backend |
instructions |
cache-references |
cache-misses |
branch-instructions|branches |
branch-misses |
bus-cycles |
cpu-clock |
task-clock |
page-faults|faults |
minor-faults |
major-faults |
context-switches|cs |
cpu-migrations|migrations |
alignment-faults |
emulation-faults
PE_NAME_CACHE_TYPE: L1-dcache|l1-d|l1d|L1-data |
L1-icache|l1-i|l1i|L1-instruction |
LLC|L2 |
dTLB|d-tlb|Data-TLB |
iTLB|i-tlb|Instruction-TLB |
branch|branches|bpu|btb|bpc |
node
PE_NAME_CACHE_OP_RESULT: load|loads|read |
store|stores|write |
prefetch|prefetches |
speculative-read|speculative-load |
refs|Reference|ops|access |
misses|miss
PE_MODIFIER_EVENT: [ukhp]{0,5}
PE_MODIFIER_BP: [rwx]
PE_SEP_BP: 'mem'
PE_SEP_RAW: 'r'
sep_dc: ':' |
Added flex/bison files for event grammar parsing. The generated
parser is part of the patch. Added makefile rule 'event-parser'
to generate the parser code out of the bison/flex sources.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/n/tip-u4pfig5waq3ll2bfcdex8fgi@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
new file mode 100644
index 0000000..4b4459e
--- /dev/null
+++ b/tools/perf/util/parse-events.y
@@ -0,0 +1,127 @@
+
+%name-prefix "parse_events_"
+%parse-param {struct list_head *list}
+%parse-param {int *idx}
+
+%{
+
+#define YYDEBUG 1
+
+#include <linux/compiler.h>
+#include <linux/list.h>
+#include "types.h"
+#include "util.h"
+#include "parse-events.h"
+
+extern int parse_events_lex (void);
+
+#define ABORT_ON(val) \
+do { \
+ if (val) \
+ YYABORT; \
+} while (0)
+
+%}
+
+%token PE_VALUE PE_VALUE_SYM PE_RAW
+%token PE_NAME
+%token PE_MODIFIER_EVENT PE_MODIFIER_BP
+%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
+%token PE_PREFIX_MEM PE_PREFIX_RAW
+%token PE_ERROR
+%type <num> PE_VALUE
+%type <num> PE_VALUE_SYM
+%type <num> PE_RAW
+%type <str> PE_NAME
+%type <str> PE_NAME_CACHE_TYPE
+%type <str> PE_NAME_CACHE_OP_RESULT
+%type <str> PE_MODIFIER_EVENT
+%type <str> PE_MODIFIER_BP
+
+%union
+{
+ char *str;
+ unsigned long num;
+}
+%%
+
+events:
+events ',' event | event
+
+event:
+event_def PE_MODIFIER_EVENT
+{
+ ABORT_ON(parse_events_modifier(list, $2));
+}
+|
+event_def
+
+event_def: event_legacy_symbol sep_dc |
+ event_legacy_cache sep_dc |
+ event_legacy_mem |
+ event_legacy_tracepoint sep_dc |
+ event_legacy_numeric sep_dc |
+ event_legacy_raw sep_dc
+
+event_legacy_symbol:
+PE_VALUE_SYM
+{
+ int type = $1 >> 16;
+ int config = $1 & 255;
+
+ ABORT_ON(parse_events_add_numeric(list, idx, type, config));
+}
+
+event_legacy_cache:
+PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT
+{
+ ABORT_ON(parse_events_add_cache(list, idx, $1, $3, $5));
+}
+|
+PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT
+{
+ ABORT_ON(parse_events_add_cache(list, idx, $1, $3, NULL));
+}
+|
+PE_NAME_CACHE_TYPE
+{
+ ABORT_ON(parse_events_add_cache(list, idx, $1, NULL, NULL));
+}
+
+event_legacy_mem:
+PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
+{
+ ABORT_ON(parse_events_add_breakpoint(list, idx, (void *) $2, $4));
+}
+|
+PE_PREFIX_MEM PE_VALUE sep_dc
+{
+ ABORT_ON(parse_events_add_breakpoint(list, idx, (void *) $2, NULL));
+}
+
+event_legacy_tracepoint:
+PE_NAME ':' PE_NAME
+{
+ ABORT_ON(parse_events_add_tracepoint(list, idx, $1, $3));
+}
+
+event_legacy_numeric:
+PE_VALUE ':' PE_VALUE
+{
+ ABORT_ON(parse_events_add_numeric(list, idx, $1, $3));
+}
+
+event_legacy_raw:
+PE_RAW
+{
+ ABORT_ON(parse_events_add_numeric(list, idx, PERF_TYPE_RAW, $1));
+}
+
+sep_dc: ':' |
+
+%%
+
+void parse_events_error(struct list_head *list __used, int *idx __used,
+ char const *msg __used)
+{
+}