* [PATCH] libtraceevent: Optimize print format parsing of constants
@ 2022-03-20 0:24 Steven Rostedt
0 siblings, 0 replies; only message in thread
From: Steven Rostedt @ 2022-03-20 0:24 UTC (permalink / raw)
To: Linux Trace Devel
From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
While debugging another issue, I found that there's no optimization of
operations in the print format for constants. That is, for example, the
sched_switch event has:
(REC->prev_state & ((((0x0000 | 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040) + 1) << 1) - 1))
Where it actually calculates the
(0x0000 | 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040) + 1) << 1) - 1)
at every event! instead of just testing against 255 (which it is
calculated to).
Add the calculation at the time the event print format is parsed.
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
src/event-parse.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 118 insertions(+)
diff --git a/src/event-parse.c b/src/event-parse.c
index 262bad26c976..bcca0af3148f 100644
--- a/src/event-parse.c
+++ b/src/event-parse.c
@@ -2144,6 +2144,120 @@ static int set_op_prio(struct tep_print_arg *arg)
return arg->op.prio;
}
+static int consolidate_op_arg(struct tep_print_arg *arg)
+{
+ unsigned long long val, left, right;
+ int ret = 0;
+
+ if (arg->type != TEP_PRINT_OP)
+ return 0;
+
+ if (arg->op.left)
+ ret = consolidate_op_arg(arg->op.left);
+ if (ret < 0)
+ return ret;
+
+ if (arg->op.right)
+ ret = consolidate_op_arg(arg->op.right);
+ if (ret < 0)
+ return ret;
+
+ if (!arg->op.left || !arg->op.right)
+ return 0;
+
+ if (arg->op.left->type != TEP_PRINT_ATOM ||
+ arg->op.right->type != TEP_PRINT_ATOM)
+ return 0;
+
+ /* Two atoms, we can do the operation now. */
+ left = strtoull(arg->op.left->atom.atom, NULL, 0);
+ right = strtoull(arg->op.right->atom.atom, NULL, 0);
+
+ switch (arg->op.op[0]) {
+ case '>':
+ switch (arg->op.op[1]) {
+ case '>':
+ val = left >> right;
+ break;
+ case '=':
+ val = left >= right;
+ break;
+ default:
+ val = left > right;
+ break;
+ }
+ break;
+ case '<':
+ switch (arg->op.op[1]) {
+ case '<':
+ val = left << right;
+ break;
+ case '=':
+ val = left <= right;
+ break;
+ default:
+ val = left < right;
+ break;
+ }
+ break;
+ case '&':
+ switch (arg->op.op[1]) {
+ case '&':
+ val = left && right;
+ break;
+ default:
+ val = left & right;
+ break;
+ }
+ break;
+ case '|':
+ switch (arg->op.op[1]) {
+ case '|':
+ val = left || right;
+ break;
+ default:
+ val = left | right;
+ break;
+ }
+ break;
+ case '-':
+ val = left - right;
+ break;
+ case '+':
+ val = left + right;
+ break;
+ case '*':
+ val = left * right;
+ break;
+ case '^':
+ val = left ^ right;
+ break;
+ case '/':
+ val = left / right;
+ break;
+ case '%':
+ val = left % right;
+ break;
+ case '=':
+ /* Only '==' is called here */
+ val = left == right;
+ break;
+ case '!':
+ /* Only '!=' is called here. */
+ val = left != right;
+ break;
+ default:
+ return 0;
+ }
+
+ free_arg(arg->op.left);
+ free_arg(arg->op.right);
+
+ arg->type = TEP_PRINT_ATOM;
+ free(arg->op.op);
+ return asprintf(&arg->atom.atom, "%lld", val) < 0 ? -1 : 0;
+}
+
/* Note, *tok does not get freed, but will most likely be saved */
static enum tep_event_type
process_op(struct tep_event *event, struct tep_print_arg *arg, char **tok)
@@ -3506,6 +3620,10 @@ static int event_read_print_args(struct tep_event *event, struct tep_print_arg *
if (type == TEP_EVENT_OP) {
type = process_op(event, arg, &token);
free_token(token);
+
+ if (consolidate_op_arg(arg) < 0)
+ type = TEP_EVENT_ERROR;
+
if (type == TEP_EVENT_ERROR) {
*list = NULL;
free_arg(arg);
--
2.35.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2022-03-20 0:24 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-20 0:24 [PATCH] libtraceevent: Optimize print format parsing of constants Steven Rostedt
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).