aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2024-01-16 22:26:52 -0800
committerNamhyung Kim <namhyung@kernel.org>2024-01-22 12:08:20 -0800
commit7a54f1d83defa6dd6c25c0851191f6d3a0a42362 (patch)
tree9221c99c6e03dce2e77ef58d0c36e8ccffe79e28 /tools/perf
parentd3030191d3a6292408c5cf999ebcc1d10e00e9c2 (diff)
downloadlinux-7a54f1d83defa6dd6c25c0851191f6d3a0a42362.tar.gz
perf annotate-data: Add stack operation pseudo type
A typical function prologue and epilogue include multiple stack operations to save and restore the current value of registers. On x86, it looks like below: push r15 push r14 push r13 push r12 ... pop r12 pop r13 pop r14 pop r15 ret As these all touches the stack memory region, chances are high that they appear in a memory profile data. But these are not used for any real purpose yet so it'd return no types. One of my profile type shows that non neglible portion of data came from the stack operations. It also seems GCC generates more stack operations than clang. Annotate Instruction stats total 264, ok 169 (64.0%), bad 95 (36.0%) Name : Good Bad ----------------------------------------------------------- movq : 49 27 movl : 24 9 popq : 0 19 <-- here cmpl : 17 2 addq : 14 1 cmpq : 12 2 cmpxchgl : 3 7 Instead of dealing them as unknown, let's create a seperate pseudo type to represent those stack operations separately. Reviewed-by: Ian Rogers <irogers@google.com> Cc: Stephane Eranian <eranian@google.com> Cc: Masami Hiramatsu <mhiramat@kernel.org> Link: https://lore.kernel.org/r/20240117062657.985479-5-namhyung@kernel.org Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/annotate-data.h1
-rw-r--r--tools/perf/util/annotate.c26
2 files changed, 27 insertions, 0 deletions
diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h
index 65ddd839850f3..214c625e7bc96 100644
--- a/tools/perf/util/annotate-data.h
+++ b/tools/perf/util/annotate-data.h
@@ -70,6 +70,7 @@ struct annotated_data_type {
};
extern struct annotated_data_type unknown_type;
+extern struct annotated_data_type stackop_type;
/**
* struct annotated_data_stat - Debug statistics
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 3cdcdd449c865..655bd9443f5e9 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -107,6 +107,14 @@ static struct ins_ops ret_ops;
struct annotated_data_stat ann_data_stat;
LIST_HEAD(ann_insn_stat);
+/* Pseudo data types */
+struct annotated_data_type stackop_type = {
+ .self = {
+ .type_name = (char *)"(stack operation)",
+ .children = LIST_HEAD_INIT(stackop_type.self.children),
+ },
+};
+
static int arch__grow_instructions(struct arch *arch)
{
struct ins *new_instructions;
@@ -3724,6 +3732,18 @@ static struct annotated_item_stat *annotate_data_stat(struct list_head *head,
return istat;
}
+static bool is_stack_operation(struct arch *arch, struct disasm_line *dl)
+{
+ if (arch__is(arch, "x86")) {
+ if (!strncmp(dl->ins.name, "push", 4) ||
+ !strncmp(dl->ins.name, "pop", 3) ||
+ !strncmp(dl->ins.name, "ret", 3))
+ return true;
+ }
+
+ return false;
+}
+
/**
* hist_entry__get_data_type - find data type for given hist entry
* @he: hist entry
@@ -3789,6 +3809,12 @@ retry:
return NULL;
}
+ if (is_stack_operation(arch, dl)) {
+ istat->good++;
+ he->mem_type_off = 0;
+ return &stackop_type;
+ }
+
for_each_insn_op_loc(&loc, i, op_loc) {
if (!op_loc->mem_ref)
continue;