2024-02-05 19:05:16

by Liang, Kan

[permalink] [raw]
Subject: [PATCH] perf script: Print source line for each jump in brstackinsn

From: Kan Liang <[email protected]>

With the srcline option, the perf script only prints a source line at
the beginning of a sample with call/ret from functions, but not for
each jump in brstackinsn. It's useful to print a source line for each
jump in brstackinsn when the end user analyze the full assembler
sequences of branch sequences for the sample.

The srccode option can also be used to locate the source code line.
However, it's printed almost for every line and makes the output less
readable.

$perf script -F +brstackinsn,+srcline --xed

Before the patch,

tchain_edit_deb 1463275 15228549.107820: 282495 instructions:u: 401133 f3+0xd (/home/kan/os.li>
tchain_edit.c:22
f3+40: tchain_edit.c:20
000000000040114e jle 0x401133 # PRED 6 cycles [6]
0000000000401133 movl -0x4(%rbp), %eax
0000000000401136 and $0x1, %eax
0000000000401139 test %eax, %eax
000000000040113b jz 0x401143
000000000040113d addl $0x1, -0x4(%rbp)
0000000000401141 jmp 0x401147 # PRED 3 cycles [9] 2.00 IPC
0000000000401147 cmpl $0x3e7, -0x4(%rbp)
000000000040114e jle 0x401133 # PRED 6 cycles [15] 0.33 IPC

After the patch,

tchain_edit_deb 1463275 15228549.107820: 282495 instructions:u: 401133 f3+0xd (/home/kan/os.li>
tchain_edit.c:22
f3+40: tchain_edit.c:20
000000000040114e jle 0x401133 srcline: tchain_edit.c:20 # PRED 6 cycles [6]
0000000000401133 movl -0x4(%rbp), %eax
0000000000401136 and $0x1, %eax
0000000000401139 test %eax, %eax
000000000040113b jz 0x401143
000000000040113d addl $0x1, -0x4(%rbp)
0000000000401141 jmp 0x401147 srcline: tchain_edit.c:23 # PRED 3 cycles [9] 2.00 IPC
0000000000401147 cmpl $0x3e7, -0x4(%rbp)
000000000040114e jle 0x401133 srcline: tchain_edit.c:20 # PRED 6 cycles [15] 0.33 IPC

Signed-off-by: Kan Liang <[email protected]>
---
tools/perf/builtin-script.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index b1f57401ff23..af63b7c37c8a 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1162,7 +1162,8 @@ static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr)
static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
struct perf_insn *x, u8 *inbuf, int len,
int insn, FILE *fp, int *total_cycles,
- struct perf_event_attr *attr)
+ struct perf_event_attr *attr,
+ struct thread *thread)
{
int ilen = 0;
int printed = fprintf(fp, "\t%016" PRIx64 "\t%-30s\t", ip,
@@ -1171,6 +1172,16 @@ static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
if (PRINT_FIELD(BRSTACKINSNLEN))
printed += fprintf(fp, "ilen: %d\t", ilen);

+ if (PRINT_FIELD(SRCLINE)) {
+ struct addr_location al;
+
+ addr_location__init(&al);
+ thread__find_map(thread, x->cpumode, ip, &al);
+ printed += map__fprintf_srcline(al.map, al.addr, " srcline: ", fp);
+ printed += fprintf(fp, "\t");
+ addr_location__exit(&al);
+ }
+
printed += fprintf(fp, "#%s%s%s%s",
en->flags.predicted ? " PRED" : "",
en->flags.mispred ? " MISPRED" : "",
@@ -1182,6 +1193,7 @@ static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
if (insn)
printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
}
+
return printed + fprintf(fp, "\n");
}

@@ -1260,7 +1272,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
x.cpumode, x.cpu, &lastsym, attr, fp);
printed += ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1],
&x, buffer, len, 0, fp, &total_cycles,
- attr);
+ attr, thread);
if (PRINT_FIELD(SRCCODE))
printed += print_srccode(thread, x.cpumode, entries[nr - 1].from);
}
@@ -1291,7 +1303,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
if (ip == end) {
printed += ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len - off, ++insn, fp,
- &total_cycles, attr);
+ &total_cycles, attr, thread);
if (PRINT_FIELD(SRCCODE))
printed += print_srccode(thread, x.cpumode, ip);
break;
--
2.35.1



2024-02-07 01:01:16

by Ian Rogers

[permalink] [raw]
Subject: Re: [PATCH] perf script: Print source line for each jump in brstackinsn

