~ [ 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.15.171)


  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 
                                                   >>  13 static double d_ratio(double val0, double val1)
                                                   >>  14 {
                                                   >>  15         if (val1 == 0) {
                                                   >>  16                 return 0;
                                                   >>  17         }
                                                   >>  18         return  val0 / val1;
                                                   >>  19 }
                                                   >>  20 
 14 %}                                                 21 %}
 15                                                    22 
 16 %define api.pure full                              23 %define api.pure full
 17                                                    24 
 18 %parse-param { double *final_val }                 25 %parse-param { double *final_val }
 19 %parse-param { struct expr_parse_ctx *ctx }        26 %parse-param { struct expr_parse_ctx *ctx }
 20 %parse-param { bool compute_ids }              << 
 21 %parse-param {void *scanner}                       27 %parse-param {void *scanner}
 22 %lex-param {void* scanner}                         28 %lex-param {void* scanner}
 23                                                    29 
 24 %union {                                           30 %union {
 25         double   num;                              31         double   num;
 26         char    *str;                              32         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 }                                                  33 }
 43                                                    34 
 44 %token ID NUMBER MIN MAX IF ELSE LITERAL D_RAT !!  35 %token EXPR_PARSE EXPR_OTHER EXPR_ERROR
                                                   >>  36 %token <num> NUMBER
                                                   >>  37 %token <str> ID
                                                   >>  38 %destructor { free ($$); } <str>
                                                   >>  39 %token MIN MAX IF ELSE SMT_ON D_RATIO
 45 %left MIN MAX IF                                   40 %left MIN MAX IF
 46 %left '|'                                          41 %left '|'
 47 %left '^'                                          42 %left '^'
 48 %left '&'                                          43 %left '&'
 49 %left '<' '>'                                      44 %left '<' '>'
 50 %left '-' '+'                                      45 %left '-' '+'
 51 %left '*' '/' '%'                                  46 %left '*' '/' '%'
 52 %left NEG NOT                                      47 %left NEG NOT
 53 %type <num> NUMBER LITERAL                     !!  48 %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                                                    49 
 59 %{                                                 50 %{
 60 static void expr_error(double *final_val __may     51 static void expr_error(double *final_val __maybe_unused,
 61                        struct expr_parse_ctx *     52                        struct expr_parse_ctx *ctx __maybe_unused,
 62                        bool compute_ids __mayb !!  53                        void *scanner,
 63                        void *scanner __maybe_u << 
 64                        const char *s)              54                        const char *s)
 65 {                                                  55 {
 66         pr_debug("%s\n", s);                       56         pr_debug("%s\n", s);
 67 }                                                  57 }
 68                                                    58 
 69 /*                                             << 
 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 {                                              << 
 93         struct ids result;                     << 
 94                                                << 
 95         if (!compute_ids) {                    << 
 96                 /*                             << 
 97                  * Compute the event's value f << 
 98                  * it isn't used to compute th << 
 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                 }                              << 
121         }                                      << 
122         return result;                         << 
123 }                                              << 
124                                                << 
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 %}                                                 59 %}
145 %%                                                 60 %%
146                                                    61 
147 start: if_expr                                 !!  62 start:
148 {                                              !!  63 EXPR_PARSE all_expr
149         if (compute_ids)                       !!  64 |
150                 ctx->ids = ids__union($1.ids,  !!  65 EXPR_OTHER all_other
151                                                !!  66 
152         if (final_val)                         !!  67 all_other: all_other other
153                 *final_val = $1.val;           !!  68 |
154 }                                              !!  69 
155 ;                                              !!  70 other: ID
156                                                !!  71 {
157 if_expr: expr IF expr ELSE if_expr             !!  72         expr__add_id(ctx, $1);
158 {                                              !!  73 }
159         if (fpclassify($3.val) == FP_ZERO) {   !!  74 |
160                 /*                             !!  75 MIN | MAX | IF | ELSE | SMT_ON | NUMBER | '|' | '^' | '&' | '-' | '+' | '*' | '/' | '%' | '(' | ')' | ','
161                  * The IF expression evaluated !!  76 |
162                  * ELSE and discard everything !!  77 '<' | '>' | D_RATIO
163                  */                            !!  78 
164                 $$.val = $5.val;               !!  79 all_expr: if_expr                       { *final_val = $1; }
165                 $$.ids = $5.ids;               !!  80         ;
166                 ids__free($1.ids);             !!  81 
167                 ids__free($3.ids);             !!  82 if_expr:
168         } else if (!compute_ids || is_const($3 !!  83         expr IF expr ELSE expr { $$ = $3 ? $1 : $5; }
169                 /*                             !!  84         | expr
170                  * If ids aren't computed then !!  85         ;
171                  * ids are being computed and  !!  86 
172                  * constant, then also evaluat !!  87 expr:     NUMBER
173                  */                            !!  88         | ID                    {
174                 $$.val = $1.val;               !!  89                                         struct expr_id_data *data;
175                 $$.ids = $1.ids;               !!  90 
176                 ids__free($3.ids);             !!  91                                         if (expr__resolve_id(ctx, $1, &data)) {
177                 ids__free($5.ids);             !!  92                                                 free($1);
178         } else if ($1.val == $5.val) {         !!  93                                                 YYABORT;
179                 /*                             !!  94                                         }
180                  * LHS == RHS, so both are an  !!  95 
181                  * evaluate any events.        !!  96                                         $$ = expr_id_data__value(data);
182                  */                            !!  97                                         free($1);
183                 $$.val = $1.val;               !!  98                                 }
184                 $$.ids = NULL;                 !!  99         | expr '|' expr         { $$ = (long)$1 | (long)$3; }
185                 ids__free($1.ids);             !! 100         | expr '&' expr         { $$ = (long)$1 & (long)$3; }
186                 ids__free($3.ids);             !! 101         | expr '^' expr         { $$ = (long)$1 ^ (long)$3; }
187                 ids__free($5.ids);             !! 102         | expr '<' expr         { $$ = $1 < $3; }
188         } else {                               !! 103         | expr '>' expr         { $$ = $1 > $3; }
189                 /*                             !! 104         | expr '+' expr         { $$ = $1 + $3; }
190                  * Value is either the LHS or  !! 105         | expr '-' expr         { $$ = $1 - $3; }
191                  * to compute it.              !! 106         | expr '*' expr         { $$ = $1 * $3; }
192                  */                            !! 107         | expr '/' expr         { if ($3 == 0) {
193                 $$ = union_expr($1, union_expr !! 108                                         pr_debug("division by zero\n");
194         }                                      !! 109                                         YYABORT;
195 }                                              !! 110                                   }
196 | expr                                         !! 111                                   $$ = $1 / $3;
197 ;                                              !! 112                                 }
198                                                !! 113         | expr '%' expr         { if ((long)$3 == 0) {
199 expr: NUMBER                                   !! 114                                         pr_debug("division by zero\n");
200 {                                              !! 115                                         YYABORT;
201         $$.val = $1;                           !! 116                                   }
202         $$.ids = NULL;                         !! 117                                   $$ = (long)$1 % (long)$3;
203 }                                              !! 118                                 }
204 | ID                            { $$ = handle_ !! 119         | '-' expr %prec NEG    { $$ = -$2; }
205 | SOURCE_COUNT '(' ID ')'       { $$ = handle_ !! 120         | '(' if_expr ')'       { $$ = $2; }
206 | HAS_EVENT '(' ID ')'                         !! 121         | MIN '(' expr ',' expr ')' { $$ = $3 < $5 ? $3 : $5; }
207 {                                              !! 122         | MAX '(' expr ',' expr ')' { $$ = $3 > $5 ? $3 : $5; }
208         $$.val = expr__has_event(ctx, compute_ !! 123         | SMT_ON                 { $$ = smt_on() > 0; }
209         $$.ids = NULL;                         !! 124         | D_RATIO '(' expr ',' expr ')' { $$ = d_ratio($3,$5); }
210         free($3);                              !! 125         ;
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 {                                              << 
278         if (is_const($1.val) && is_const($3.va << 
279                 assert($1.ids == NULL);        << 
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;                       << 
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         }                                      << 
325 }                                              << 
326 | D_RATIO '(' expr ',' expr ')'                << 
327 {                                              << 
328         if (fpclassify($5.val) == FP_ZERO) {   << 
329                 /*                             << 
330                  * Division by constant zero a << 
331                  * are necessary.              << 
332                  */                            << 
333                 assert($5.ids == NULL);        << 
334                 $$.val = 0.0;                  << 
335                 $$.ids = NULL;                 << 
336                 ids__free($3.ids);             << 
337         } else if (!compute_ids || (is_const($ << 
338                 assert($3.ids == NULL);        << 
339                 assert($5.ids == NULL);        << 
340                 $$.val = $3.val / $5.val;      << 
341                 $$.ids = NULL;                 << 
342         } else {                               << 
343                 /* LHS and/or RHS need computi << 
344                 $$ = union_expr($3, $5);       << 
345         }                                      << 
346 }                                              << 
347 | '-' expr %prec NEG                           << 
348 {                                              << 
349         $$.val = -$2.val;                      << 
350         $$.ids = $2.ids;                       << 
351 }                                              << 
352 | '(' if_expr ')'                              << 
353 {                                              << 
354         $$ = $2;                               << 
355 }                                              << 
356 | MIN '(' expr ',' expr ')'                    << 
357 {                                              << 
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                                                   126 
381 %%                                                127 %%
                                                      

~ [ 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