[PATCH v2 14/14] perf diff: Filter out streams by changed functions

Jin Yao
2020-03-13T07:12:31Z

Sometime some changes are not reflected in the source code,
e.g. changing the compiler option. So for this, we can't get
the changes by diffing the source code lines.

This patch introduces a new perf-diff option "--changed-func".
It passes the names of changed functions then perf-diff can
know what functions are changed.

For example,
perf diff --stream --changed-func main --changed-func rand

It passes the function list {"main", "rand"} to perf-diff.
Now perf-diff knows the functions "main" and "rand" in new perf
data file are changed.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
tools/perf/Documentation/perf-diff.txt | 5 +++++
tools/perf/builtin-diff.c | 30 ++++++++++++++++++++++++--
2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt
index 296fea98ac07..784598c12e26 100644
--- a/tools/perf/Documentation/perf-diff.txt
+++ b/tools/perf/Documentation/perf-diff.txt
@@ -196,6 +196,11 @@ OPTIONS
Source code directory corresponding to perf.data. Should be
used with --stream and --before.

+--changed-func=::
+ The given function is changed in new perf data file. This option
+ needs to be used with --stream option. Multiple functions can be given
+ by using this option more than once.
+
COMPARISON
----------
The comparison is governed by the baseline file. The baseline perf.data
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 98e9ab8c69ce..5e5f29105fe1 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -27,6 +27,7 @@
#include "util/block-info.h"
#include "util/srclist.h"
#include "util/callchain.h"
+#include "util/strlist.h"
#include <linux/err.h>
#include <linux/zalloc.h>
#include <subcmd/pager.h>
@@ -49,6 +50,7 @@ struct perf_diff {
bool src_cmp;
bool stream;
struct srclist *src_list;
+ struct strlist *func_list;
u64 total_cycles;
float min_percent;
};
@@ -1017,7 +1019,8 @@ static int process_base_stream(struct data__file *data_base,
if (!es_pair)
return -1;

- callchain_match_streams(es_base, es_pair, pdiff.src_list, NULL);
+ callchain_match_streams(es_base, es_pair, pdiff.src_list,
+ pdiff.func_list);
callchain_stream_report(es_base, es_pair);
}

@@ -1043,7 +1046,7 @@ static int process_base_stream(struct data__file *data_base,
block_hists_addr2line(&rep_pair->hist.block_hists, pair_dir);

block_info__match_report(rep_base, rep_pair,
- pdiff.src_list, NULL, NULL);
+ pdiff.src_list, pdiff.func_list, NULL);

fprintf(stdout, "%s", title);

@@ -1213,6 +1216,24 @@ static struct callchain_streams *create_evsel_streams(struct evlist *evlist,
return evsel_streams;
}

+static int parse_func(const struct option *opt __maybe_unused,
+ const char *str, int unset __maybe_unused)
+{
+ int ret;
+
+ if (!pdiff.func_list) {
+ pdiff.func_list = strlist__new(NULL, NULL);
+ if (!pdiff.func_list)
+ return -ENOMEM;
+ }
+
+ ret = strlist__add(pdiff.func_list, str);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int __cmd_diff(void)
{
struct data__file *d;
@@ -1312,6 +1333,9 @@ static int __cmd_diff(void)
if (pdiff.src_list)
srclist__delete(pdiff.src_list);

+ if (pdiff.func_list)
+ strlist__delete(pdiff.func_list);
+
return ret;
}

@@ -1390,6 +1414,8 @@ static const struct option options[] = {
OPT_CALLBACK(0, "percent-limit", &pdiff, "percent",
"Don't show entries under that percent",
parse_percent_limit),
+ OPT_CALLBACK(0, "changed-func", NULL, "func",
+ "Given function is changed", parse_func),
OPT_END()
};

--
2.17.1