On Mon, Feb 5, 2024 at 6:58 AM <[email protected]> wrote:
>
> From: Kan Liang <[email protected]>
>
> With the srcline option, the perf script only prints a source line at
> the beginning of a sample with call/ret from functions, but not for
> each jump in brstackinsn. It's useful to print a source line for each
> jump in brstackinsn when the end user analyze the full assembler
> sequences of branch sequences for the sample.
>
> The srccode option can also be used to locate the source code line.
> However, it's printed almost for every line and makes the output less
> readable.
>
> $perf script -F +brstackinsn,+srcline --xed
>
> Before the patch,
>
> tchain_edit_deb 1463275 15228549.107820: 282495 instructions:u: 401133 f3+0xd (/home/kan/os.li>
> tchain_edit.c:22
> f3+40: tchain_edit.c:20
> 000000000040114e jle 0x401133 # PRED 6 cycles [6]
> 0000000000401133 movl -0x4(%rbp), %eax
> 0000000000401136 and $0x1, %eax
> 0000000000401139 test %eax, %eax
> 000000000040113b jz 0x401143
> 000000000040113d addl $0x1, -0x4(%rbp)
> 0000000000401141 jmp 0x401147 # PRED 3 cycles [9] 2.00 IPC
> 0000000000401147 cmpl $0x3e7, -0x4(%rbp)
> 000000000040114e jle 0x401133 # PRED 6 cycles [15] 0.33 IPC
>
> After the patch,
>
> tchain_edit_deb 1463275 15228549.107820: 282495 instructions:u: 401133 f3+0xd (/home/kan/os.li>
> tchain_edit.c:22
> f3+40: tchain_edit.c:20
> 000000000040114e jle 0x401133 srcline: tchain_edit.c:20 # PRED 6 cycles [6]
> 0000000000401133 movl -0x4(%rbp), %eax
> 0000000000401136 and $0x1, %eax
> 0000000000401139 test %eax, %eax
> 000000000040113b jz 0x401143
> 000000000040113d addl $0x1, -0x4(%rbp)
> 0000000000401141 jmp 0x401147 srcline: tchain_edit.c:23 # PRED 3 cycles [9] 2.00 IPC
> 0000000000401147 cmpl $0x3e7, -0x4(%rbp)
> 000000000040114e jle 0x401133 srcline: tchain_edit.c:20 # PRED 6 cycles [15] 0.33 IPC
>
> Signed-off-by: Kan Liang <[email protected]>

Reviewed-by: Ian Rogers <[email protected]>

Thanks,
Ian

> ---
> tools/perf/builtin-script.c | 18 +++++++++++++++---
> 1 file changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index b1f57401ff23..af63b7c37c8a 100644
> --- a/tools/perf/builtin-script.c
> +++ b/tools/perf/builtin-script.c
> @@ -1162,7 +1162,8 @@ static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr)
> static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
> struct perf_insn *x, u8 *inbuf, int len,
> int insn, FILE *fp, int *total_cycles,
> - struct perf_event_attr *attr)
> + struct perf_event_attr *attr,
> + struct thread *thread)
> {
> int ilen = 0;
> int printed = fprintf(fp, "\t%016" PRIx64 "\t%-30s\t", ip,
> @@ -1171,6 +1172,16 @@ static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
> if (PRINT_FIELD(BRSTACKINSNLEN))
> printed += fprintf(fp, "ilen: %d\t", ilen);
>
> + if (PRINT_FIELD(SRCLINE)) {
> + struct addr_location al;
> +
> + addr_location__init(&al);
> + thread__find_map(thread, x->cpumode, ip, &al);
> + printed += map__fprintf_srcline(al.map, al.addr, " srcline: ", fp);
> + printed += fprintf(fp, "\t");
> + addr_location__exit(&al);
> + }
> +
> printed += fprintf(fp, "#%s%s%s%s",
> en->flags.predicted ? " PRED" : "",
> en->flags.mispred ? " MISPRED" : "",
> @@ -1182,6 +1193,7 @@ static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
> if (insn)
> printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
> }
> +
> return printed + fprintf(fp, "\n");
> }
>
> @@ -1260,7 +1272,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
> x.cpumode, x.cpu, &lastsym, attr, fp);
> printed += ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1],
> &x, buffer, len, 0, fp, &total_cycles,
> - attr);
> + attr, thread);
> if (PRINT_FIELD(SRCCODE))
> printed += print_srccode(thread, x.cpumode, entries[nr - 1].from);
> }
> @@ -1291,7 +1303,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
> printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
> if (ip == end) {
> printed += ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len - off, ++insn, fp,
> - &total_cycles, attr);
> + &total_cycles, attr, thread);
> if (PRINT_FIELD(SRCCODE))
> printed += print_srccode(thread, x.cpumode, ip);
> break;
> --
> 2.35.1
>

2024-02-07 22:14:08

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH] perf script: Print source line for each jump in brstackinsn

On Mon, 5 Feb 2024 06:58:19 -0800, [email protected] wrote:
> From: Kan Liang <[email protected]>
>
> With the srcline option, the perf script only prints a source line at
> the beginning of a sample with call/ret from functions, but not for
> each jump in brstackinsn. It's useful to print a source line for each
> jump in brstackinsn when the end user analyze the full assembler
> sequences of branch sequences for the sample.
>
> [...]

Applied to perf-tools-next, thanks!

Best regards,
--
Namhyung Kim <[email protected]>