~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/expr.y

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /tools/perf/util/expr.y (Version linux-6.12-rc7) and /tools/perf/util/expr.y (Version linux-5.7.19)


  1 /* Simple expression parser */                      1 /* Simple expression parser */
  2 %{                                                  2 %{
  3 #ifndef NDEBUG                                 << 
  4 #define YYDEBUG 1                                   3 #define YYDEBUG 1
  5 #endif                                         !!   4 #include <stdio.h>
  6 #include <assert.h>                            !!   5 #include "util.h"
  7 #include <math.h>                              << 
  8 #include <stdlib.h>                            << 
  9 #include "util/debug.h"                             6 #include "util/debug.h"
                                                   >>   7 #include <stdlib.h> // strtod()
 10 #define IN_EXPR_Y 1                                 8 #define IN_EXPR_Y 1
 11 #include "expr.h"                                   9 #include "expr.h"
 12 #include "expr-bison.h"                        !!  10 #include "smt.h"
 13 int expr_lex(YYSTYPE * yylval_param , void *yy !!  11 #include <string.h>
                                                   >>  12 
 14 %}                                                 13 %}
 15                                                    14 
 16 %define api.pure full                              15 %define api.pure full
 17                                                    16 
 18 %parse-param { double *final_val }                 17 %parse-param { double *final_val }
 19 %parse-param { struct expr_parse_ctx *ctx }    !!  18 %parse-param { struct parse_ctx *ctx }
 20 %parse-param { bool compute_ids }              << 
 21 %parse-param {void *scanner}                       19 %parse-param {void *scanner}
 22 %lex-param {void* scanner}                         20 %lex-param {void* scanner}
 23                                                    21 
 24 %union {                                           22 %union {
 25         double   num;                              23         double   num;
 26         char    *str;                              24         char    *str;
 27         struct ids {                           << 
 28                 /*                             << 
 29                  * When creating ids, holds th << 
 30                  * implies the set is empty.   << 
 31                  */                            << 
 32                 struct hashmap *ids;           << 
 33                 /*                             << 
 34                  * The metric value. When not  << 
 35                  * read from a counter, a cons << 
 36                  * creating ids the value is e << 
 37                  * used as the special BOTTOM  << 
 38                  * values" case.               << 
 39                  */                            << 
 40                 double val;                    << 
 41         } ids;                                 << 
 42 }                                                  25 }
 43                                                    26 
 44 %token ID NUMBER MIN MAX IF ELSE LITERAL D_RAT !!  27 %token EXPR_PARSE EXPR_OTHER EXPR_ERROR
                                                   >>  28 %token <num> NUMBER
                                                   >>  29 %token <str> ID
                                                   >>  30 %token MIN MAX IF ELSE SMT_ON
 45 %left MIN MAX IF                                   31 %left MIN MAX IF
 46 %left '|'                                          32 %left '|'
 47 %left '^'                                          33 %left '^'
 48 %left '&'                                          34 %left '&'
 49 %left '<' '>'                                  << 
 50 %left '-' '+'                                      35 %left '-' '+'
 51 %left '*' '/' '%'                                  36 %left '*' '/' '%'
 52 %left NEG NOT                                      37 %left NEG NOT
 53 %type <num> NUMBER LITERAL                     !!  38 %type <num> expr if_expr
 54 %type <str> ID                                 << 
 55 %destructor { free ($$); } <str>               << 
 56 %type <ids> expr if_expr                       << 
 57 %destructor { ids__free($$.ids); } <ids>       << 
 58                                                    39 
 59 %{                                                 40 %{
 60 static void expr_error(double *final_val __may     41 static void expr_error(double *final_val __maybe_unused,
 61                        struct expr_parse_ctx * !!  42                        struct parse_ctx *ctx __maybe_unused,
 62                        bool compute_ids __mayb !!  43                        void *scanner,
 63                        void *scanner __maybe_u << 
 64                        const char *s)              44                        const char *s)
 65 {                                                  45 {
 66         pr_debug("%s\n", s);                       46         pr_debug("%s\n", s);
 67 }                                                  47 }
 68                                                    48 
 69 /*                                             !!  49 static int lookup_id(struct parse_ctx *ctx, char *id, double *val)
 70  * During compute ids, the special "bottom" va << 
 71  * of all values. NAN is selected as it isn't  << 
 72  */                                            << 
 73 #define BOTTOM NAN                             << 
 74                                                << 
 75 /* During computing ids, does val represent a  << 
 76 static bool is_const(double val)               << 
 77 {                                              << 
 78         return isfinite(val);                  << 
 79 }                                              << 
 80                                                << 
 81 static struct ids union_expr(struct ids ids1,  << 
 82 {                                              << 
 83         struct ids result = {                  << 
 84                 .val = BOTTOM,                 << 
 85                 .ids = ids__union(ids1.ids, id << 
 86         };                                     << 
 87         return result;                         << 
 88 }                                              << 
 89                                                << 
 90 static struct ids handle_id(struct expr_parse_ << 
 91                             bool compute_ids,  << 
 92 {                                                  50 {
 93         struct ids result;                     !!  51         int i;
 94                                                    52 
 95         if (!compute_ids) {                    !!  53         for (i = 0; i < ctx->num_ids; i++) {
 96                 /*                             !!  54                 if (!strcasecmp(ctx->ids[i].name, id)) {
 97                  * Compute the event's value f !!  55                         *val = ctx->ids[i].val;
 98                  * it isn't used to compute th !!  56                         return 0;
 99                  */                            << 
100                 struct expr_id_data *data;     << 
101                                                << 
102                 result.val = NAN;              << 
103                 if (expr__resolve_id(ctx, id,  << 
104                         result.val = source_co << 
105                                 ? expr_id_data << 
106                                 : expr_id_data << 
107                 }                              << 
108                 result.ids = NULL;             << 
109                 free(id);                      << 
110         } else {                               << 
111                 /*                             << 
112                  * Set the value to BOTTOM to  << 
113                  * when the event is computed. << 
114                  */                            << 
115                 result.val = BOTTOM;           << 
116                 result.ids = ids__new();       << 
117                 if (!result.ids || ids__insert << 
118                         pr_err("Error creating << 
119                         free(id);              << 
120                 }                                  57                 }
121         }                                          58         }
122         return result;                         !!  59         return -1;
123 }                                                  60 }
124                                                    61 
125 /*                                             << 
126  * If we're not computing ids or $1 and $3 are << 
127  * constant value using OP. Its invariant that << 
128  * ids for non-constants union the set of IDs  << 
129  */                                            << 
130 #define BINARY_OP(RESULT, OP, LHS, RHS)        << 
131         if (!compute_ids || (is_const(LHS.val) << 
132                 assert(LHS.ids == NULL);       << 
133                 assert(RHS.ids == NULL);       << 
134                 if (isnan(LHS.val) || isnan(RH << 
135                         RESULT.val = NAN;      << 
136                 } else {                       << 
137                         RESULT.val = LHS.val O << 
138                 }                              << 
139                 RESULT.ids = NULL;             << 
140         } else {                               << 
141                 RESULT = union_expr(LHS, RHS); << 
142         }                                      << 
143                                                << 
144 %}                                                 62 %}
145 %%                                                 63 %%
146                                                    64 
147 start: if_expr                                 !!  65 start:
148 {                                              !!  66 EXPR_PARSE all_expr
149         if (compute_ids)                       !!  67 |
150                 ctx->ids = ids__union($1.ids,  !!  68 EXPR_OTHER all_other
151                                                    69 
152         if (final_val)                         !!  70 all_other: all_other other
153                 *final_val = $1.val;           !!  71 |
154 }                                              << 
155 ;                                              << 
156                                                    72 
157 if_expr: expr IF expr ELSE if_expr             !!  73 other: ID
158 {                                              << 
159         if (fpclassify($3.val) == FP_ZERO) {   << 
160                 /*                             << 
161                  * The IF expression evaluated << 
162                  * ELSE and discard everything << 
163                  */                            << 
164                 $$.val = $5.val;               << 
165                 $$.ids = $5.ids;               << 
166                 ids__free($1.ids);             << 
167                 ids__free($3.ids);             << 
168         } else if (!compute_ids || is_const($3 << 
169                 /*                             << 
170                  * If ids aren't computed then << 
171                  * ids are being computed and  << 
172                  * constant, then also evaluat << 
173                  */                            << 
174                 $$.val = $1.val;               << 
175                 $$.ids = $1.ids;               << 
176                 ids__free($3.ids);             << 
177                 ids__free($5.ids);             << 
178         } else if ($1.val == $5.val) {         << 
179                 /*                             << 
180                  * LHS == RHS, so both are an  << 
181                  * evaluate any events.        << 
182                  */                            << 
183                 $$.val = $1.val;               << 
184                 $$.ids = NULL;                 << 
185                 ids__free($1.ids);             << 
186                 ids__free($3.ids);             << 
187                 ids__free($5.ids);             << 
188         } else {                               << 
189                 /*                             << 
190                  * Value is either the LHS or  << 
191                  * to compute it.              << 
192                  */                            << 
193                 $$ = union_expr($1, union_expr << 
194         }                                      << 
195 }                                              << 
196 | expr                                         << 
197 ;                                              << 
198                                                << 
199 expr: NUMBER                                   << 
200 {                                              << 
201         $$.val = $1;                           << 
202         $$.ids = NULL;                         << 
203 }                                              << 
204 | ID                            { $$ = handle_ << 
205 | SOURCE_COUNT '(' ID ')'       { $$ = handle_ << 
206 | HAS_EVENT '(' ID ')'                         << 
207 {                                              << 
208         $$.val = expr__has_event(ctx, compute_ << 
209         $$.ids = NULL;                         << 
210         free($3);                              << 
211 }                                              << 
212 | STRCMP_CPUID_STR '(' ID ')'                  << 
213 {                                              << 
214         $$.val = expr__strcmp_cpuid_str(ctx, c << 
215         $$.ids = NULL;                         << 
216         free($3);                              << 
217 }                                              << 
218 | expr '|' expr                                << 
219 {                                              << 
220         if (is_const($1.val) && is_const($3.va << 
221                 assert($1.ids == NULL);        << 
222                 assert($3.ids == NULL);        << 
223                 $$.ids = NULL;                 << 
224                 $$.val = (fpclassify($1.val) = << 
225         } else if (is_const($1.val)) {         << 
226                 assert($1.ids == NULL);        << 
227                 if (fpclassify($1.val) == FP_Z << 
228                         $$ = $3;               << 
229                 } else {                       << 
230                         $$.val = 1;            << 
231                         $$.ids = NULL;         << 
232                         ids__free($3.ids);     << 
233                 }                              << 
234         } else if (is_const($3.val)) {         << 
235                 assert($3.ids == NULL);        << 
236                 if (fpclassify($3.val) == FP_Z << 
237                         $$ = $1;               << 
238                 } else {                       << 
239                         $$.val = 1;            << 
240                         $$.ids = NULL;         << 
241                         ids__free($1.ids);     << 
242                 }                              << 
243         } else {                               << 
244                 $$ = union_expr($1, $3);       << 
245         }                                      << 
246 }                                              << 
247 | expr '&' expr                                << 
248 {                                              << 
249         if (is_const($1.val) && is_const($3.va << 
250                 assert($1.ids == NULL);        << 
251                 assert($3.ids == NULL);        << 
252                 $$.val = (fpclassify($1.val) ! << 
253                 $$.ids = NULL;                 << 
254         } else if (is_const($1.val)) {         << 
255                 assert($1.ids == NULL);        << 
256                 if (fpclassify($1.val) != FP_Z << 
257                         $$ = $3;               << 
258                 } else {                       << 
259                         $$.val = 0;            << 
260                         $$.ids = NULL;         << 
261                         ids__free($3.ids);     << 
262                 }                              << 
263         } else if (is_const($3.val)) {         << 
264                 assert($3.ids == NULL);        << 
265                 if (fpclassify($3.val) != FP_Z << 
266                         $$ = $1;               << 
267                 } else {                       << 
268                         $$.val = 0;            << 
269                         $$.ids = NULL;         << 
270                         ids__free($1.ids);     << 
271                 }                              << 
272         } else {                               << 
273                 $$ = union_expr($1, $3);       << 
274         }                                      << 
275 }                                              << 
276 | expr '^' expr                                << 
277 {                                                  74 {
278         if (is_const($1.val) && is_const($3.va !!  75         if (ctx->num_ids + 1 >= EXPR_MAX_OTHER) {
279                 assert($1.ids == NULL);        !!  76                 pr_err("failed: way too many variables");
280                 assert($3.ids == NULL);        << 
281                 $$.val = (fpclassify($1.val) = << 
282                 $$.ids = NULL;                 << 
283         } else {                               << 
284                 $$ = union_expr($1, $3);       << 
285         }                                      << 
286 }                                              << 
287 | expr '<' expr { BINARY_OP($$, <, $1, $3); }  << 
288 | expr '>' expr { BINARY_OP($$, >, $1, $3); }  << 
289 | expr '+' expr { BINARY_OP($$, +, $1, $3); }  << 
290 | expr '-' expr { BINARY_OP($$, -, $1, $3); }  << 
291 | expr '*' expr { BINARY_OP($$, *, $1, $3); }  << 
292 | expr '/' expr                                << 
293 {                                              << 
294         if (fpclassify($3.val) == FP_ZERO) {   << 
295                 pr_debug("division by zero\n") << 
296                 assert($3.ids == NULL);        << 
297                 if (compute_ids)               << 
298                         ids__free($1.ids);     << 
299                 $$.val = NAN;                  << 
300                 $$.ids = NULL;                 << 
301         } else if (!compute_ids || (is_const($ << 
302                 assert($1.ids == NULL);        << 
303                 assert($3.ids == NULL);        << 
304                 $$.val = $1.val / $3.val;      << 
305                 $$.ids = NULL;                 << 
306         } else {                               << 
307                 /* LHS and/or RHS need computi << 
308                 $$ = union_expr($1, $3);       << 
309         }                                      << 
310 }                                              << 
311 | expr '%' expr                                << 
312 {                                              << 
313         if (fpclassify($3.val) == FP_ZERO) {   << 
314                 pr_debug("division by zero\n") << 
315                 YYABORT;                           77                 YYABORT;
316         } else if (!compute_ids || (is_const($ << 
317                 assert($1.ids == NULL);        << 
318                 assert($3.ids == NULL);        << 
319                 $$.val = (long)$1.val % (long) << 
320                 $$.ids = NULL;                 << 
321         } else {                               << 
322                 /* LHS and/or RHS need computi << 
323                 $$ = union_expr($1, $3);       << 
324         }                                          78         }
                                                   >>  79 
                                                   >>  80         ctx->ids[ctx->num_ids++].name = $1;
325 }                                                  81 }
326 | D_RATIO '(' expr ',' expr ')'                !!  82 |
327 {                                              !!  83 MIN | MAX | IF | ELSE | SMT_ON | NUMBER | '|' | '^' | '&' | '-' | '+' | '*' | '/' | '%' | '(' | ')'
328         if (fpclassify($5.val) == FP_ZERO) {   !!  84 
329                 /*                             !!  85 
330                  * Division by constant zero a !!  86 all_expr: if_expr                       { *final_val = $1; }
331                  * are necessary.              !!  87         ;
332                  */                            !!  88 
333                 assert($5.ids == NULL);        !!  89 if_expr:
334                 $$.val = 0.0;                  !!  90         expr IF expr ELSE expr { $$ = $3 ? $1 : $5; }
335                 $$.ids = NULL;                 !!  91         | expr
336                 ids__free($3.ids);             !!  92         ;
337         } else if (!compute_ids || (is_const($ !!  93 
338                 assert($3.ids == NULL);        !!  94 expr:     NUMBER
339                 assert($5.ids == NULL);        !!  95         | ID                    { if (lookup_id(ctx, $1, &$$) < 0) {
340                 $$.val = $3.val / $5.val;      !!  96                                         pr_debug("%s not found\n", $1);
341                 $$.ids = NULL;                 !!  97                                         YYABORT;
342         } else {                               !!  98                                   }
343                 /* LHS and/or RHS need computi !!  99                                 }
344                 $$ = union_expr($3, $5);       !! 100         | expr '|' expr         { $$ = (long)$1 | (long)$3; }
345         }                                      !! 101         | expr '&' expr         { $$ = (long)$1 & (long)$3; }
346 }                                              !! 102         | expr '^' expr         { $$ = (long)$1 ^ (long)$3; }
347 | '-' expr %prec NEG                           !! 103         | expr '+' expr         { $$ = $1 + $3; }
348 {                                              !! 104         | expr '-' expr         { $$ = $1 - $3; }
349         $$.val = -$2.val;                      !! 105         | expr '*' expr         { $$ = $1 * $3; }
350         $$.ids = $2.ids;                       !! 106         | expr '/' expr         { if ($3 == 0) YYABORT; $$ = $1 / $3; }
351 }                                              !! 107         | expr '%' expr         { if ((long)$3 == 0) YYABORT; $$ = (long)$1 % (long)$3; }
352 | '(' if_expr ')'                              !! 108         | '-' expr %prec NEG    { $$ = -$2; }
353 {                                              !! 109         | '(' if_expr ')'       { $$ = $2; }
354         $$ = $2;                               !! 110         | MIN '(' expr ',' expr ')' { $$ = $3 < $5 ? $3 : $5; }
355 }                                              !! 111         | MAX '(' expr ',' expr ')' { $$ = $3 > $5 ? $3 : $5; }
356 | MIN '(' expr ',' expr ')'                    !! 112         | SMT_ON                 { $$ = smt_on() > 0; }
357 {                                              !! 113         ;
358         if (!compute_ids) {                    << 
359                 $$.val = $3.val < $5.val ? $3. << 
360                 $$.ids = NULL;                 << 
361         } else {                               << 
362                 $$ = union_expr($3, $5);       << 
363         }                                      << 
364 }                                              << 
365 | MAX '(' expr ',' expr ')'                    << 
366 {                                              << 
367         if (!compute_ids) {                    << 
368                 $$.val = $3.val > $5.val ? $3. << 
369                 $$.ids = NULL;                 << 
370         } else {                               << 
371                 $$ = union_expr($3, $5);       << 
372         }                                      << 
373 }                                              << 
374 | LITERAL                                      << 
375 {                                              << 
376         $$.val = $1;                           << 
377         $$.ids = NULL;                         << 
378 }                                              << 
379 ;                                              << 
380                                                   114 
381 %%                                                115 %%
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php