diff options
Diffstat (limited to 'tools/perf/util/parse-events.y')
| -rw-r--r-- | tools/perf/util/parse-events.y | 298 |
1 files changed, 239 insertions, 59 deletions
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 362cc59332a..0bc87ba46bf 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -1,7 +1,7 @@ - -%name-prefix "parse_events_" -%parse-param {struct list_head *list_all} -%parse-param {int *idx} +%pure-parser +%parse-param {void *_data} +%parse-param {void *scanner} +%lex-param {void* scanner} %{ @@ -9,11 +9,12 @@ #include <linux/compiler.h> #include <linux/list.h> -#include "types.h" +#include <linux/types.h> #include "util.h" #include "parse-events.h" +#include "parse-events-bison.h" -extern int parse_events_lex (void); +extern int parse_events_lex (YYSTYPE* lvalp, void* scanner); #define ABORT_ON(val) \ do { \ @@ -21,16 +22,34 @@ do { \ YYABORT; \ } while (0) +#define ALLOC_LIST(list) \ +do { \ + list = malloc(sizeof(*list)); \ + ABORT_ON(!list); \ + INIT_LIST_HEAD(list); \ +} while (0) + +static inc_group_count(struct list_head *list, + struct parse_events_evlist *data) +{ + /* Count groups only have more than 1 members */ + if (!list_is_last(list->next, list)) + data->nr_groups++; +} + %} -%token PE_VALUE PE_VALUE_SYM PE_RAW PE_TERM +%token PE_START_EVENTS PE_START_TERMS +%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM +%token PE_EVENT_NAME %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_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP %token PE_ERROR %type <num> PE_VALUE -%type <num> PE_VALUE_SYM +%type <num> PE_VALUE_SYM_HW +%type <num> PE_VALUE_SYM_SW %type <num> PE_RAW %type <num> PE_TERM %type <str> PE_NAME @@ -38,6 +57,8 @@ do { \ %type <str> PE_NAME_CACHE_OP_RESULT %type <str> PE_MODIFIER_EVENT %type <str> PE_MODIFIER_BP +%type <str> PE_EVENT_NAME +%type <num> value_sym %type <head> event_config %type <term> event_term %type <head> event_pmu @@ -48,35 +69,127 @@ do { \ %type <head> event_legacy_numeric %type <head> event_legacy_raw %type <head> event_def +%type <head> event_mod +%type <head> event_name +%type <head> event +%type <head> events +%type <head> group_def +%type <head> group +%type <head> groups %union { char *str; - unsigned long num; + u64 num; struct list_head *head; - struct parse_events__term *term; + struct parse_events_term *term; } %% +start: +PE_START_EVENTS start_events +| +PE_START_TERMS start_terms + +start_events: groups +{ + struct parse_events_evlist *data = _data; + + parse_events_update_lists($1, &data->list); +} + +groups: +groups ',' group +{ + struct list_head *list = $1; + struct list_head *group = $3; + + parse_events_update_lists(group, list); + $$ = list; +} +| +groups ',' event +{ + struct list_head *list = $1; + struct list_head *event = $3; + + parse_events_update_lists(event, list); + $$ = list; +} +| +group +| +event + +group: +group_def ':' PE_MODIFIER_EVENT +{ + struct list_head *list = $1; + + ABORT_ON(parse_events__modifier_group(list, $3)); + $$ = list; +} +| +group_def + +group_def: +PE_NAME '{' events '}' +{ + struct list_head *list = $3; + + inc_group_count(list, _data); + parse_events__set_leader($1, list); + $$ = list; +} +| +'{' events '}' +{ + struct list_head *list = $2; + + inc_group_count(list, _data); + parse_events__set_leader(NULL, list); + $$ = list; +} + events: -events ',' event | event +events ',' event +{ + struct list_head *event = $3; + struct list_head *list = $1; + + parse_events_update_lists(event, list); + $$ = list; +} +| +event + +event: event_mod -event: -event_def PE_MODIFIER_EVENT +event_mod: +event_name PE_MODIFIER_EVENT { + struct list_head *list = $1; + /* * Apply modifier on all events added by single event definition * (there could be more events added for multiple tracepoint * definitions via '*?'. */ - ABORT_ON(parse_events_modifier($1, $2)); - parse_events_update_lists($1, list_all); + ABORT_ON(parse_events__modifier_event(list, $2, false)); + $$ = list; } | -event_def +event_name + +event_name: +PE_EVENT_NAME event_def { - parse_events_update_lists($1, list_all); + ABORT_ON(parse_events_name($2, $1)); + free($1); + $$ = $2; } +| +event_def event_def: event_pmu | event_legacy_symbol | @@ -89,109 +202,159 @@ event_def: event_pmu | event_pmu: PE_NAME '/' event_config '/' { - struct list_head *list = NULL; + struct parse_events_evlist *data = _data; + struct list_head *list; - ABORT_ON(parse_events_add_pmu(&list, idx, $1, $3)); + ALLOC_LIST(list); + ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, $3)); parse_events__free_terms($3); $$ = list; } +value_sym: +PE_VALUE_SYM_HW +| +PE_VALUE_SYM_SW + event_legacy_symbol: -PE_VALUE_SYM '/' event_config '/' +value_sym '/' event_config '/' { - struct list_head *list = NULL; + struct parse_events_evlist *data = _data; + struct list_head *list; int type = $1 >> 16; int config = $1 & 255; - ABORT_ON(parse_events_add_numeric(&list, idx, type, config, $3)); + ALLOC_LIST(list); + ABORT_ON(parse_events_add_numeric(list, &data->idx, + type, config, $3)); parse_events__free_terms($3); $$ = list; } | -PE_VALUE_SYM sep_slash_dc +value_sym sep_slash_dc { - struct list_head *list = NULL; + struct parse_events_evlist *data = _data; + struct list_head *list; int type = $1 >> 16; int config = $1 & 255; - ABORT_ON(parse_events_add_numeric(&list, idx, type, config, NULL)); + ALLOC_LIST(list); + ABORT_ON(parse_events_add_numeric(list, &data->idx, + type, config, NULL)); $$ = list; } event_legacy_cache: PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT { - struct list_head *list = NULL; + struct parse_events_evlist *data = _data; + struct list_head *list; - ABORT_ON(parse_events_add_cache(&list, idx, $1, $3, $5)); + ALLOC_LIST(list); + ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, $5)); $$ = list; } | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT { - struct list_head *list = NULL; + struct parse_events_evlist *data = _data; + struct list_head *list; - ABORT_ON(parse_events_add_cache(&list, idx, $1, $3, NULL)); + ALLOC_LIST(list); + ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, NULL)); $$ = list; } | PE_NAME_CACHE_TYPE { - struct list_head *list = NULL; + struct parse_events_evlist *data = _data; + struct list_head *list; - ABORT_ON(parse_events_add_cache(&list, idx, $1, NULL, NULL)); + ALLOC_LIST(list); + ABORT_ON(parse_events_add_cache(list, &data->idx, $1, NULL, NULL)); $$ = list; } event_legacy_mem: PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc { - struct list_head *list = NULL; + struct parse_events_evlist *data = _data; + struct list_head *list; - ABORT_ON(parse_events_add_breakpoint(&list, idx, (void *) $2, $4)); + ALLOC_LIST(list); + ABORT_ON(parse_events_add_breakpoint(list, &data->idx, + (void *) $2, $4)); $$ = list; } | PE_PREFIX_MEM PE_VALUE sep_dc { - struct list_head *list = NULL; + struct parse_events_evlist *data = _data; + struct list_head *list; - ABORT_ON(parse_events_add_breakpoint(&list, idx, (void *) $2, NULL)); + ALLOC_LIST(list); + ABORT_ON(parse_events_add_breakpoint(list, &data->idx, + (void *) $2, NULL)); $$ = list; } event_legacy_tracepoint: +PE_NAME '-' PE_NAME ':' PE_NAME +{ + struct parse_events_evlist *data = _data; + struct list_head *list; + char sys_name[128]; + snprintf(&sys_name, 128, "%s-%s", $1, $3); + + ALLOC_LIST(list); + ABORT_ON(parse_events_add_tracepoint(list, &data->idx, &sys_name, $5)); + $$ = list; +} +| PE_NAME ':' PE_NAME { - struct list_head *list = NULL; + struct parse_events_evlist *data = _data; + struct list_head *list; - ABORT_ON(parse_events_add_tracepoint(&list, idx, $1, $3)); + ALLOC_LIST(list); + ABORT_ON(parse_events_add_tracepoint(list, &data->idx, $1, $3)); $$ = list; } event_legacy_numeric: PE_VALUE ':' PE_VALUE { - struct list_head *list = NULL; + struct parse_events_evlist *data = _data; + struct list_head *list; - ABORT_ON(parse_events_add_numeric(&list, idx, $1, $3, NULL)); + ALLOC_LIST(list); + ABORT_ON(parse_events_add_numeric(list, &data->idx, (u32)$1, $3, NULL)); $$ = list; } event_legacy_raw: PE_RAW { - struct list_head *list = NULL; + struct parse_events_evlist *data = _data; + struct list_head *list; - ABORT_ON(parse_events_add_numeric(&list, idx, PERF_TYPE_RAW, $1, NULL)); + ALLOC_LIST(list); + ABORT_ON(parse_events_add_numeric(list, &data->idx, + PERF_TYPE_RAW, $1, NULL)); $$ = list; } +start_terms: event_config +{ + struct parse_events_terms *data = _data; + data->terms = $1; +} + event_config: event_config ',' event_term { struct list_head *head = $1; - struct parse_events__term *term = $3; + struct parse_events_term *term = $3; ABORT_ON(!head); list_add_tail(&term->list, head); @@ -201,7 +364,7 @@ event_config ',' event_term event_term { struct list_head *head = malloc(sizeof(*head)); - struct parse_events__term *term = $1; + struct parse_events_term *term = $1; ABORT_ON(!head); INIT_LIST_HEAD(head); @@ -212,52 +375,70 @@ event_term event_term: PE_NAME '=' PE_NAME { - struct parse_events__term *term; + struct parse_events_term *term; - ABORT_ON(parse_events__term_str(&term, PARSE_EVENTS__TERM_TYPE_USER, + ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, $1, $3)); $$ = term; } | PE_NAME '=' PE_VALUE { - struct parse_events__term *term; + struct parse_events_term *term; - ABORT_ON(parse_events__term_num(&term, PARSE_EVENTS__TERM_TYPE_USER, + ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, $1, $3)); $$ = term; } | +PE_NAME '=' PE_VALUE_SYM_HW +{ + struct parse_events_term *term; + int config = $3 & 255; + + ABORT_ON(parse_events_term__sym_hw(&term, $1, config)); + $$ = term; +} +| PE_NAME { - struct parse_events__term *term; + struct parse_events_term *term; - ABORT_ON(parse_events__term_num(&term, PARSE_EVENTS__TERM_TYPE_USER, + ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, $1, 1)); $$ = term; } | +PE_VALUE_SYM_HW +{ + struct parse_events_term *term; + int config = $1 & 255; + + ABORT_ON(parse_events_term__sym_hw(&term, NULL, config)); + $$ = term; +} +| PE_TERM '=' PE_NAME { - struct parse_events__term *term; + struct parse_events_term *term; - ABORT_ON(parse_events__term_str(&term, $1, NULL, $3)); + ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3)); $$ = term; } | PE_TERM '=' PE_VALUE { - struct parse_events__term *term; + struct parse_events_term *term; - ABORT_ON(parse_events__term_num(&term, $1, NULL, $3)); + ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3)); $$ = term; } | PE_TERM { - struct parse_events__term *term; + struct parse_events_term *term; - ABORT_ON(parse_events__term_num(&term, $1, NULL, 1)); + ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1)); $$ = term; } @@ -267,8 +448,7 @@ sep_slash_dc: '/' | ':' | %% -void parse_events_error(struct list_head *list_all __used, - int *idx __used, - char const *msg __used) +void parse_events_error(void *data __maybe_unused, void *scanner __maybe_unused, + char const *msg __maybe_unused) { } |
