linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ian Rogers <irogers@google.com>
To: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Jiri Olsa <jolsa@redhat.com>, Namhyung Kim <namhyung@kernel.org>,
	linux-kernel@vger.kernel.org, Andi Kleen <ak@linux.intel.com>,
	Jin Yao <yao.jin@linux.intel.com>,
	John Garry <john.garry@huawei.com>, Paul Clarke <pc@us.ibm.com>,
	kajoljain <kjain@linux.ibm.com>,
	linux-perf-users@vger.kernel.org
Cc: Stephane Eranian <eranian@google.com>,
	Sandeep Dasgupta <sdasgup@google.com>,
	Ian Rogers <irogers@google.com>
Subject: [PATCH v9 11/13] perf expr: Propagate constants for binary operations
Date: Thu, 23 Sep 2021 00:46:14 -0700	[thread overview]
Message-ID: <20210923074616.674826-12-irogers@google.com> (raw)
In-Reply-To: <20210923074616.674826-1-irogers@google.com>

When we're computing ID values, if we have constant values then compute
the constant result. For example:
  1 + 2
Previously .val would be set to BOTTOM by union_expr, meaning that
all values are possible. With this change .val is set to 3.
Later changes will use the constant values to hopefully eliminate ID
values that don't need to be computed.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/util/expr.y | 63 ++++++++++++++++++++++++++++++------------
 1 file changed, 45 insertions(+), 18 deletions(-)

diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
index 6aeead54760a..5a295e385914 100644
--- a/tools/perf/util/expr.y
+++ b/tools/perf/util/expr.y
@@ -68,6 +68,12 @@ static void expr_error(double *final_val __maybe_unused,
  */
 #define BOTTOM NAN
 
+/* During computing ids, does val represent a constant (non-BOTTOM) value? */
+static bool is_const(double val)
+{
+	return isfinite(val);
+}
+
 static struct ids union_expr(struct ids ids1, struct ids ids2)
 {
 	struct ids result = {
@@ -77,8 +83,15 @@ static struct ids union_expr(struct ids ids1, struct ids ids2)
 	return result;
 }
 
+/*
+ * If we're not computing ids or $1 and $3 are constants, compute the new
+ * constant value using OP. Its invariant that there are no ids.  If computing
+ * ids for non-constants union the set of IDs that must be computed.
+ */
 #define BINARY_LONG_OP(RESULT, OP, LHS, RHS)				\
-	if (!compute_ids) {						\
+	if (!compute_ids || (is_const(LHS.val) && is_const(RHS.val))) { \
+		assert(LHS.ids == NULL);				\
+		assert(RHS.ids == NULL);				\
 		RESULT.val = (long)LHS.val OP (long)RHS.val;		\
 		RESULT.ids = NULL;					\
 	} else {							\
@@ -86,7 +99,9 @@ static struct ids union_expr(struct ids ids1, struct ids ids2)
 	}
 
 #define BINARY_OP(RESULT, OP, LHS, RHS)					\
-	if (!compute_ids) {						\
+	if (!compute_ids || (is_const(LHS.val) && is_const(RHS.val))) { \
+		assert(LHS.ids == NULL);				\
+		assert(RHS.ids == NULL);				\
 		RESULT.val = LHS.val OP RHS.val;			\
 		RESULT.ids = NULL;					\
 	} else {							\
@@ -163,40 +178,52 @@ expr: NUMBER
 | expr '*' expr { BINARY_OP($$, *, $1, $3); }
 | expr '/' expr
 {
-	if (!compute_ids) {
-		if (fpclassify($3.val) == FP_ZERO) {
-			pr_debug("division by zero\n");
-			YYABORT;
-		}
+	if (fpclassify($3.val) == FP_ZERO) {
+		pr_debug("division by zero\n");
+		YYABORT;
+	} else if (!compute_ids || (is_const($1.val) && is_const($3.val))) {
+		assert($1.ids == NULL);
+		assert($3.ids == NULL);
 		$$.val = $1.val / $3.val;
 		$$.ids = NULL;
 	} else {
+		/* LHS and/or RHS need computing from event IDs so union. */
 		$$ = union_expr($1, $3);
 	}
 }
 | expr '%' expr
 {
-	if (!compute_ids) {
-		if (fpclassify($3.val) == FP_ZERO) {
-			pr_debug("division by zero\n");
-			YYABORT;
-		}
+	if (fpclassify($3.val) == FP_ZERO) {
+		pr_debug("division by zero\n");
+		YYABORT;
+	} else if (!compute_ids || (is_const($1.val) && is_const($3.val))) {
+		assert($1.ids == NULL);
+		assert($3.ids == NULL);
 		$$.val = (long)$1.val % (long)$3.val;
 		$$.ids = NULL;
 	} else {
+		/* LHS and/or RHS need computing from event IDs so union. */
 		$$ = union_expr($1, $3);
 	}
 }
 | D_RATIO '(' expr ',' expr ')'
 {
-	if (!compute_ids) {
+	if (fpclassify($5.val) == FP_ZERO) {
+		/*
+		 * Division by constant zero always yields zero and no events
+		 * are necessary.
+		 */
+		assert($5.ids == NULL);
+		$$.val = 0.0;
+		$$.ids = NULL;
+		ids__free($3.ids);
+	} else if (!compute_ids || (is_const($3.val) && is_const($5.val))) {
+		assert($3.ids == NULL);
+		assert($5.ids == NULL);
+		$$.val = $3.val / $5.val;
 		$$.ids = NULL;
-		if (fpclassify($5.val) == FP_ZERO) {
-			$$.val = 0.0;
-		} else {
-			$$.val = $3.val / $5.val;
-		}
 	} else {
+		/* LHS and/or RHS need computing from event IDs so union. */
 		$$ = union_expr($3, $5);
 	}
 }
-- 
2.33.0.464.g1972c5931b-goog


  parent reply	other threads:[~2021-09-23  7:47 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-23  7:46 [PATCH v9 00/13] Don't compute events that won't be used in a metric Ian Rogers
2021-09-23  7:46 ` [PATCH v9 01/13] perf metric: Restructure struct expr_parse_ctx Ian Rogers
2021-09-23  7:46 ` [PATCH v9 02/13] perf metric: Use NAN for missing event IDs Ian Rogers
2021-09-23  7:46 ` [PATCH v9 03/13] perf expr: Remove unused headers and inline d_ratio Ian Rogers
2021-09-23  7:46 ` [PATCH v9 04/13] perf expr: Separate token declataion from type Ian Rogers
2021-09-23  7:46 ` [PATCH v9 05/13] perf expr: Use macros for operators Ian Rogers
2021-09-23  7:46 ` [PATCH v9 06/13] perf expr: Move actions to the left Ian Rogers
2021-09-23  7:46 ` [PATCH v9 07/13] perf metric: Rename expr__find_other Ian Rogers
2021-09-23  7:46 ` [PATCH v9 08/13] perf metric: Add utilities to work on ids map Ian Rogers
2021-09-23  7:46 ` [PATCH v9 09/13] perf metric: Allow metrics with no events Ian Rogers
2021-09-23  7:46 ` [PATCH v9 10/13] perf expr: Merge find_ids and regular parsing Ian Rogers
2021-09-28 20:56   ` Jiri Olsa
2021-09-28 21:20     ` Ian Rogers
2021-09-23  7:46 ` Ian Rogers [this message]
2021-09-23  7:46 ` [PATCH v9 12/13] perf metric: Don't compute unused events Ian Rogers
2021-09-23  7:46 ` [PATCH v9 13/13] perf metric: Avoid events for an 'if' constant result Ian Rogers
2021-09-29  5:35 ` [PATCH v9 00/13] Don't compute events that won't be used in a metric Jiri Olsa
2021-09-29 15:19 ` John Garry
2021-09-29 16:09   ` Ian Rogers
2021-09-29 16:51     ` Arnaldo Carvalho de Melo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210923074616.674826-12-irogers@google.com \
    --to=irogers@google.com \
    --cc=acme@kernel.org \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=eranian@google.com \
    --cc=john.garry@huawei.com \
    --cc=jolsa@redhat.com \
    --cc=kjain@linux.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=pc@us.ibm.com \
    --cc=peterz@infradead.org \
    --cc=sdasgup@google.com \
    --cc=yao.jin@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).