diff options
-rw-r--r-- | tools/perf/tests/expr.c | 11 | ||||
-rw-r--r-- | tools/perf/util/expr.y | 30 |
2 files changed, 34 insertions, 7 deletions
diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index 1c881bea7fca..287989321d2a 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "util/debug.h" #include "util/expr.h" +#include "util/smt.h" #include "tests.h" #include <stdlib.h> #include <string.h> @@ -132,6 +133,16 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "EVENT2,param=3/", (void **)&val_ptr)); + /* Only EVENT1 or EVENT2 need be measured depending on the value of smt_on. */ + expr__ctx_clear(ctx); + TEST_ASSERT_VAL("find ids", + expr__find_ids("EVENT1 if #smt_on else EVENT2", + NULL, ctx, 0) == 0); + TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 1); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, + smt_on() ? "EVENT1" : "EVENT2", + (void **)&val_ptr)); + expr__ctx_free(ctx); return 0; diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y index 5a295e385914..5b878f044f22 100644 --- a/tools/perf/util/expr.y +++ b/tools/perf/util/expr.y @@ -123,14 +123,30 @@ start: if_expr if_expr: expr IF expr ELSE expr { - if (!compute_ids) { - $$.ids = NULL; - if (fpclassify($3.val) == FP_ZERO) { - $$.val = $5.val; - } else { - $$.val = $1.val; - } + if (fpclassify($3.val) == FP_ZERO) { + /* + * The IF expression evaluated to 0 so treat as false, take the + * ELSE and discard everything else. + */ + $$.val = $5.val; + $$.ids = $5.ids; + ids__free($1.ids); + ids__free($3.ids); + } else if (!compute_ids || is_const($3.val)) { + /* + * If ids aren't computed then treat the expression as true. If + * ids are being computed and the IF expr is a non-zero + * constant, then also evaluate the true case. + */ + $$.val = $1.val; + $$.ids = $1.ids; + ids__free($3.ids); + ids__free($5.ids); } else { + /* + * Value is either the LHS or RHS and we need the IF expression + * to compute it. + */ $$ = union_expr($1, union_expr($3, $5)); } } |